diff options
Diffstat (limited to 'contrib/libstdc++/include/ext')
301 files changed, 56896 insertions, 7760 deletions
diff --git a/contrib/libstdc++/include/ext/algorithm b/contrib/libstdc++/include/ext/algorithm index 07ac4cbe4d31..712a4edc7fdf 100644 --- a/contrib/libstdc++/include/ext/algorithm +++ b/contrib/libstdc++/include/ext/algorithm @@ -1,6 +1,6 @@ // Algorithm extensions -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2004, 2005 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -15,7 +15,7 @@ // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, // USA. // As a special exception, you may use this file as part of a free software @@ -55,8 +55,7 @@ /** @file ext/algorithm * This file is a GNU extension to the Standard C++ Library (possibly - * containing extensions from the HP/SGI STL subset). You should only - * include this header if you are using GCC 3 or later. + * containing extensions from the HP/SGI STL subset). */ #ifndef _EXT_ALGORITHM @@ -66,8 +65,8 @@ #include <algorithm> -namespace __gnu_cxx -{ +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + using std::ptrdiff_t; using std::min; using std::pair; @@ -84,11 +83,12 @@ namespace __gnu_cxx _OutputIterator __result, input_iterator_tag) { - for ( ; __count > 0; --__count) { - *__result = *__first; - ++__first; - ++__result; - } + for ( ; __count > 0; --__count) + { + *__result = *__first; + ++__first; + ++__result; + } return pair<_InputIterator, _OutputIterator>(__first, __result); } @@ -99,8 +99,9 @@ namespace __gnu_cxx random_access_iterator_tag) { _RAIterator __last = __first + __count; - return pair<_RAIterator, _OutputIterator>(__last, - std::copy(__first, __last, __result)); + return pair<_RAIterator, _OutputIterator>(__last, std::copy(__first, + __last, + __result)); } /** @@ -132,23 +133,24 @@ namespace __gnu_cxx template<typename _InputIterator1, typename _InputIterator2> int - __lexicographical_compare_3way(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2) + __lexicographical_compare_3way(_InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2) { - while (__first1 != __last1 && __first2 != __last2) { - if (*__first1 < *__first2) - return -1; - if (*__first2 < *__first1) - return 1; - ++__first1; - ++__first2; - } - if (__first2 == __last2) { + while (__first1 != __last1 && __first2 != __last2) + { + if (*__first1 < *__first2) + return -1; + if (*__first2 < *__first1) + return 1; + ++__first1; + ++__first2; + } + if (__first2 == __last2) return !(__first1 == __last1); - } - else { + else return -1; - } } inline int @@ -169,11 +171,10 @@ namespace __gnu_cxx 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, @@ -198,8 +199,10 @@ namespace __gnu_cxx */ template<typename _InputIterator1, typename _InputIterator2> int - lexicographical_compare_3way(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2) + lexicographical_compare_3way(_InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) @@ -211,12 +214,12 @@ namespace __gnu_cxx __glibcxx_requires_valid_range(__first1, __last1); __glibcxx_requires_valid_range(__first2, __last2); - return __lexicographical_compare_3way(__first1, __last1, __first2, __last2); + return __lexicographical_compare_3way(__first1, __last1, __first2, + __last2); } // count and count_if: this version, whose return type is void, was present // in the HP STL, and is retained as an extension for backward compatibility. - template<typename _InputIterator, typename _Tp, typename _Size> void count(_InputIterator __first, _InputIterator __last, @@ -259,7 +262,8 @@ namespace __gnu_cxx * @ingroup SGIextensions * @doctodo */ - template<typename _ForwardIterator, typename _OutputIterator, typename _Distance> + template<typename _ForwardIterator, typename _OutputIterator, + typename _Distance> _OutputIterator random_sample_n(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __out, const _Distance __n) @@ -273,16 +277,17 @@ namespace __gnu_cxx _Distance __remaining = std::distance(__first, __last); _Distance __m = min(__n, __remaining); - while (__m > 0) { - if ((std::rand() % __remaining) < __m) { + while (__m > 0) + { + if ((std::rand() % __remaining) < __m) + { *__out = *__first; ++__out; --__m; + } + --__remaining; + ++__first; } - - --__remaining; - ++__first; - } return __out; } @@ -291,8 +296,8 @@ namespace __gnu_cxx * @ingroup SGIextensions * @doctodo */ - template<typename _ForwardIterator, typename _OutputIterator, typename _Distance, - typename _RandomNumberGenerator> + template<typename _ForwardIterator, typename _OutputIterator, + typename _Distance, typename _RandomNumberGenerator> _OutputIterator random_sample_n(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __out, const _Distance __n, @@ -309,20 +314,22 @@ namespace __gnu_cxx _Distance __remaining = std::distance(__first, __last); _Distance __m = min(__n, __remaining); - while (__m > 0) { - if (__rand(__remaining) < __m) { + while (__m > 0) + { + if (__rand(__remaining) < __m) + { *__out = *__first; ++__out; --__m; + } + --__remaining; + ++__first; } - - --__remaining; - ++__first; - } return __out; } - template<typename _InputIterator, typename _RandomAccessIterator, typename _Distance> + template<typename _InputIterator, typename _RandomAccessIterator, + typename _Distance> _RandomAccessIterator __random_sample(_InputIterator __first, _InputIterator __last, _RandomAccessIterator __out, @@ -333,14 +340,14 @@ namespace __gnu_cxx for ( ; __first != __last && __m < __n; ++__m, ++__first) __out[__m] = *__first; - while (__first != __last) { - ++__t; - _Distance __M = std::rand() % (__t); - if (__M < __n) - __out[__M] = *__first; - ++__first; - } - + while (__first != __last) + { + ++__t; + _Distance __M = std::rand() % (__t); + if (__M < __n) + __out[__M] = *__first; + ++__first; + } return __out + __m; } @@ -361,14 +368,14 @@ namespace __gnu_cxx 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; } @@ -380,7 +387,8 @@ namespace __gnu_cxx template<typename _InputIterator, typename _RandomAccessIterator> inline _RandomAccessIterator random_sample(_InputIterator __first, _InputIterator __last, - _RandomAccessIterator __out_first, _RandomAccessIterator __out_last) + _RandomAccessIterator __out_first, + _RandomAccessIterator __out_last) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) @@ -402,7 +410,8 @@ namespace __gnu_cxx typename _RandomNumberGenerator> inline _RandomAccessIterator random_sample(_InputIterator __first, _InputIterator __last, - _RandomAccessIterator __out_first, _RandomAccessIterator __out_last, + _RandomAccessIterator __out_first, + _RandomAccessIterator __out_last, _RandomNumberGenerator& __rand) { // concept requirements @@ -427,7 +436,8 @@ namespace __gnu_cxx is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { // concept requirements - __glibcxx_function_requires(_RandomAccessIteratorConcept<_RandomAccessIterator>) + __glibcxx_function_requires(_RandomAccessIteratorConcept< + _RandomAccessIterator>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_RandomAccessIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); @@ -446,7 +456,8 @@ namespace __gnu_cxx _StrictWeakOrdering __comp) { // concept requirements - __glibcxx_function_requires(_RandomAccessIteratorConcept<_RandomAccessIterator>) + __glibcxx_function_requires(_RandomAccessIteratorConcept< + _RandomAccessIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_StrictWeakOrdering, typename iterator_traits<_RandomAccessIterator>::value_type, typename iterator_traits<_RandomAccessIterator>::value_type>) @@ -478,11 +489,9 @@ namespace __gnu_cxx return true; _ForwardIterator __next = __first; - for (++__next; __next != __last; __first = __next, ++__next) { + for (++__next; __next != __last; __first = __next, ++__next) if (*__next < *__first) return false; - } - return true; } @@ -493,7 +502,8 @@ namespace __gnu_cxx */ template<typename _ForwardIterator, typename _StrictWeakOrdering> bool - is_sorted(_ForwardIterator __first, _ForwardIterator __last, _StrictWeakOrdering __comp) + is_sorted(_ForwardIterator __first, _ForwardIterator __last, + _StrictWeakOrdering __comp) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) @@ -506,13 +516,12 @@ namespace __gnu_cxx return true; _ForwardIterator __next = __first; - for (++__next; __next != __last; __first = __next, ++__next) { + for (++__next; __next != __last; __first = __next, ++__next) if (__comp(*__next, *__first)) return false; - } - return true; } -} // namespace __gnu_cxx + +_GLIBCXX_END_NAMESPACE #endif /* _EXT_ALGORITHM */ diff --git a/contrib/libstdc++/include/ext/array_allocator.h b/contrib/libstdc++/include/ext/array_allocator.h new file mode 100644 index 000000000000..0bbd97a2d094 --- /dev/null +++ b/contrib/libstdc++/include/ext/array_allocator.h @@ -0,0 +1,149 @@ +// array allocator -*- C++ -*- + +// Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/** @file ext/array_allocator.h + * This file is a GNU extension to the Standard C++ Library. + */ + +#ifndef _ARRAY_ALLOCATOR_H +#define _ARRAY_ALLOCATOR_H 1 + +#include <cstddef> +#include <new> +#include <bits/functexcept.h> +#include <tr1/array> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + using std::size_t; + using std::ptrdiff_t; + + /// @brief Base class. + template<typename _Tp> + class array_allocator_base + { + 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; + + pointer + address(reference __x) const { return &__x; } + + const_pointer + address(const_reference __x) const { return &__x; } + + void + deallocate(pointer, size_type) + { + // Does nothing. + } + + size_type + max_size() const throw() + { return size_t(-1) / sizeof(_Tp); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 402. wrong new expression in [some_] allocator::construct + void + construct(pointer __p, const _Tp& __val) + { ::new(__p) value_type(__val); } + + void + destroy(pointer __p) { __p->~_Tp(); } + }; + + /** + * @brief An allocator that uses previously allocated memory. + * This memory can be externally, globally, or otherwise allocated. + */ + template<typename _Tp, typename _Array = std::tr1::array<_Tp, 1> > + class array_allocator : public array_allocator_base<_Tp> + { + 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; + typedef _Array array_type; + + private: + array_type* _M_array; + size_type _M_used; + + public: + template<typename _Tp1, typename _Array1 = _Array> + struct rebind + { typedef array_allocator<_Tp1, _Array1> other; }; + + array_allocator(array_type* __array = NULL) throw() + : _M_array(__array), _M_used(size_type()) { } + + array_allocator(const array_allocator& __o) throw() + : _M_array(__o._M_array), _M_used(__o._M_used) { } + + template<typename _Tp1, typename _Array1> + array_allocator(const array_allocator<_Tp1, _Array1>&) throw() + : _M_array(NULL), _M_used(size_type()) { } + + ~array_allocator() throw() { } + + pointer + allocate(size_type __n, const void* = 0) + { + if (_M_array == 0 || _M_used + __n > _M_array->size()) + std::__throw_bad_alloc(); + pointer __ret = _M_array->begin() + _M_used; + _M_used += __n; + return __ret; + } + }; + + template<typename _Tp, typename _Array> + inline bool + operator==(const array_allocator<_Tp, _Array>&, + const array_allocator<_Tp, _Array>&) + { return true; } + + template<typename _Tp, typename _Array> + inline bool + operator!=(const array_allocator<_Tp, _Array>&, + const array_allocator<_Tp, _Array>&) + { return false; } + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/contrib/libstdc++/include/ext/atomicity.h b/contrib/libstdc++/include/ext/atomicity.h new file mode 100644 index 000000000000..975121e876b3 --- /dev/null +++ b/contrib/libstdc++/include/ext/atomicity.h @@ -0,0 +1,118 @@ +// Support for atomic operations -*- C++ -*- + +// Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/** @file atomicity.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _GLIBCXX_ATOMICITY_H +#define _GLIBCXX_ATOMICITY_H 1 + +#include <bits/c++config.h> +#include <bits/gthr.h> +#include <bits/atomic_word.h> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + // Functions for portable atomic access. + // To abstract locking primatives across all thread policies, use: + // __exchange_and_add_dispatch + // __atomic_add_dispatch +#ifdef _GLIBCXX_ATOMIC_BUILTINS + static inline _Atomic_word + __exchange_and_add(volatile _Atomic_word* __mem, int __val) + { return __sync_fetch_and_add(__mem, __val); } + + static inline void + __atomic_add(volatile _Atomic_word* __mem, int __val) + { __sync_fetch_and_add(__mem, __val); } +#else + _Atomic_word + __attribute__ ((__unused__)) + __exchange_and_add(volatile _Atomic_word*, int); + + void + __attribute__ ((__unused__)) + __atomic_add(volatile _Atomic_word*, int); +#endif + + static inline _Atomic_word + __exchange_and_add_single(_Atomic_word* __mem, int __val) + { + _Atomic_word __result = *__mem; + *__mem += __val; + return __result; + } + + static inline void + __atomic_add_single(_Atomic_word* __mem, int __val) + { *__mem += __val; } + + static inline _Atomic_word + __attribute__ ((__unused__)) + __exchange_and_add_dispatch(_Atomic_word* __mem, int __val) + { +#ifdef __GTHREADS + if (__gthread_active_p()) + return __exchange_and_add(__mem, __val); + else + return __exchange_and_add_single(__mem, __val); +#else + return __exchange_and_add_single(__mem, __val); +#endif + } + + static inline void + __attribute__ ((__unused__)) + __atomic_add_dispatch(_Atomic_word* __mem, int __val) + { +#ifdef __GTHREADS + if (__gthread_active_p()) + __atomic_add(__mem, __val); + else + __atomic_add_single(__mem, __val); +#else + __atomic_add_single(__mem, __val); +#endif + } + +_GLIBCXX_END_NAMESPACE + +// Even if the CPU doesn't need a memory barrier, we need to ensure +// that the compiler doesn't reorder memory accesses across the +// barriers. +#ifndef _GLIBCXX_READ_MEM_BARRIER +#define _GLIBCXX_READ_MEM_BARRIER __asm __volatile ("":::"memory") +#endif +#ifndef _GLIBCXX_WRITE_MEM_BARRIER +#define _GLIBCXX_WRITE_MEM_BARRIER __asm __volatile ("":::"memory") +#endif + +#endif diff --git a/contrib/libstdc++/include/ext/bitmap_allocator.h b/contrib/libstdc++/include/ext/bitmap_allocator.h index 9a0d16209848..93fa8e63ad53 100644 --- a/contrib/libstdc++/include/ext/bitmap_allocator.h +++ b/contrib/libstdc++/include/ext/bitmap_allocator.h @@ -1,6 +1,6 @@ -// Bitmapped Allocator. -*- C++ -*- +// Bitmap Allocator. -*- C++ -*- -// Copyright (C) 2004 Free Software Foundation, Inc. +// Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -15,7 +15,7 @@ // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, // USA. // As a special exception, you may use this file as part of a free software @@ -27,833 +27,1112 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. +/** @file ext/bitmap_allocator.h + * This file is a GNU extension to the Standard C++ Library. + */ - -#if !defined _BITMAP_ALLOCATOR_H +#ifndef _BITMAP_ALLOCATOR_H #define _BITMAP_ALLOCATOR_H 1 -#include <cstddef> -//For std::size_t, and ptrdiff_t. -#include <utility> -//For std::pair. -#include <algorithm> -//std::find_if, and std::lower_bound. -#include <vector> -//For the free list of exponentially growing memory blocks. At max, -//size of the vector should be not more than the number of bits in an -//integer or an unsigned integer. -#include <functional> -//For greater_equal, and less_equal. -#include <new> -//For operator new. -#include <bits/gthr.h> -//For __gthread_mutex_t, __gthread_mutex_lock and __gthread_mutex_unlock. -#include <ext/new_allocator.h> -//For __gnu_cxx::new_allocator for std::vector. - -#include <cassert> -#define NDEBUG - -//#define CHECK_FOR_ERRORS -//#define __CPU_HAS_BACKWARD_BRANCH_PREDICTION - -namespace __gnu_cxx -{ - namespace { -#if defined __GTHREADS - bool const __threads_enabled = __gthread_active_p(); -#endif +#include <cstddef> // For std::size_t, and ptrdiff_t. +#include <bits/functexcept.h> // For __throw_bad_alloc(). +#include <utility> // For std::pair. +#include <functional> // For greater_equal, and less_equal. +#include <new> // For operator new. +#include <debug/debug.h> // _GLIBCXX_DEBUG_ASSERT +#include <ext/concurrence.h> - } -#if defined __GTHREADS - class _Mutex { - __gthread_mutex_t _M_mut; - //Prevent Copying and assignment. - _Mutex (_Mutex const&); - _Mutex& operator= (_Mutex const&); - public: - _Mutex () - { - if (__threads_enabled) - { -#if !defined __GTHREAD_MUTEX_INIT - __GTHREAD_MUTEX_INIT_FUNCTION(&_M_mut); -#else - __gthread_mutex_t __mtemp = __GTHREAD_MUTEX_INIT; - _M_mut = __mtemp; -#endif - } - } - ~_Mutex () - { - //Gthreads does not define a Mutex Destruction Function. - } - __gthread_mutex_t *_M_get() { return &_M_mut; } - }; +/** @brief The constant in the expression below is the alignment + * required in bytes. + */ +#define _BALLOC_ALIGN_BYTES 8 - class _Lock { - _Mutex* _M_pmt; - bool _M_locked; - //Prevent Copying and assignment. - _Lock (_Lock const&); - _Lock& operator= (_Lock const&); - public: - _Lock(_Mutex* __mptr) - : _M_pmt(__mptr), _M_locked(false) - { this->_M_lock(); } - void _M_lock() - { - if (__threads_enabled) - { - _M_locked = true; - __gthread_mutex_lock(_M_pmt->_M_get()); - } - } - void _M_unlock() - { - if (__threads_enabled) +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + using std::size_t; + using std::ptrdiff_t; + + namespace __detail + { + /** @class __mini_vector bitmap_allocator.h bitmap_allocator.h + * + * @brief __mini_vector<> is a stripped down version of the + * full-fledged std::vector<>. + * + * It is to be used only for built-in types or PODs. Notable + * differences are: + * + * @detail + * 1. Not all accessor functions are present. + * 2. Used ONLY for PODs. + * 3. No Allocator template argument. Uses ::operator new() to get + * memory, and ::operator delete() to free it. + * Caveat: The dtor does NOT free the memory allocated, so this a + * memory-leaking vector! + */ + template<typename _Tp> + class __mini_vector + { + __mini_vector(const __mini_vector&); + __mini_vector& operator=(const __mini_vector&); + + public: + typedef _Tp value_type; + typedef _Tp* pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef pointer iterator; + + private: + pointer _M_start; + pointer _M_finish; + pointer _M_end_of_storage; + + size_type + _M_space_left() const throw() + { return _M_end_of_storage - _M_finish; } + + pointer + allocate(size_type __n) + { return static_cast<pointer>(::operator new(__n * sizeof(_Tp))); } + + void + deallocate(pointer __p, size_type) + { ::operator delete(__p); } + + public: + // Members used: size(), push_back(), pop_back(), + // insert(iterator, const_reference), erase(iterator), + // begin(), end(), back(), operator[]. + + __mini_vector() : _M_start(0), _M_finish(0), + _M_end_of_storage(0) + { } + +#if 0 + ~__mini_vector() { - if (__builtin_expect(_M_locked, true)) + if (this->_M_start) { - __gthread_mutex_unlock(_M_pmt->_M_get()); - _M_locked = false; + this->deallocate(this->_M_start, this->_M_end_of_storage + - this->_M_start); } } - } - ~_Lock() { this->_M_unlock(); } - }; #endif + size_type + size() const throw() + { return _M_finish - _M_start; } + iterator + begin() const throw() + { return this->_M_start; } - namespace __aux_balloc { - static const unsigned int _Bits_Per_Byte = 8; - static const unsigned int _Bits_Per_Block = sizeof(unsigned int) * _Bits_Per_Byte; + iterator + end() const throw() + { return this->_M_finish; } - template <typename _Addr_Pair_t> - inline size_t __balloc_num_blocks (_Addr_Pair_t __ap) - { - return (__ap.second - __ap.first) + 1; - } + reference + back() const throw() + { return *(this->end() - 1); } - template <typename _Addr_Pair_t> - inline size_t __balloc_num_bit_maps (_Addr_Pair_t __ap) - { - return __balloc_num_blocks(__ap) / _Bits_Per_Block; - } + reference + operator[](const size_type __pos) const throw() + { return this->_M_start[__pos]; } - //T should be a pointer type. - template <typename _Tp> - class _Inclusive_between : public std::unary_function<typename std::pair<_Tp, _Tp>, bool> { - typedef _Tp pointer; - pointer _M_ptr_value; - typedef typename std::pair<_Tp, _Tp> _Block_pair; - - public: - _Inclusive_between (pointer __ptr) : _M_ptr_value(__ptr) { } - bool operator () (_Block_pair __bp) const throw () - { - if (std::less_equal<pointer> ()(_M_ptr_value, __bp.second) && - std::greater_equal<pointer> ()(_M_ptr_value, __bp.first)) - return true; - else - return false; - } - }; - - //Used to pass a Functor to functions by reference. - template <typename _Functor> - class _Functor_Ref : - public std::unary_function<typename _Functor::argument_type, typename _Functor::result_type> { - _Functor& _M_fref; - - public: - typedef typename _Functor::argument_type argument_type; - typedef typename _Functor::result_type result_type; - - _Functor_Ref (_Functor& __fref) : _M_fref(__fref) { } - result_type operator() (argument_type __arg) { return _M_fref (__arg); } - }; + void + insert(iterator __pos, const_reference __x); + void + push_back(const_reference __x) + { + if (this->_M_space_left()) + { + *this->end() = __x; + ++this->_M_finish; + } + else + this->insert(this->end(), __x); + } - //T should be a pointer type, and A is the Allocator for the vector. - template <typename _Tp, typename _Alloc> - class _Ffit_finder - : public std::unary_function<typename std::pair<_Tp, _Tp>, bool> { - typedef typename std::vector<std::pair<_Tp, _Tp>, _Alloc> _BPVector; - typedef typename _BPVector::difference_type _Counter_type; - typedef typename std::pair<_Tp, _Tp> _Block_pair; + void + pop_back() throw() + { --this->_M_finish; } - unsigned int *_M_pbitmap; - unsigned int _M_data_offset; + void + erase(iterator __pos) throw(); - public: - _Ffit_finder () - : _M_pbitmap (0), _M_data_offset (0) - { } + void + clear() throw() + { this->_M_finish = this->_M_start; } + }; - bool operator() (_Block_pair __bp) throw() + // Out of line function definitions. + template<typename _Tp> + void __mini_vector<_Tp>:: + insert(iterator __pos, const_reference __x) { - //Set the _rover to the last unsigned integer, which is the - //bitmap to the first free block. Thus, the bitmaps are in exact - //reverse order of the actual memory layout. So, we count down - //the bimaps, which is the same as moving up the memory. - - //If the used count stored at the start of the Bit Map headers - //is equal to the number of Objects that the current Block can - //store, then there is definitely no space for another single - //object, so just return false. - _Counter_type __diff = __gnu_cxx::__aux_balloc::__balloc_num_bit_maps (__bp); - - assert (*(reinterpret_cast<unsigned int*>(__bp.first) - (__diff + 1)) <= - __gnu_cxx::__aux_balloc::__balloc_num_blocks (__bp)); - - if (*(reinterpret_cast<unsigned int*>(__bp.first) - (__diff + 1)) == - __gnu_cxx::__aux_balloc::__balloc_num_blocks (__bp)) - return false; + if (this->_M_space_left()) + { + size_type __to_move = this->_M_finish - __pos; + iterator __dest = this->end(); + iterator __src = this->end() - 1; - unsigned int *__rover = reinterpret_cast<unsigned int*>(__bp.first) - 1; - for (_Counter_type __i = 0; __i < __diff; ++__i) + ++this->_M_finish; + while (__to_move) + { + *__dest = *__src; + --__dest; --__src; --__to_move; + } + *__pos = __x; + } + else { - _M_data_offset = __i; - if (*__rover) + size_type __new_size = this->size() ? this->size() * 2 : 1; + iterator __new_start = this->allocate(__new_size); + iterator __first = this->begin(); + iterator __start = __new_start; + while (__first != __pos) + { + *__start = *__first; + ++__start; ++__first; + } + *__start = __x; + ++__start; + while (__first != this->end()) { - _M_pbitmap = __rover; - return true; + *__start = *__first; + ++__start; ++__first; } - --__rover; + if (this->_M_start) + this->deallocate(this->_M_start, this->size()); + + this->_M_start = __new_start; + this->_M_finish = __start; + this->_M_end_of_storage = this->_M_start + __new_size; } - return false; - } - - unsigned int *_M_get () { return _M_pbitmap; } - unsigned int _M_offset () { return _M_data_offset * _Bits_Per_Block; } - }; - - //T should be a pointer type. - template <typename _Tp, typename _Alloc> - class _Bit_map_counter { - - typedef typename std::vector<std::pair<_Tp, _Tp>, _Alloc> _BPVector; - typedef typename _BPVector::size_type _Index_type; - typedef _Tp pointer; - - _BPVector& _M_vbp; - unsigned int *_M_curr_bmap; - unsigned int *_M_last_bmap_in_block; - _Index_type _M_curr_index; - - public: - //Use the 2nd parameter with care. Make sure that such an entry - //exists in the vector before passing that particular index to - //this ctor. - _Bit_map_counter (_BPVector& Rvbp, int __index = -1) - : _M_vbp(Rvbp) - { - this->_M_reset(__index); } - - void _M_reset (int __index = -1) throw() + + template<typename _Tp> + void __mini_vector<_Tp>:: + erase(iterator __pos) throw() { - if (__index == -1) + while (__pos + 1 != this->end()) { - _M_curr_bmap = 0; - _M_curr_index = (_Index_type)-1; - return; + *__pos = __pos[1]; + ++__pos; } + --this->_M_finish; + } - _M_curr_index = __index; - _M_curr_bmap = reinterpret_cast<unsigned int*>(_M_vbp[_M_curr_index].first) - 1; - assert (__index <= (int)_M_vbp.size() - 1); - - _M_last_bmap_in_block = _M_curr_bmap - - ((_M_vbp[_M_curr_index].second - _M_vbp[_M_curr_index].first + 1) / _Bits_Per_Block - 1); - } - - //Dangerous Function! Use with extreme care. Pass to this - //function ONLY those values that are known to be correct, - //otherwise this will mess up big time. - void _M_set_internal_bit_map (unsigned int *__new_internal_marker) throw() + template<typename _Tp> + struct __mv_iter_traits { - _M_curr_bmap = __new_internal_marker; - } - - bool _M_finished () const throw() + typedef typename _Tp::value_type value_type; + typedef typename _Tp::difference_type difference_type; + }; + + template<typename _Tp> + struct __mv_iter_traits<_Tp*> { - return (_M_curr_bmap == 0); - } - - _Bit_map_counter& operator++ () throw() + typedef _Tp value_type; + typedef ptrdiff_t difference_type; + }; + + enum + { + bits_per_byte = 8, + bits_per_block = sizeof(size_t) * size_t(bits_per_byte) + }; + + template<typename _ForwardIterator, typename _Tp, typename _Compare> + _ForwardIterator + __lower_bound(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val, _Compare __comp) { - if (_M_curr_bmap == _M_last_bmap_in_block) + typedef typename __mv_iter_traits<_ForwardIterator>::value_type + _ValueType; + typedef typename __mv_iter_traits<_ForwardIterator>::difference_type + _DistanceType; + + _DistanceType __len = __last - __first; + _DistanceType __half; + _ForwardIterator __middle; + + while (__len > 0) { - if (++_M_curr_index == _M_vbp.size()) + __half = __len >> 1; + __middle = __first; + __middle += __half; + if (__comp(*__middle, __val)) { - _M_curr_bmap = 0; + __first = __middle; + ++__first; + __len = __len - __half - 1; } else - { - this->_M_reset (_M_curr_index); - } + __len = __half; } - else - { - --_M_curr_bmap; - } - return *this; + return __first; } - - unsigned int *_M_get () + + template<typename _InputIterator, typename _Predicate> + inline _InputIterator + __find_if(_InputIterator __first, _InputIterator __last, _Predicate __p) { - return _M_curr_bmap; + while (__first != __last && !__p(*__first)) + ++__first; + return __first; } + + /** @brief The number of Blocks pointed to by the address pair + * passed to the function. + */ + template<typename _AddrPair> + inline size_t + __num_blocks(_AddrPair __ap) + { return (__ap.second - __ap.first) + 1; } + + /** @brief The number of Bit-maps pointed to by the address pair + * passed to the function. + */ + template<typename _AddrPair> + inline size_t + __num_bitmaps(_AddrPair __ap) + { return __num_blocks(__ap) / size_t(bits_per_block); } + + // _Tp should be a pointer type. + template<typename _Tp> + class _Inclusive_between + : public std::unary_function<typename std::pair<_Tp, _Tp>, bool> + { + typedef _Tp pointer; + pointer _M_ptr_value; + typedef typename std::pair<_Tp, _Tp> _Block_pair; + + public: + _Inclusive_between(pointer __ptr) : _M_ptr_value(__ptr) + { } + + bool + operator()(_Block_pair __bp) const throw() + { + if (std::less_equal<pointer>()(_M_ptr_value, __bp.second) + && std::greater_equal<pointer>()(_M_ptr_value, __bp.first)) + return true; + else + return false; + } + }; + + // Used to pass a Functor to functions by reference. + template<typename _Functor> + class _Functor_Ref + : public std::unary_function<typename _Functor::argument_type, + typename _Functor::result_type> + { + _Functor& _M_fref; + + public: + typedef typename _Functor::argument_type argument_type; + typedef typename _Functor::result_type result_type; + + _Functor_Ref(_Functor& __fref) : _M_fref(__fref) + { } + + result_type + operator()(argument_type __arg) + { return _M_fref(__arg); } + }; + + /** @class _Ffit_finder bitmap_allocator.h bitmap_allocator.h + * + * @brief The class which acts as a predicate for applying the + * first-fit memory allocation policy for the bitmap allocator. + */ + // _Tp should be a pointer type, and _Alloc is the Allocator for + // the vector. + template<typename _Tp> + class _Ffit_finder + : public std::unary_function<typename std::pair<_Tp, _Tp>, bool> + { + typedef typename std::pair<_Tp, _Tp> _Block_pair; + typedef typename __detail::__mini_vector<_Block_pair> _BPVector; + typedef typename _BPVector::difference_type _Counter_type; + + size_t* _M_pbitmap; + _Counter_type _M_data_offset; + + public: + _Ffit_finder() : _M_pbitmap(0), _M_data_offset(0) + { } + + bool + operator()(_Block_pair __bp) throw() + { + // Set the _rover to the last physical location bitmap, + // which is the bitmap which belongs to the first free + // block. Thus, the bitmaps are in exact reverse order of + // the actual memory layout. So, we count down the bimaps, + // which is the same as moving up the memory. + + // If the used count stored at the start of the Bit Map headers + // is equal to the number of Objects that the current Block can + // store, then there is definitely no space for another single + // object, so just return false. + _Counter_type __diff = + __gnu_cxx::__detail::__num_bitmaps(__bp); + + if (*(reinterpret_cast<size_t*> + (__bp.first) - (__diff + 1)) + == __gnu_cxx::__detail::__num_blocks(__bp)) + return false; + + size_t* __rover = reinterpret_cast<size_t*>(__bp.first) - 1; + + for (_Counter_type __i = 0; __i < __diff; ++__i) + { + _M_data_offset = __i; + if (*__rover) + { + _M_pbitmap = __rover; + return true; + } + --__rover; + } + return false; + } + - pointer _M_base () { return _M_vbp[_M_curr_index].first; } - unsigned int _M_offset () + size_t* + _M_get() const throw() + { return _M_pbitmap; } + + _Counter_type + _M_offset() const throw() + { return _M_data_offset * size_t(bits_per_block); } + }; + + + /** @class _Bitmap_counter bitmap_allocator.h bitmap_allocator.h + * + * @brief The bitmap counter which acts as the bitmap + * manipulator, and manages the bit-manipulation functions and + * the searching and identification functions on the bit-map. + */ + // _Tp should be a pointer type. + template<typename _Tp> + class _Bitmap_counter { - return _Bits_Per_Block * ((reinterpret_cast<unsigned int*>(this->_M_base()) - _M_curr_bmap) - 1); - } + typedef typename __detail::__mini_vector<typename std::pair<_Tp, _Tp> > + _BPVector; + typedef typename _BPVector::size_type _Index_type; + typedef _Tp pointer; - unsigned int _M_where () { return _M_curr_index; } - }; - } + _BPVector& _M_vbp; + size_t* _M_curr_bmap; + size_t* _M_last_bmap_in_block; + _Index_type _M_curr_index; + + public: + // Use the 2nd parameter with care. Make sure that such an + // entry exists in the vector before passing that particular + // index to this ctor. + _Bitmap_counter(_BPVector& Rvbp, long __index = -1) : _M_vbp(Rvbp) + { this->_M_reset(__index); } + + void + _M_reset(long __index = -1) throw() + { + if (__index == -1) + { + _M_curr_bmap = 0; + _M_curr_index = static_cast<_Index_type>(-1); + return; + } - //Generic Version of the bsf instruction. - typedef unsigned int _Bit_map_type; - static inline unsigned int _Bit_scan_forward (register _Bit_map_type __num) - { - return static_cast<unsigned int>(__builtin_ctz(__num)); - } - - struct _OOM_handler { - static std::new_handler _S_old_handler; - static bool _S_handled_oom; - typedef void (*_FL_clear_proc)(void); - static _FL_clear_proc _S_oom_fcp; + _M_curr_index = __index; + _M_curr_bmap = reinterpret_cast<size_t*> + (_M_vbp[_M_curr_index].first) - 1; + + _GLIBCXX_DEBUG_ASSERT(__index <= (long)_M_vbp.size() - 1); + + _M_last_bmap_in_block = _M_curr_bmap + - ((_M_vbp[_M_curr_index].second + - _M_vbp[_M_curr_index].first + 1) + / size_t(bits_per_block) - 1); + } - _OOM_handler (_FL_clear_proc __fcp) - { - _S_oom_fcp = __fcp; - _S_old_handler = std::set_new_handler (_S_handle_oom_proc); - _S_handled_oom = false; - } + // Dangerous Function! Use with extreme care. Pass to this + // function ONLY those values that are known to be correct, + // otherwise this will mess up big time. + void + _M_set_internal_bitmap(size_t* __new_internal_marker) throw() + { _M_curr_bmap = __new_internal_marker; } + + bool + _M_finished() const throw() + { return(_M_curr_bmap == 0); } + + _Bitmap_counter& + operator++() throw() + { + if (_M_curr_bmap == _M_last_bmap_in_block) + { + if (++_M_curr_index == _M_vbp.size()) + _M_curr_bmap = 0; + else + this->_M_reset(_M_curr_index); + } + else + --_M_curr_bmap; + return *this; + } + + size_t* + _M_get() const throw() + { return _M_curr_bmap; } + + pointer + _M_base() const throw() + { return _M_vbp[_M_curr_index].first; } - static void _S_handle_oom_proc() + _Index_type + _M_offset() const throw() + { + return size_t(bits_per_block) + * ((reinterpret_cast<size_t*>(this->_M_base()) + - _M_curr_bmap) - 1); + } + + _Index_type + _M_where() const throw() + { return _M_curr_index; } + }; + + /** @brief Mark a memory address as allocated by re-setting the + * corresponding bit in the bit-map. + */ + inline void + __bit_allocate(size_t* __pbmap, size_t __pos) throw() { - _S_oom_fcp(); - std::set_new_handler (_S_old_handler); - _S_handled_oom = true; + size_t __mask = 1 << __pos; + __mask = ~__mask; + *__pbmap &= __mask; } - - ~_OOM_handler () + + /** @brief Mark a memory address as free by setting the + * corresponding bit in the bit-map. + */ + inline void + __bit_free(size_t* __pbmap, size_t __pos) throw() { - if (!_S_handled_oom) - std::set_new_handler (_S_old_handler); + size_t __mask = 1 << __pos; + *__pbmap |= __mask; } - }; - - std::new_handler _OOM_handler::_S_old_handler; - bool _OOM_handler::_S_handled_oom = false; - _OOM_handler::_FL_clear_proc _OOM_handler::_S_oom_fcp = 0; - + } // namespace __detail + + /** @brief Generic Version of the bsf instruction. + */ + inline size_t + _Bit_scan_forward(size_t __num) + { return static_cast<size_t>(__builtin_ctzl(__num)); } + + /** @class free_list bitmap_allocator.h bitmap_allocator.h + * + * @brief The free list class for managing chunks of memory to be + * given to and returned by the bitmap_allocator. + */ + class free_list + { + typedef size_t* value_type; + typedef __detail::__mini_vector<value_type> vector_type; + typedef vector_type::iterator iterator; + typedef __mutex __mutex_type; - class _BA_free_list_store { - struct _LT_pointer_compare { - template <typename _Tp> - bool operator() (_Tp* __pt, _Tp const& __crt) const throw() - { - return *__pt < __crt; - } + struct _LT_pointer_compare + { + bool + operator()(const size_t* __pui, + const size_t __cui) const throw() + { return *__pui < __cui; } }; #if defined __GTHREADS - static _Mutex _S_bfl_mutex; + __mutex_type& + _M_get_mutex() + { + static __mutex_type _S_mutex; + return _S_mutex; + } #endif - static std::vector<unsigned int*> _S_free_list; - typedef std::vector<unsigned int*>::iterator _FLIter; - static void _S_validate_free_list(unsigned int *__addr) throw() + vector_type& + _M_get_free_list() + { + static vector_type _S_free_list; + return _S_free_list; + } + + /** @brief Performs validation of memory based on their size. + * + * @param __addr The pointer to the memory block to be + * validated. + * + * @detail Validates the memory block passed to this function and + * appropriately performs the action of managing the free list of + * blocks by adding this block to the free list or deleting this + * or larger blocks from the free list. + */ + void + _M_validate(size_t* __addr) throw() { - const unsigned int __max_size = 64; - if (_S_free_list.size() >= __max_size) + vector_type& __free_list = _M_get_free_list(); + const vector_type::size_type __max_size = 64; + if (__free_list.size() >= __max_size) { - //Ok, the threshold value has been reached. - //We determine which block to remove from the list of free - //blocks. - if (*__addr >= *_S_free_list.back()) + // Ok, the threshold value has been reached. We determine + // which block to remove from the list of free blocks. + if (*__addr >= *__free_list.back()) { - //Ok, the new block is greater than or equal to the last - //block in the list of free blocks. We just free the new - //block. - operator delete((void*)__addr); + // Ok, the new block is greater than or equal to the + // last block in the list of free blocks. We just free + // the new block. + ::operator delete(static_cast<void*>(__addr)); return; } else { - //Deallocate the last block in the list of free lists, and - //insert the new one in it's correct position. - operator delete((void*)_S_free_list.back()); - _S_free_list.pop_back(); + // Deallocate the last block in the list of free lists, + // and insert the new one in it's correct position. + ::operator delete(static_cast<void*>(__free_list.back())); + __free_list.pop_back(); } } - //Just add the block to the list of free lists - //unconditionally. - _FLIter __temp = std::lower_bound(_S_free_list.begin(), _S_free_list.end(), - *__addr, _LT_pointer_compare ()); - //We may insert the new free list before _temp; - _S_free_list.insert(__temp, __addr); + // Just add the block to the list of free lists unconditionally. + iterator __temp = __gnu_cxx::__detail::__lower_bound + (__free_list.begin(), __free_list.end(), + *__addr, _LT_pointer_compare()); + + // We may insert the new free list before _temp; + __free_list.insert(__temp, __addr); } - static bool _S_should_i_give(unsigned int __block_size, unsigned int __required_size) throw() + /** @brief Decides whether the wastage of memory is acceptable for + * the current memory request and returns accordingly. + * + * @param __block_size The size of the block available in the free + * list. + * + * @param __required_size The required size of the memory block. + * + * @return true if the wastage incurred is acceptable, else returns + * false. + */ + bool + _M_should_i_give(size_t __block_size, + size_t __required_size) throw() { - const unsigned int __max_wastage_percentage = 36; + const size_t __max_wastage_percentage = 36; if (__block_size >= __required_size && - (((__block_size - __required_size) * 100 / __block_size) < __max_wastage_percentage)) + (((__block_size - __required_size) * 100 / __block_size) + < __max_wastage_percentage)) return true; else return false; } public: - typedef _BA_free_list_store _BFL_type; - - static inline void _S_insert_free_list(unsigned int *__addr) throw() + /** @brief This function returns the block of memory to the + * internal free list. + * + * @param __addr The pointer to the memory block that was given + * by a call to the _M_get function. + */ + inline void + _M_insert(size_t* __addr) throw() { #if defined __GTHREADS - _Lock __bfl_lock(&_S_bfl_mutex); + __gnu_cxx::__scoped_lock __bfl_lock(_M_get_mutex()); #endif - //Call _S_validate_free_list to decide what should be done with this - //particular free list. - _S_validate_free_list(--__addr); + // Call _M_validate to decide what should be done with + // this particular free list. + this->_M_validate(reinterpret_cast<size_t*>(__addr) - 1); + // See discussion as to why this is 1! } - static unsigned int *_S_get_free_list(unsigned int __sz) throw (std::bad_alloc) - { -#if defined __GTHREADS - _Lock __bfl_lock(&_S_bfl_mutex); -#endif - _FLIter __temp = std::lower_bound(_S_free_list.begin(), _S_free_list.end(), - __sz, _LT_pointer_compare()); - if (__temp == _S_free_list.end() || !_S_should_i_give (**__temp, __sz)) - { - //We hold the lock because the OOM_Handler is a stateless - //entity. - _OOM_handler __set_handler(_BFL_type::_S_clear); - unsigned int *__ret_val = reinterpret_cast<unsigned int*> - (operator new (__sz + sizeof(unsigned int))); - *__ret_val = __sz; - return ++__ret_val; - } - else - { - unsigned int* __ret_val = *__temp; - _S_free_list.erase (__temp); - return ++__ret_val; - } - } - - //This function just clears the internal Free List, and gives back - //all the memory to the OS. - static void _S_clear() - { -#if defined __GTHREADS - _Lock __bfl_lock(&_S_bfl_mutex); -#endif - _FLIter __iter = _S_free_list.begin(); - while (__iter != _S_free_list.end()) - { - operator delete((void*)*__iter); - ++__iter; - } - _S_free_list.clear(); - } - + /** @brief This function gets a block of memory of the specified + * size from the free list. + * + * @param __sz The size in bytes of the memory required. + * + * @return A pointer to the new memory block of size at least + * equal to that requested. + */ + size_t* + _M_get(size_t __sz) throw(std::bad_alloc); + + /** @brief This function just clears the internal Free List, and + * gives back all the memory to the OS. + */ + void + _M_clear(); }; -#if defined __GTHREADS - _Mutex _BA_free_list_store::_S_bfl_mutex; -#endif - std::vector<unsigned int*> _BA_free_list_store::_S_free_list; - template <typename _Tp> class bitmap_allocator; - // specialize for void: - template <> class bitmap_allocator<void> { - public: - typedef void* pointer; - typedef const void* const_pointer; - // reference-to-void members are impossible. - typedef void value_type; - template <typename _Tp1> struct rebind { typedef bitmap_allocator<_Tp1> other; }; - }; + // Forward declare the class. + template<typename _Tp> + class bitmap_allocator; - template <typename _Tp> class bitmap_allocator : private _BA_free_list_store { - 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 <typename _Tp1> struct rebind { typedef bitmap_allocator<_Tp1> other; }; - - private: - static const unsigned int _Bits_Per_Byte = 8; - static const unsigned int _Bits_Per_Block = sizeof(unsigned int) * _Bits_Per_Byte; - - static inline void _S_bit_allocate(unsigned int *__pbmap, unsigned int __pos) throw() + // Specialize for void: + template<> + class bitmap_allocator<void> { - unsigned int __mask = 1 << __pos; - __mask = ~__mask; - *__pbmap &= __mask; - } - - static inline void _S_bit_free(unsigned int *__pbmap, unsigned int __pos) throw() - { - unsigned int __mask = 1 << __pos; - *__pbmap |= __mask; - } + public: + typedef void* pointer; + typedef const void* const_pointer; - static inline void *_S_memory_get(size_t __sz) throw (std::bad_alloc) - { - return operator new(__sz); - } + // Reference-to-void members are impossible. + typedef void value_type; + template<typename _Tp1> + struct rebind + { + typedef bitmap_allocator<_Tp1> other; + }; + }; - static inline void _S_memory_put(void *__vptr) throw () + template<typename _Tp> + class bitmap_allocator : private free_list { - operator delete(__vptr); - } + 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; + typedef free_list::__mutex_type __mutex_type; + + template<typename _Tp1> + struct rebind + { + typedef bitmap_allocator<_Tp1> other; + }; - typedef typename std::pair<pointer, pointer> _Block_pair; - typedef typename __gnu_cxx::new_allocator<_Block_pair> _BPVec_allocator_type; - typedef typename std::vector<_Block_pair, _BPVec_allocator_type> _BPVector; + private: + template<size_t _BSize, size_t _AlignSize> + struct aligned_size + { + enum + { + modulus = _BSize % _AlignSize, + value = _BSize + (modulus ? _AlignSize - (modulus) : 0) + }; + }; + + struct _Alloc_block + { + char __M_unused[aligned_size<sizeof(value_type), + _BALLOC_ALIGN_BYTES>::value]; + }; -#if defined CHECK_FOR_ERRORS - //Complexity: O(lg(N)). Where, N is the number of block of size - //sizeof(value_type). - static void _S_check_for_free_blocks() throw() - { - typedef typename __gnu_cxx::__aux_balloc::_Ffit_finder<pointer, _BPVec_allocator_type> _FFF; - _FFF __fff; - typedef typename _BPVector::iterator _BPiter; - _BPiter __bpi = std::find_if(_S_mem_blocks.begin(), _S_mem_blocks.end(), - __gnu_cxx::__aux_balloc::_Functor_Ref<_FFF>(__fff)); - assert(__bpi == _S_mem_blocks.end()); - } -#endif + typedef typename std::pair<_Alloc_block*, _Alloc_block*> _Block_pair; + typedef typename + __detail::__mini_vector<_Block_pair> _BPVector; - //Complexity: O(1), but internally depends upon the complexity of - //the function _BA_free_list_store::_S_get_free_list. The part - //where the bitmap headers are written is of worst case complexity: - //O(X),where X is the number of blocks of size sizeof(value_type) - //within the newly acquired block. Having a tight bound. - static void _S_refill_pool() throw (std::bad_alloc) - { -#if defined CHECK_FOR_ERRORS - _S_check_for_free_blocks(); +#if defined _GLIBCXX_DEBUG + // Complexity: O(lg(N)). Where, N is the number of block of size + // sizeof(value_type). + void + _S_check_for_free_blocks() throw() + { + typedef typename + __gnu_cxx::__detail::_Ffit_finder<_Alloc_block*> _FFF; + _FFF __fff; + typedef typename _BPVector::iterator _BPiter; + _BPiter __bpi = + __gnu_cxx::__detail::__find_if + (_S_mem_blocks.begin(), _S_mem_blocks.end(), + __gnu_cxx::__detail::_Functor_Ref<_FFF>(__fff)); + + _GLIBCXX_DEBUG_ASSERT(__bpi == _S_mem_blocks.end()); + } #endif - const unsigned int __num_bit_maps = _S_block_size / _Bits_Per_Block; - const unsigned int __size_to_allocate = sizeof(unsigned int) + - _S_block_size * sizeof(value_type) + __num_bit_maps*sizeof(unsigned int); + /** @brief Responsible for exponentially growing the internal + * memory pool. + * + * @throw std::bad_alloc. If memory can not be allocated. + * + * @detail Complexity: O(1), but internally depends upon the + * complexity of the function free_list::_M_get. The part where + * the bitmap headers are written has complexity: O(X),where X + * is the number of blocks of size sizeof(value_type) within + * the newly acquired block. Having a tight bound. + */ + void + _S_refill_pool() throw(std::bad_alloc) + { +#if defined _GLIBCXX_DEBUG + _S_check_for_free_blocks(); +#endif - unsigned int *__temp = - reinterpret_cast<unsigned int*>(_BA_free_list_store::_S_get_free_list(__size_to_allocate)); - *__temp = 0; - ++__temp; + const size_t __num_bitmaps = (_S_block_size + / size_t(__detail::bits_per_block)); + const size_t __size_to_allocate = sizeof(size_t) + + _S_block_size * sizeof(_Alloc_block) + + __num_bitmaps * sizeof(size_t); + + size_t* __temp = + reinterpret_cast<size_t*> + (this->_M_get(__size_to_allocate)); + *__temp = 0; + ++__temp; + + // The Header information goes at the Beginning of the Block. + _Block_pair __bp = + std::make_pair(reinterpret_cast<_Alloc_block*> + (__temp + __num_bitmaps), + reinterpret_cast<_Alloc_block*> + (__temp + __num_bitmaps) + + _S_block_size - 1); + + // Fill the Vector with this information. + _S_mem_blocks.push_back(__bp); - //The Header information goes at the Beginning of the Block. - _Block_pair __bp = std::make_pair(reinterpret_cast<pointer>(__temp + __num_bit_maps), - reinterpret_cast<pointer>(__temp + __num_bit_maps) - + _S_block_size - 1); + size_t __bit_mask = 0; // 0 Indicates all Allocated. + __bit_mask = ~__bit_mask; // 1 Indicates all Free. - //Fill the Vector with this information. - _S_mem_blocks.push_back(__bp); + for (size_t __i = 0; __i < __num_bitmaps; ++__i) + __temp[__i] = __bit_mask; - unsigned int __bit_mask = 0; //0 Indicates all Allocated. - __bit_mask = ~__bit_mask; //1 Indicates all Free. + _S_block_size *= 2; + } - for (unsigned int __i = 0; __i < __num_bit_maps; ++__i) - __temp[__i] = __bit_mask; - //On some implementations, operator new might throw bad_alloc, or - //malloc might fail if the size passed is too large, therefore, we - //limit the size passed to malloc or operator new. - _S_block_size *= 2; - } - - static _BPVector _S_mem_blocks; - static unsigned int _S_block_size; - static __gnu_cxx::__aux_balloc::_Bit_map_counter<pointer, _BPVec_allocator_type> _S_last_request; - static typename _BPVector::size_type _S_last_dealloc_index; + static _BPVector _S_mem_blocks; + static size_t _S_block_size; + static __gnu_cxx::__detail:: + _Bitmap_counter<_Alloc_block*> _S_last_request; + static typename _BPVector::size_type _S_last_dealloc_index; #if defined __GTHREADS - static _Mutex _S_mut; + static __mutex_type _S_mut; #endif - //Complexity: Worst case complexity is O(N), but that is hardly ever - //hit. if and when this particular case is encountered, the next few - //cases are guaranteed to have a worst case complexity of O(1)! - //That's why this function performs very well on the average. you - //can consider this function to be having a complexity refrred to - //commonly as: Amortized Constant time. - static pointer _S_allocate_single_object() - { + public: + + /** @brief Allocates memory for a single object of size + * sizeof(_Tp). + * + * @throw std::bad_alloc. If memory can not be allocated. + * + * @detail Complexity: Worst case complexity is O(N), but that + * is hardly ever hit. If and when this particular case is + * encountered, the next few cases are guaranteed to have a + * worst case complexity of O(1)! That's why this function + * performs very well on average. You can consider this + * function to have a complexity referred to commonly as: + * Amortized Constant time. + */ + pointer + _M_allocate_single_object() throw(std::bad_alloc) + { #if defined __GTHREADS - _Lock __bit_lock(&_S_mut); + __gnu_cxx::__scoped_lock __bit_lock(_S_mut); #endif - //The algorithm is something like this: The last_requst variable - //points to the last accessed Bit Map. When such a condition - //occurs, we try to find a free block in the current bitmap, or - //succeeding bitmaps until the last bitmap is reached. If no free - //block turns up, we resort to First Fit method. - - //WARNING: Do not re-order the condition in the while statement - //below, because it relies on C++'s short-circuit - //evaluation. The return from _S_last_request->_M_get() will NOT - //be dereferenceable if _S_last_request->_M_finished() returns - //true. This would inevitibly lead to a NULL pointer dereference - //if tinkered with. - while (_S_last_request._M_finished() == false && (*(_S_last_request._M_get()) == 0)) - { - _S_last_request.operator++(); - } + // The algorithm is something like this: The last_request + // variable points to the last accessed Bit Map. When such a + // condition occurs, we try to find a free block in the + // current bitmap, or succeeding bitmaps until the last bitmap + // is reached. If no free block turns up, we resort to First + // Fit method. + + // WARNING: Do not re-order the condition in the while + // statement below, because it relies on C++'s short-circuit + // evaluation. The return from _S_last_request->_M_get() will + // NOT be dereference able if _S_last_request->_M_finished() + // returns true. This would inevitably lead to a NULL pointer + // dereference if tinkered with. + while (_S_last_request._M_finished() == false + && (*(_S_last_request._M_get()) == 0)) + { + _S_last_request.operator++(); + } - if (__builtin_expect(_S_last_request._M_finished() == true, false)) - { - //Fall Back to First Fit algorithm. - typedef typename __gnu_cxx::__aux_balloc::_Ffit_finder<pointer, _BPVec_allocator_type> _FFF; - _FFF __fff; - typedef typename _BPVector::iterator _BPiter; - _BPiter __bpi = std::find_if(_S_mem_blocks.begin(), _S_mem_blocks.end(), - __gnu_cxx::__aux_balloc::_Functor_Ref<_FFF>(__fff)); - - if (__bpi != _S_mem_blocks.end()) - { - //Search was successful. Ok, now mark the first bit from - //the right as 0, meaning Allocated. This bit is obtained - //by calling _M_get() on __fff. - unsigned int __nz_bit = _Bit_scan_forward(*__fff._M_get()); - _S_bit_allocate(__fff._M_get(), __nz_bit); - - _S_last_request._M_reset(__bpi - _S_mem_blocks.begin()); - - //Now, get the address of the bit we marked as allocated. - pointer __ret_val = __bpi->first + __fff._M_offset() + __nz_bit; - unsigned int *__puse_count = reinterpret_cast<unsigned int*>(__bpi->first) - - (__gnu_cxx::__aux_balloc::__balloc_num_bit_maps(*__bpi) + 1); - ++(*__puse_count); - return __ret_val; - } - else - { - //Search was unsuccessful. We Add more memory to the pool - //by calling _S_refill_pool(). - _S_refill_pool(); + if (__builtin_expect(_S_last_request._M_finished() == true, false)) + { + // Fall Back to First Fit algorithm. + typedef typename + __gnu_cxx::__detail::_Ffit_finder<_Alloc_block*> _FFF; + _FFF __fff; + typedef typename _BPVector::iterator _BPiter; + _BPiter __bpi = + __gnu_cxx::__detail::__find_if + (_S_mem_blocks.begin(), _S_mem_blocks.end(), + __gnu_cxx::__detail::_Functor_Ref<_FFF>(__fff)); + + if (__bpi != _S_mem_blocks.end()) + { + // Search was successful. Ok, now mark the first bit from + // the right as 0, meaning Allocated. This bit is obtained + // by calling _M_get() on __fff. + size_t __nz_bit = _Bit_scan_forward(*__fff._M_get()); + __detail::__bit_allocate(__fff._M_get(), __nz_bit); + + _S_last_request._M_reset(__bpi - _S_mem_blocks.begin()); + + // Now, get the address of the bit we marked as allocated. + pointer __ret = reinterpret_cast<pointer> + (__bpi->first + __fff._M_offset() + __nz_bit); + size_t* __puse_count = + reinterpret_cast<size_t*> + (__bpi->first) + - (__gnu_cxx::__detail::__num_bitmaps(*__bpi) + 1); + + ++(*__puse_count); + return __ret; + } + else + { + // Search was unsuccessful. We Add more memory to the + // pool by calling _S_refill_pool(). + _S_refill_pool(); - //_M_Reset the _S_last_request structure to the first free - //block's bit map. - _S_last_request._M_reset(_S_mem_blocks.size() - 1); + // _M_Reset the _S_last_request structure to the first + // free block's bit map. + _S_last_request._M_reset(_S_mem_blocks.size() - 1); - //Now, mark that bit as allocated. - } - } - //_S_last_request holds a pointer to a valid bit map, that points - //to a free block in memory. - unsigned int __nz_bit = _Bit_scan_forward(*_S_last_request._M_get()); - _S_bit_allocate(_S_last_request._M_get(), __nz_bit); - - pointer __ret_val = _S_last_request._M_base() + _S_last_request._M_offset() + __nz_bit; - - unsigned int *__puse_count = reinterpret_cast<unsigned int*> - (_S_mem_blocks[_S_last_request._M_where()].first) - - (__gnu_cxx::__aux_balloc::__balloc_num_bit_maps(_S_mem_blocks[_S_last_request._M_where()]) + 1); - ++(*__puse_count); - return __ret_val; - } + // Now, mark that bit as allocated. + } + } - //Complexity: O(lg(N)), but the worst case is hit quite often! I - //need to do something about this. I'll be able to work on it, only - //when I have some solid figures from a few real apps. - static void _S_deallocate_single_object(pointer __p) throw() - { -#if defined __GTHREADS - _Lock __bit_lock(&_S_mut); -#endif + // _S_last_request holds a pointer to a valid bit map, that + // points to a free block in memory. + size_t __nz_bit = _Bit_scan_forward(*_S_last_request._M_get()); + __detail::__bit_allocate(_S_last_request._M_get(), __nz_bit); - typedef typename _BPVector::iterator _Iterator; - typedef typename _BPVector::difference_type _Difference_type; + pointer __ret = reinterpret_cast<pointer> + (_S_last_request._M_base() + _S_last_request._M_offset() + __nz_bit); - _Difference_type __diff; - int __displacement; + size_t* __puse_count = reinterpret_cast<size_t*> + (_S_mem_blocks[_S_last_request._M_where()].first) + - (__gnu_cxx::__detail:: + __num_bitmaps(_S_mem_blocks[_S_last_request._M_where()]) + 1); - assert(_S_last_dealloc_index >= 0); + ++(*__puse_count); + return __ret; + } - if (__gnu_cxx::__aux_balloc::_Inclusive_between<pointer>(__p)(_S_mem_blocks[_S_last_dealloc_index])) - { - assert(_S_last_dealloc_index <= _S_mem_blocks.size() - 1); + /** @brief Deallocates memory that belongs to a single object of + * size sizeof(_Tp). + * + * @detail Complexity: O(lg(N)), but the worst case is not hit + * often! This is because containers usually deallocate memory + * close to each other and this case is handled in O(1) time by + * the deallocate function. + */ + void + _M_deallocate_single_object(pointer __p) throw() + { +#if defined __GTHREADS + __gnu_cxx::__scoped_lock __bit_lock(_S_mut); +#endif + _Alloc_block* __real_p = reinterpret_cast<_Alloc_block*>(__p); - //Initial Assumption was correct! - __diff = _S_last_dealloc_index; - __displacement = __p - _S_mem_blocks[__diff].first; - } - else - { - _Iterator _iter = (std::find_if(_S_mem_blocks.begin(), _S_mem_blocks.end(), - __gnu_cxx::__aux_balloc::_Inclusive_between<pointer>(__p))); - assert(_iter != _S_mem_blocks.end()); + typedef typename _BPVector::iterator _Iterator; + typedef typename _BPVector::difference_type _Difference_type; - __diff = _iter - _S_mem_blocks.begin(); - __displacement = __p - _S_mem_blocks[__diff].first; - _S_last_dealloc_index = __diff; - } + _Difference_type __diff; + long __displacement; - //Get the position of the iterator that has been found. - const unsigned int __rotate = __displacement % _Bits_Per_Block; - unsigned int *__bit_mapC = reinterpret_cast<unsigned int*>(_S_mem_blocks[__diff].first) - 1; - __bit_mapC -= (__displacement / _Bits_Per_Block); - - _S_bit_free(__bit_mapC, __rotate); - unsigned int *__puse_count = reinterpret_cast<unsigned int*> - (_S_mem_blocks[__diff].first) - - (__gnu_cxx::__aux_balloc::__balloc_num_bit_maps(_S_mem_blocks[__diff]) + 1); + _GLIBCXX_DEBUG_ASSERT(_S_last_dealloc_index >= 0); - assert(*__puse_count != 0); + + if (__gnu_cxx::__detail::_Inclusive_between<_Alloc_block*> + (__real_p) (_S_mem_blocks[_S_last_dealloc_index])) + { + _GLIBCXX_DEBUG_ASSERT(_S_last_dealloc_index + <= _S_mem_blocks.size() - 1); - --(*__puse_count); + // Initial Assumption was correct! + __diff = _S_last_dealloc_index; + __displacement = __real_p - _S_mem_blocks[__diff].first; + } + else + { + _Iterator _iter = __gnu_cxx::__detail:: + __find_if(_S_mem_blocks.begin(), + _S_mem_blocks.end(), + __gnu_cxx::__detail:: + _Inclusive_between<_Alloc_block*>(__real_p)); - if (__builtin_expect(*__puse_count == 0, false)) - { - _S_block_size /= 2; - - //We may safely remove this block. - _Block_pair __bp = _S_mem_blocks[__diff]; - _S_insert_free_list(__puse_count); - _S_mem_blocks.erase(_S_mem_blocks.begin() + __diff); - - //We reset the _S_last_request variable to reflect the erased - //block. We do this to protect future requests after the last - //block has been removed from a particular memory Chunk, - //which in turn has been returned to the free list, and - //hence had been erased from the vector, so the size of the - //vector gets reduced by 1. - if ((_Difference_type)_S_last_request._M_where() >= __diff--) - { - _S_last_request._M_reset(__diff); - // assert(__diff >= 0); - } + _GLIBCXX_DEBUG_ASSERT(_iter != _S_mem_blocks.end()); - //If the Index into the vector of the region of memory that - //might hold the next address that will be passed to - //deallocated may have been invalidated due to the above - //erase procedure being called on the vector, hence we try - //to restore this invariant too. - if (_S_last_dealloc_index >= _S_mem_blocks.size()) - { - _S_last_dealloc_index =(__diff != -1 ? __diff : 0); - assert(_S_last_dealloc_index >= 0); - } - } - } + __diff = _iter - _S_mem_blocks.begin(); + __displacement = __real_p - _S_mem_blocks[__diff].first; + _S_last_dealloc_index = __diff; + } - public: - bitmap_allocator() throw() - { } + // Get the position of the iterator that has been found. + const size_t __rotate = (__displacement + % size_t(__detail::bits_per_block)); + size_t* __bitmapC = + reinterpret_cast<size_t*> + (_S_mem_blocks[__diff].first) - 1; + __bitmapC -= (__displacement / size_t(__detail::bits_per_block)); + + __detail::__bit_free(__bitmapC, __rotate); + size_t* __puse_count = reinterpret_cast<size_t*> + (_S_mem_blocks[__diff].first) + - (__gnu_cxx::__detail::__num_bitmaps(_S_mem_blocks[__diff]) + 1); + + _GLIBCXX_DEBUG_ASSERT(*__puse_count != 0); + + --(*__puse_count); - bitmap_allocator(const bitmap_allocator&) { } + if (__builtin_expect(*__puse_count == 0, false)) + { + _S_block_size /= 2; + + // We can safely remove this block. + // _Block_pair __bp = _S_mem_blocks[__diff]; + this->_M_insert(__puse_count); + _S_mem_blocks.erase(_S_mem_blocks.begin() + __diff); + + // Reset the _S_last_request variable to reflect the + // erased block. We do this to protect future requests + // after the last block has been removed from a particular + // memory Chunk, which in turn has been returned to the + // free list, and hence had been erased from the vector, + // so the size of the vector gets reduced by 1. + if ((_Difference_type)_S_last_request._M_where() >= __diff--) + _S_last_request._M_reset(__diff); + + // If the Index into the vector of the region of memory + // that might hold the next address that will be passed to + // deallocated may have been invalidated due to the above + // erase procedure being called on the vector, hence we + // try to restore this invariant too. + if (_S_last_dealloc_index >= _S_mem_blocks.size()) + { + _S_last_dealloc_index =(__diff != -1 ? __diff : 0); + _GLIBCXX_DEBUG_ASSERT(_S_last_dealloc_index >= 0); + } + } + } - template <typename _Tp1> bitmap_allocator(const bitmap_allocator<_Tp1>&) throw() - { } + public: + bitmap_allocator() throw() + { } - ~bitmap_allocator() throw() - { } + bitmap_allocator(const bitmap_allocator&) + { } - //Complexity: O(1), but internally the complexity depends upon the - //complexity of the function(s) _S_allocate_single_object and - //_S_memory_get. - pointer allocate(size_type __n) - { - if (__builtin_expect(__n == 1, true)) - return _S_allocate_single_object(); - else - return reinterpret_cast<pointer>(_S_memory_get(__n * sizeof(value_type))); - } + template<typename _Tp1> + bitmap_allocator(const bitmap_allocator<_Tp1>&) throw() + { } - //Complexity: Worst case complexity is O(N) where N is the number of - //blocks of size sizeof(value_type) within the free lists that the - //allocator holds. However, this worst case is hit only when the - //user supplies a bogus argument to hint. If the hint argument is - //sensible, then the complexity drops to O(lg(N)), and in extreme - //cases, even drops to as low as O(1). So, if the user supplied - //argument is good, then this function performs very well. - pointer allocate(size_type __n, typename bitmap_allocator<void>::const_pointer) - { - return allocate(__n); - } + ~bitmap_allocator() throw() + { } - void deallocate(pointer __p, size_type __n) throw() - { - if (__builtin_expect(__n == 1, true)) - _S_deallocate_single_object(__p); - else - _S_memory_put(__p); - } + pointer + allocate(size_type __n) + { + if (__builtin_expect(__n > this->max_size(), false)) + std::__throw_bad_alloc(); - pointer address(reference r) const { return &r; } - const_pointer address(const_reference r) const { return &r; } + if (__builtin_expect(__n == 1, true)) + return this->_M_allocate_single_object(); + else + { + const size_type __b = __n * sizeof(value_type); + return reinterpret_cast<pointer>(::operator new(__b)); + } + } - size_type max_size(void) const throw() { return (size_type()-1)/sizeof(value_type); } + pointer + allocate(size_type __n, typename bitmap_allocator<void>::const_pointer) + { return allocate(__n); } - void construct (pointer p, const_reference __data) - { - ::new(p) value_type(__data); - } + void + deallocate(pointer __p, size_type __n) throw() + { + if (__builtin_expect(__p != 0, true)) + { + if (__builtin_expect(__n == 1, true)) + this->_M_deallocate_single_object(__p); + else + ::operator delete(__p); + } + } - void destroy (pointer p) - { - p->~value_type(); - } + pointer + address(reference __r) const + { return &__r; } - }; + const_pointer + address(const_reference __r) const + { return &__r; } - template <typename _Tp> - typename bitmap_allocator<_Tp>::_BPVector bitmap_allocator<_Tp>::_S_mem_blocks; + size_type + max_size() const throw() + { return size_type(-1) / sizeof(value_type); } - template <typename _Tp> - unsigned int bitmap_allocator<_Tp>::_S_block_size = bitmap_allocator<_Tp>::_Bits_Per_Block; + void + construct(pointer __p, const_reference __data) + { ::new(__p) value_type(__data); } - template <typename _Tp> - typename __gnu_cxx::bitmap_allocator<_Tp>::_BPVector::size_type - bitmap_allocator<_Tp>::_S_last_dealloc_index = 0; + void + destroy(pointer __p) + { __p->~value_type(); } + }; - template <typename _Tp> - __gnu_cxx::__aux_balloc::_Bit_map_counter - <typename bitmap_allocator<_Tp>::pointer, typename bitmap_allocator<_Tp>::_BPVec_allocator_type> - bitmap_allocator<_Tp>::_S_last_request(_S_mem_blocks); + template<typename _Tp1, typename _Tp2> + bool + operator==(const bitmap_allocator<_Tp1>&, + const bitmap_allocator<_Tp2>&) throw() + { return true; } + + template<typename _Tp1, typename _Tp2> + bool + operator!=(const bitmap_allocator<_Tp1>&, + const bitmap_allocator<_Tp2>&) throw() + { return false; } + + // Static member definitions. + template<typename _Tp> + typename bitmap_allocator<_Tp>::_BPVector + bitmap_allocator<_Tp>::_S_mem_blocks; + + template<typename _Tp> + size_t bitmap_allocator<_Tp>::_S_block_size = + 2 * size_t(__detail::bits_per_block); + + template<typename _Tp> + typename __gnu_cxx::bitmap_allocator<_Tp>::_BPVector::size_type + bitmap_allocator<_Tp>::_S_last_dealloc_index = 0; + + template<typename _Tp> + __gnu_cxx::__detail::_Bitmap_counter + <typename bitmap_allocator<_Tp>::_Alloc_block*> + bitmap_allocator<_Tp>::_S_last_request(_S_mem_blocks); #if defined __GTHREADS - template <typename _Tp> - __gnu_cxx::_Mutex - bitmap_allocator<_Tp>::_S_mut; + template<typename _Tp> + typename bitmap_allocator<_Tp>::__mutex_type + bitmap_allocator<_Tp>::_S_mut; #endif - template <typename _Tp1, typename _Tp2> - bool operator== (const bitmap_allocator<_Tp1>&, const bitmap_allocator<_Tp2>&) throw() - { - return true; - } - - template <typename _Tp1, typename _Tp2> - bool operator!= (const bitmap_allocator<_Tp1>&, const bitmap_allocator<_Tp2>&) throw() - { - return false; - } -} +_GLIBCXX_END_NAMESPACE +#endif -#endif //_BITMAP_ALLOCATOR_H diff --git a/contrib/libstdc++/include/ext/codecvt_specializations.h b/contrib/libstdc++/include/ext/codecvt_specializations.h new file mode 100644 index 000000000000..f0a6bbed4d65 --- /dev/null +++ b/contrib/libstdc++/include/ext/codecvt_specializations.h @@ -0,0 +1,521 @@ +// Locale support (codecvt) -*- C++ -*- + +// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 22.2.1.5 Template class codecvt +// + +// Written by Benjamin Kosnik <bkoz@redhat.com> + +/** @file ext/codecvt_specializations.h + * This file is a GNU extension to the Standard C++ Library. + */ + +#ifndef _EXT_CODECVT_SPECIALIZATIONS_H +#define _EXT_CODECVT_SPECIALIZATIONS_H 1 + +#include <bits/c++config.h> + +#ifdef _GLIBCXX_USE_ICONV + +#include <locale> +#include <iconv.h> + + // XXX + // Define this here so codecvt.cc can have _S_max_size definition. +#define _GLIBCXX_USE_ENCODING_STATE 1 + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + /// @brief Extension to use icov for dealing with character encodings. + // This includes conversions and comparisons between various character + // sets. This object encapsulates data that may need to be shared between + // char_traits, codecvt and ctype. + class encoding_state + { + public: + // Types: + // NB: A conversion descriptor subsumes and enhances the + // functionality of a simple state type such as mbstate_t. + typedef iconv_t descriptor_type; + + protected: + // Name of internal character set encoding. + std::string _M_int_enc; + + // Name of external character set encoding. + std::string _M_ext_enc; + + // Conversion descriptor between external encoding to internal encoding. + descriptor_type _M_in_desc; + + // Conversion descriptor between internal encoding to external encoding. + descriptor_type _M_out_desc; + + // The byte-order marker for the external encoding, if necessary. + int _M_ext_bom; + + // The byte-order marker for the internal encoding, if necessary. + int _M_int_bom; + + // Number of external bytes needed to construct one complete + // character in the internal encoding. + // NB: -1 indicates variable, or stateful, encodings. + int _M_bytes; + + public: + explicit + encoding_state() + : _M_in_desc(0), _M_out_desc(0), _M_ext_bom(0), _M_int_bom(0), _M_bytes(0) + { } + + explicit + encoding_state(const char* __int, const char* __ext, + int __ibom = 0, int __ebom = 0, int __bytes = 1) + : _M_int_enc(__int), _M_ext_enc(__ext), _M_in_desc(0), _M_out_desc(0), + _M_ext_bom(__ebom), _M_int_bom(__ibom), _M_bytes(__bytes) + { init(); } + + // 21.1.2 traits typedefs + // p4 + // typedef STATE_T state_type + // requires: state_type shall meet the requirements of + // CopyConstructible types (20.1.3) + // NB: This does not preseve the actual state of the conversion + // descriptor member, but it does duplicate the encoding + // information. + encoding_state(const encoding_state& __obj) : _M_in_desc(0), _M_out_desc(0) + { construct(__obj); } + + // Need assignment operator as well. + encoding_state& + operator=(const encoding_state& __obj) + { + construct(__obj); + return *this; + } + + ~encoding_state() + { destroy(); } + + bool + good() const throw() + { + const descriptor_type __err = reinterpret_cast<iconv_t>(-1); + bool __test = _M_in_desc && _M_in_desc != __err; + __test &= _M_out_desc && _M_out_desc != __err; + return __test; + } + + int + character_ratio() const + { return _M_bytes; } + + const std::string + internal_encoding() const + { return _M_int_enc; } + + int + internal_bom() const + { return _M_int_bom; } + + const std::string + external_encoding() const + { return _M_ext_enc; } + + int + external_bom() const + { return _M_ext_bom; } + + const descriptor_type& + in_descriptor() const + { return _M_in_desc; } + + const descriptor_type& + out_descriptor() const + { return _M_out_desc; } + + protected: + void + init() + { + const descriptor_type __err = reinterpret_cast<iconv_t>(-1); + const bool __have_encodings = _M_int_enc.size() && _M_ext_enc.size(); + if (!_M_in_desc && __have_encodings) + { + _M_in_desc = iconv_open(_M_int_enc.c_str(), _M_ext_enc.c_str()); + if (_M_in_desc == __err) + std::__throw_runtime_error(__N("encoding_state::_M_init " + "creating iconv input descriptor failed")); + } + if (!_M_out_desc && __have_encodings) + { + _M_out_desc = iconv_open(_M_ext_enc.c_str(), _M_int_enc.c_str()); + if (_M_out_desc == __err) + std::__throw_runtime_error(__N("encoding_state::_M_init " + "creating iconv output descriptor failed")); + } + } + + void + construct(const encoding_state& __obj) + { + destroy(); + _M_int_enc = __obj._M_int_enc; + _M_ext_enc = __obj._M_ext_enc; + _M_ext_bom = __obj._M_ext_bom; + _M_int_bom = __obj._M_int_bom; + _M_bytes = __obj._M_bytes; + init(); + } + + void + destroy() throw() + { + const descriptor_type __err = reinterpret_cast<iconv_t>(-1); + if (_M_in_desc && _M_in_desc != __err) + { + iconv_close(_M_in_desc); + _M_in_desc = 0; + } + if (_M_out_desc && _M_out_desc != __err) + { + iconv_close(_M_out_desc); + _M_out_desc = 0; + } + } + }; + + /// @brief encoding_char_traits. + // Custom traits type with encoding_state for the state type, and the + // associated fpos<encoding_state> for the position type, all other + // bits equivalent to the required char_traits instantiations. + template<typename _CharT> + struct encoding_char_traits : public std::char_traits<_CharT> + { + typedef encoding_state state_type; + typedef typename std::fpos<state_type> pos_type; + }; + +_GLIBCXX_END_NAMESPACE + + +_GLIBCXX_BEGIN_NAMESPACE(std) + + using __gnu_cxx::encoding_state; + + /// @brief codecvt<InternT, _ExternT, encoding_state> specialization. + // This partial specialization takes advantage of iconv to provide + // code conversions between a large number of character encodings. + template<typename _InternT, typename _ExternT> + class codecvt<_InternT, _ExternT, encoding_state> + : public __codecvt_abstract_base<_InternT, _ExternT, encoding_state> + { + public: + // Types: + typedef codecvt_base::result result; + typedef _InternT intern_type; + typedef _ExternT extern_type; + typedef __gnu_cxx::encoding_state state_type; + typedef state_type::descriptor_type descriptor_type; + + // Data Members: + static locale::id id; + + explicit + codecvt(size_t __refs = 0) + : __codecvt_abstract_base<intern_type, extern_type, state_type>(__refs) + { } + + explicit + codecvt(state_type& __enc, size_t __refs = 0) + : __codecvt_abstract_base<intern_type, extern_type, state_type>(__refs) + { } + + protected: + virtual + ~codecvt() { } + + virtual result + do_out(state_type& __state, const intern_type* __from, + const intern_type* __from_end, const intern_type*& __from_next, + extern_type* __to, extern_type* __to_end, + extern_type*& __to_next) const; + + virtual result + do_unshift(state_type& __state, extern_type* __to, + extern_type* __to_end, extern_type*& __to_next) const; + + virtual result + do_in(state_type& __state, const extern_type* __from, + const extern_type* __from_end, const extern_type*& __from_next, + intern_type* __to, intern_type* __to_end, + intern_type*& __to_next) const; + + virtual int + do_encoding() const throw(); + + virtual bool + do_always_noconv() const throw(); + + virtual int + do_length(state_type&, const extern_type* __from, + const extern_type* __end, size_t __max) const; + + virtual int + do_max_length() const throw(); + }; + + template<typename _InternT, typename _ExternT> + locale::id + codecvt<_InternT, _ExternT, encoding_state>::id; + + // This adaptor works around the signature problems of the second + // argument to iconv(): SUSv2 and others use 'const char**', but glibc 2.2 + // uses 'char**', which matches the POSIX 1003.1-2001 standard. + // Using this adaptor, g++ will do the work for us. + template<typename _Tp> + inline size_t + __iconv_adaptor(size_t(*__func)(iconv_t, _Tp, size_t*, char**, size_t*), + iconv_t __cd, char** __inbuf, size_t* __inbytes, + char** __outbuf, size_t* __outbytes) + { return __func(__cd, (_Tp)__inbuf, __inbytes, __outbuf, __outbytes); } + + template<typename _InternT, typename _ExternT> + codecvt_base::result + codecvt<_InternT, _ExternT, encoding_state>:: + do_out(state_type& __state, const intern_type* __from, + const intern_type* __from_end, const intern_type*& __from_next, + extern_type* __to, extern_type* __to_end, + extern_type*& __to_next) const + { + result __ret = codecvt_base::error; + if (__state.good()) + { + const descriptor_type& __desc = __state.out_descriptor(); + const size_t __fmultiple = sizeof(intern_type); + size_t __fbytes = __fmultiple * (__from_end - __from); + const size_t __tmultiple = sizeof(extern_type); + size_t __tbytes = __tmultiple * (__to_end - __to); + + // Argument list for iconv specifies a byte sequence. Thus, + // all to/from arrays must be brutally casted to char*. + char* __cto = reinterpret_cast<char*>(__to); + char* __cfrom; + size_t __conv; + + // Some encodings need a byte order marker as the first item + // in the byte stream, to designate endian-ness. The default + // value for the byte order marker is NULL, so if this is + // the case, it's not necessary and we can just go on our + // merry way. + int __int_bom = __state.internal_bom(); + if (__int_bom) + { + size_t __size = __from_end - __from; + intern_type* __cfixed = static_cast<intern_type*> + (__builtin_alloca(sizeof(intern_type) * (__size + 1))); + __cfixed[0] = static_cast<intern_type>(__int_bom); + char_traits<intern_type>::copy(__cfixed + 1, __from, __size); + __cfrom = reinterpret_cast<char*>(__cfixed); + __conv = __iconv_adaptor(iconv, __desc, &__cfrom, + &__fbytes, &__cto, &__tbytes); + } + else + { + intern_type* __cfixed = const_cast<intern_type*>(__from); + __cfrom = reinterpret_cast<char*>(__cfixed); + __conv = __iconv_adaptor(iconv, __desc, &__cfrom, &__fbytes, + &__cto, &__tbytes); + } + + if (__conv != size_t(-1)) + { + __from_next = reinterpret_cast<const intern_type*>(__cfrom); + __to_next = reinterpret_cast<extern_type*>(__cto); + __ret = codecvt_base::ok; + } + else + { + if (__fbytes < __fmultiple * (__from_end - __from)) + { + __from_next = reinterpret_cast<const intern_type*>(__cfrom); + __to_next = reinterpret_cast<extern_type*>(__cto); + __ret = codecvt_base::partial; + } + else + __ret = codecvt_base::error; + } + } + return __ret; + } + + template<typename _InternT, typename _ExternT> + codecvt_base::result + codecvt<_InternT, _ExternT, encoding_state>:: + do_unshift(state_type& __state, extern_type* __to, + extern_type* __to_end, extern_type*& __to_next) const + { + result __ret = codecvt_base::error; + if (__state.good()) + { + const descriptor_type& __desc = __state.in_descriptor(); + const size_t __tmultiple = sizeof(intern_type); + size_t __tlen = __tmultiple * (__to_end - __to); + + // Argument list for iconv specifies a byte sequence. Thus, + // all to/from arrays must be brutally casted to char*. + char* __cto = reinterpret_cast<char*>(__to); + size_t __conv = __iconv_adaptor(iconv,__desc, NULL, NULL, + &__cto, &__tlen); + + if (__conv != size_t(-1)) + { + __to_next = reinterpret_cast<extern_type*>(__cto); + if (__tlen == __tmultiple * (__to_end - __to)) + __ret = codecvt_base::noconv; + else if (__tlen == 0) + __ret = codecvt_base::ok; + else + __ret = codecvt_base::partial; + } + else + __ret = codecvt_base::error; + } + return __ret; + } + + template<typename _InternT, typename _ExternT> + codecvt_base::result + codecvt<_InternT, _ExternT, encoding_state>:: + do_in(state_type& __state, const extern_type* __from, + const extern_type* __from_end, const extern_type*& __from_next, + intern_type* __to, intern_type* __to_end, + intern_type*& __to_next) const + { + result __ret = codecvt_base::error; + if (__state.good()) + { + const descriptor_type& __desc = __state.in_descriptor(); + const size_t __fmultiple = sizeof(extern_type); + size_t __flen = __fmultiple * (__from_end - __from); + const size_t __tmultiple = sizeof(intern_type); + size_t __tlen = __tmultiple * (__to_end - __to); + + // Argument list for iconv specifies a byte sequence. Thus, + // all to/from arrays must be brutally casted to char*. + char* __cto = reinterpret_cast<char*>(__to); + char* __cfrom; + size_t __conv; + + // Some encodings need a byte order marker as the first item + // in the byte stream, to designate endian-ness. The default + // value for the byte order marker is NULL, so if this is + // the case, it's not necessary and we can just go on our + // merry way. + int __ext_bom = __state.external_bom(); + if (__ext_bom) + { + size_t __size = __from_end - __from; + extern_type* __cfixed = static_cast<extern_type*> + (__builtin_alloca(sizeof(extern_type) * (__size + 1))); + __cfixed[0] = static_cast<extern_type>(__ext_bom); + char_traits<extern_type>::copy(__cfixed + 1, __from, __size); + __cfrom = reinterpret_cast<char*>(__cfixed); + __conv = __iconv_adaptor(iconv, __desc, &__cfrom, + &__flen, &__cto, &__tlen); + } + else + { + extern_type* __cfixed = const_cast<extern_type*>(__from); + __cfrom = reinterpret_cast<char*>(__cfixed); + __conv = __iconv_adaptor(iconv, __desc, &__cfrom, + &__flen, &__cto, &__tlen); + } + + + if (__conv != size_t(-1)) + { + __from_next = reinterpret_cast<const extern_type*>(__cfrom); + __to_next = reinterpret_cast<intern_type*>(__cto); + __ret = codecvt_base::ok; + } + else + { + if (__flen < static_cast<size_t>(__from_end - __from)) + { + __from_next = reinterpret_cast<const extern_type*>(__cfrom); + __to_next = reinterpret_cast<intern_type*>(__cto); + __ret = codecvt_base::partial; + } + else + __ret = codecvt_base::error; + } + } + return __ret; + } + + template<typename _InternT, typename _ExternT> + int + codecvt<_InternT, _ExternT, encoding_state>:: + do_encoding() const throw() + { + int __ret = 0; + if (sizeof(_ExternT) <= sizeof(_InternT)) + __ret = sizeof(_InternT) / sizeof(_ExternT); + return __ret; + } + + template<typename _InternT, typename _ExternT> + bool + codecvt<_InternT, _ExternT, encoding_state>:: + do_always_noconv() const throw() + { return false; } + + template<typename _InternT, typename _ExternT> + int + codecvt<_InternT, _ExternT, encoding_state>:: + do_length(state_type&, const extern_type* __from, + const extern_type* __end, size_t __max) const + { return std::min(__max, static_cast<size_t>(__end - __from)); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 74. Garbled text for codecvt::do_max_length + template<typename _InternT, typename _ExternT> + int + codecvt<_InternT, _ExternT, encoding_state>:: + do_max_length() const throw() + { return 1; } + +_GLIBCXX_END_NAMESPACE + +#endif + +#endif diff --git a/contrib/libstdc++/include/ext/concurrence.h b/contrib/libstdc++/include/ext/concurrence.h new file mode 100644 index 000000000000..56e07de91e0d --- /dev/null +++ b/contrib/libstdc++/include/ext/concurrence.h @@ -0,0 +1,225 @@ +// Support for concurrent programing -*- C++ -*- + +// Copyright (C) 2003, 2004, 2005, 2006 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/** @file concurrence.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _CONCURRENCE_H +#define _CONCURRENCE_H 1 + +#include <cstdlib> +#include <exception> +#include <bits/gthr.h> +#include <bits/functexcept.h> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + // Available locking policies: + // _S_single single-threaded code that doesn't need to be locked. + // _S_mutex multi-threaded code that requires additional support + // from gthr.h or abstraction layers in concurrance.h. + // _S_atomic multi-threaded code using atomic operations. + enum _Lock_policy { _S_single, _S_mutex, _S_atomic }; + + // Compile time constant that indicates prefered locking policy in + // the current configuration. + static const _Lock_policy __default_lock_policy = +#ifdef __GTHREADS + // NB: This macro doesn't actually exist yet in the compiler, but is + // set somewhat haphazardly at configure time. +#ifdef _GLIBCXX_ATOMIC_BUILTINS + _S_atomic; +#else + _S_mutex; +#endif +#else + _S_single; +#endif + + // NB: As this is used in libsupc++, need to only depend on + // exception. No stdexception classes, no use of std::string. + class __concurrence_lock_error : public std::exception + { + public: + virtual char const* + what() const throw() + { return "__gnu_cxx::__concurrence_lock_error"; } + }; + + class __concurrence_unlock_error : public std::exception + { + public: + virtual char const* + what() const throw() + { return "__gnu_cxx::__concurrence_unlock_error"; } + }; + + // Substitute for concurrence_error object in the case of -fno-exceptions. + inline void + __throw_concurrence_lock_error() + { +#if __EXCEPTIONS + throw __concurrence_lock_error(); +#else + std::abort(); +#endif + } + + inline void + __throw_concurrence_unlock_error() + { +#if __EXCEPTIONS + throw __concurrence_unlock_error(); +#else + std::abort(); +#endif + } + + class __mutex + { + private: + __gthread_mutex_t _M_mutex; + + __mutex(const __mutex&); + __mutex& operator=(const __mutex&); + + public: + __mutex() + { +#if __GTHREADS + if (__gthread_active_p()) + { +#if defined __GTHREAD_MUTEX_INIT + __gthread_mutex_t __tmp = __GTHREAD_MUTEX_INIT; + _M_mutex = __tmp; +#else + __GTHREAD_MUTEX_INIT_FUNCTION(&_M_mutex); +#endif + } +#endif + } + + void lock() + { +#if __GTHREADS + if (__gthread_active_p()) + { + if (__gthread_mutex_lock(&_M_mutex) != 0) + __throw_concurrence_lock_error(); + } +#endif + } + + void unlock() + { +#if __GTHREADS + if (__gthread_active_p()) + { + if (__gthread_mutex_unlock(&_M_mutex) != 0) + __throw_concurrence_unlock_error(); + } +#endif + } + }; + + class __recursive_mutex + { + private: + __gthread_recursive_mutex_t _M_mutex; + + __recursive_mutex(const __recursive_mutex&); + __recursive_mutex& operator=(const __recursive_mutex&); + + public: + __recursive_mutex() + { +#if __GTHREADS + if (__gthread_active_p()) + { +#if defined __GTHREAD_RECURSIVE_MUTEX_INIT + __gthread_recursive_mutex_t __tmp = __GTHREAD_RECURSIVE_MUTEX_INIT; + _M_mutex = __tmp; +#else + __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION(&_M_mutex); +#endif + } +#endif + } + + void lock() + { +#if __GTHREADS + if (__gthread_active_p()) + { + if (__gthread_recursive_mutex_lock(&_M_mutex) != 0) + __throw_concurrence_lock_error(); + } +#endif + } + + void unlock() + { +#if __GTHREADS + if (__gthread_active_p()) + { + if (__gthread_recursive_mutex_unlock(&_M_mutex) != 0) + __throw_concurrence_unlock_error(); + } +#endif + } + }; + + /// @brief Scoped lock idiom. + // Acquire the mutex here with a constructor call, then release with + // the destructor call in accordance with RAII style. + class __scoped_lock + { + public: + typedef __mutex __mutex_type; + + private: + __mutex_type& _M_device; + + __scoped_lock(const __scoped_lock&); + __scoped_lock& operator=(const __scoped_lock&); + + public: + explicit __scoped_lock(__mutex_type& __name) : _M_device(__name) + { _M_device.lock(); } + + ~__scoped_lock() throw() + { _M_device.unlock(); } + }; + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/contrib/libstdc++/include/ext/debug_allocator.h b/contrib/libstdc++/include/ext/debug_allocator.h index 7ea6fb42f980..43a9a8719988 100644 --- a/contrib/libstdc++/include/ext/debug_allocator.h +++ b/contrib/libstdc++/include/ext/debug_allocator.h @@ -1,6 +1,6 @@ // Allocators -*- C++ -*- -// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -15,7 +15,7 @@ // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, // USA. // As a special exception, you may use this file as part of a free software @@ -48,18 +48,18 @@ #ifndef _DEBUG_ALLOCATOR_H #define _DEBUG_ALLOCATOR_H 1 -#include <cstdlib> +#include <stdexcept> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + using std::size_t; -namespace __gnu_cxx -{ /** * @brief A meta-allocator with debugging bits, as per [20.4]. * * This is precisely the allocator defined in the C++ Standard. * - all allocation calls operator new * - all deallocation calls operator delete - * - * (See @link Allocators allocators info @endlink for more.) */ template<typename _Alloc> class debug_allocator @@ -108,14 +108,21 @@ namespace __gnu_cxx void deallocate(pointer __p, size_type __n) { - if (!__p) - abort(); - pointer __real_p = __p - _M_extra; - if (*reinterpret_cast<size_type*>(__real_p) != __n) - abort(); - _M_allocator.deallocate(__real_p, __n + _M_extra); + if (__p) + { + pointer __real_p = __p - _M_extra; + if (*reinterpret_cast<size_type*>(__real_p) != __n) + { + throw std::runtime_error("debug_allocator::deallocate" + " wrong size"); + } + _M_allocator.deallocate(__real_p, __n + _M_extra); + } + else + throw std::runtime_error("debug_allocator::deallocate null pointer"); } }; -} // namespace __gnu_cxx + +_GLIBCXX_END_NAMESPACE #endif diff --git a/contrib/libstdc++/include/ext/functional b/contrib/libstdc++/include/ext/functional index 1a378173177a..f159e11d6399 100644 --- a/contrib/libstdc++/include/ext/functional +++ b/contrib/libstdc++/include/ext/functional @@ -1,6 +1,6 @@ // Functional extensions -*- C++ -*- -// Copyright (C) 2002 Free Software Foundation, Inc. +// Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -15,7 +15,7 @@ // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, // USA. // As a special exception, you may use this file as part of a free software @@ -55,8 +55,7 @@ /** @file ext/functional * This file is a GNU extension to the Standard C++ Library (possibly - * containing extensions from the HP/SGI STL subset). You should only - * include this header if you are using GCC 3 or later. + * containing extensions from the HP/SGI STL subset). */ #ifndef _EXT_FUNCTIONAL @@ -66,330 +65,364 @@ #include <functional> -namespace __gnu_cxx -{ -using std::unary_function; -using std::binary_function; -using std::mem_fun1_t; -using std::const_mem_fun1_t; -using std::mem_fun1_ref_t; -using std::const_mem_fun1_ref_t; - -/** The @c identity_element functions are not part of the C++ standard; SGI - * provided them as an extension. Its argument is an operation, and its - * return value is the identity element for that operation. It is overloaded - * for addition and multiplication, and you can overload it for your own - * nefarious operations. - * - * @addtogroup SGIextensions - * @{ -*/ -/// An \link SGIextensions SGI extension \endlink. -template <class _Tp> inline _Tp identity_element(std::plus<_Tp>) { - return _Tp(0); -} -/// An \link SGIextensions SGI extension \endlink. -template <class _Tp> inline _Tp identity_element(std::multiplies<_Tp>) { - return _Tp(1); -} -/** @} */ - -/** As an extension to the binders, SGI provided composition functors and - * wrapper functions to aid in their creation. The @c unary_compose - * functor is constructed from two functions/functors, @c f and @c g. - * Calling @c operator() with a single argument @c x returns @c f(g(x)). - * The function @c compose1 takes the two functions and constructs a - * @c unary_compose variable for you. - * - * @c binary_compose is constructed from three functors, @c f, @c g1, - * and @c g2. Its @c operator() returns @c f(g1(x),g2(x)). The function - * @compose2 takes f, g1, and g2, and constructs the @c binary_compose - * instance for you. For example, if @c f returns an int, then - * \code - * int answer = (compose2(f,g1,g2))(x); - * \endcode - * is equivalent to - * \code - * int temp1 = g1(x); - * int temp2 = g2(x); - * int answer = f(temp1,temp2); - * \endcode - * But the first form is more compact, and can be passed around as a - * functor to other algorithms. - * - * @addtogroup SGIextensions - * @{ -*/ -/// An \link SGIextensions SGI extension \endlink. -template <class _Operation1, class _Operation2> -class unary_compose - : public unary_function<typename _Operation2::argument_type, - typename _Operation1::result_type> -{ -protected: - _Operation1 _M_fn1; - _Operation2 _M_fn2; -public: - unary_compose(const _Operation1& __x, const _Operation2& __y) - : _M_fn1(__x), _M_fn2(__y) {} - typename _Operation1::result_type - operator()(const typename _Operation2::argument_type& __x) const { - return _M_fn1(_M_fn2(__x)); - } -}; - -/// An \link SGIextensions SGI extension \endlink. -template <class _Operation1, class _Operation2> -inline unary_compose<_Operation1,_Operation2> -compose1(const _Operation1& __fn1, const _Operation2& __fn2) -{ - return unary_compose<_Operation1,_Operation2>(__fn1, __fn2); -} - -/// An \link SGIextensions SGI extension \endlink. -template <class _Operation1, class _Operation2, class _Operation3> -class binary_compose - : public unary_function<typename _Operation2::argument_type, - typename _Operation1::result_type> { -protected: - _Operation1 _M_fn1; - _Operation2 _M_fn2; - _Operation3 _M_fn3; -public: - binary_compose(const _Operation1& __x, const _Operation2& __y, - const _Operation3& __z) - : _M_fn1(__x), _M_fn2(__y), _M_fn3(__z) { } - typename _Operation1::result_type - operator()(const typename _Operation2::argument_type& __x) const { - return _M_fn1(_M_fn2(__x), _M_fn3(__x)); - } -}; - -/// An \link SGIextensions SGI extension \endlink. -template <class _Operation1, class _Operation2, class _Operation3> -inline binary_compose<_Operation1, _Operation2, _Operation3> -compose2(const _Operation1& __fn1, const _Operation2& __fn2, - const _Operation3& __fn3) -{ - return binary_compose<_Operation1,_Operation2,_Operation3> - (__fn1, __fn2, __fn3); -} -/** @} */ - -/** As an extension, SGI provided a functor called @c identity. When a - * functor is required but no operations are desired, this can be used as a - * pass-through. Its @c operator() returns its argument unchanged. - * - * @addtogroup SGIextensions -*/ -template <class _Tp> struct identity : public std::_Identity<_Tp> {}; - -/** @c select1st and @c select2nd are extensions provided by SGI. Their - * @c operator()s - * take a @c std::pair as an argument, and return either the first member - * or the second member, respectively. They can be used (especially with - * the composition functors) to "strip" data from a sequence before - * performing the remainder of an algorithm. - * - * @addtogroup SGIextensions - * @{ -*/ -/// An \link SGIextensions SGI extension \endlink. -template <class _Pair> struct select1st : public std::_Select1st<_Pair> {}; -/// An \link SGIextensions SGI extension \endlink. -template <class _Pair> struct select2nd : public std::_Select2nd<_Pair> {}; -/** @} */ - -// extension documented next -template <class _Arg1, class _Arg2> -struct _Project1st : public binary_function<_Arg1, _Arg2, _Arg1> { - _Arg1 operator()(const _Arg1& __x, const _Arg2&) const { return __x; } -}; - -template <class _Arg1, class _Arg2> -struct _Project2nd : public binary_function<_Arg1, _Arg2, _Arg2> { - _Arg2 operator()(const _Arg1&, const _Arg2& __y) const { return __y; } -}; - -/** The @c operator() of the @c project1st functor takes two arbitrary - * arguments and returns the first one, while @c project2nd returns the - * second one. They are extensions provided by SGI. - * - * @addtogroup SGIextensions - * @{ -*/ - -/// An \link SGIextensions SGI extension \endlink. -template <class _Arg1, class _Arg2> -struct project1st : public _Project1st<_Arg1, _Arg2> {}; - -/// An \link SGIextensions SGI extension \endlink. -template <class _Arg1, class _Arg2> -struct project2nd : public _Project2nd<_Arg1, _Arg2> {}; -/** @} */ - -// extension documented next -template <class _Result> -struct _Constant_void_fun { - typedef _Result result_type; - result_type _M_val; - - _Constant_void_fun(const result_type& __v) : _M_val(__v) {} - const result_type& operator()() const { return _M_val; } -}; - -template <class _Result, class _Argument> -struct _Constant_unary_fun { - typedef _Argument argument_type; - typedef _Result result_type; - result_type _M_val; - - _Constant_unary_fun(const result_type& __v) : _M_val(__v) {} - const result_type& operator()(const _Argument&) const { return _M_val; } -}; - -template <class _Result, class _Arg1, class _Arg2> -struct _Constant_binary_fun { - typedef _Arg1 first_argument_type; - typedef _Arg2 second_argument_type; - typedef _Result result_type; - _Result _M_val; - - _Constant_binary_fun(const _Result& __v) : _M_val(__v) {} - const result_type& operator()(const _Arg1&, const _Arg2&) const { - return _M_val; - } -}; - -/** These three functors are each constructed from a single arbitrary - * variable/value. Later, their @c operator()s completely ignore any - * arguments passed, and return the stored value. - * - @c constant_void_fun's @c operator() takes no arguments - * - @c constant_unary_fun's @c operator() takes one argument (ignored) - * - @c constant_binary_fun's @c operator() takes two arguments (ignored) - * - * The helper creator functions @c constant0, @c constant1, and - * @c constant2 each take a "result" argument and construct variables of - * the appropriate functor type. - * - * @addtogroup SGIextensions - * @{ -*/ -/// An \link SGIextensions SGI extension \endlink. -template <class _Result> -struct constant_void_fun : public _Constant_void_fun<_Result> { - constant_void_fun(const _Result& __v) : _Constant_void_fun<_Result>(__v) {} -}; - -/// An \link SGIextensions SGI extension \endlink. -template <class _Result, - class _Argument = _Result> -struct constant_unary_fun : public _Constant_unary_fun<_Result, _Argument> -{ - constant_unary_fun(const _Result& __v) - : _Constant_unary_fun<_Result, _Argument>(__v) {} -}; - -/// An \link SGIextensions SGI extension \endlink. -template <class _Result, - class _Arg1 = _Result, - class _Arg2 = _Arg1> -struct constant_binary_fun - : public _Constant_binary_fun<_Result, _Arg1, _Arg2> -{ - constant_binary_fun(const _Result& __v) - : _Constant_binary_fun<_Result, _Arg1, _Arg2>(__v) {} -}; - -/// An \link SGIextensions SGI extension \endlink. -template <class _Result> -inline constant_void_fun<_Result> constant0(const _Result& __val) -{ - return constant_void_fun<_Result>(__val); -} - -/// An \link SGIextensions SGI extension \endlink. -template <class _Result> -inline constant_unary_fun<_Result,_Result> constant1(const _Result& __val) -{ - return constant_unary_fun<_Result,_Result>(__val); -} - -/// An \link SGIextensions SGI extension \endlink. -template <class _Result> -inline constant_binary_fun<_Result,_Result,_Result> -constant2(const _Result& __val) -{ - return constant_binary_fun<_Result,_Result,_Result>(__val); -} -/** @} */ - -/** The @c subtractive_rng class is documented on - * <a href="http://www.sgi.com/tech/stl/">SGI's site</a>. - * Note that this code assumes that @c int is 32 bits. - * - * @ingroup SGIextensions -*/ -class subtractive_rng : public unary_function<unsigned int, unsigned int> { -private: - unsigned int _M_table[55]; - size_t _M_index1; - size_t _M_index2; -public: - /// Returns a number less than the argument. - 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 _M_initialize(unsigned int __seed) +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + using std::size_t; + using std::unary_function; + using std::binary_function; + using std::mem_fun1_t; + using std::const_mem_fun1_t; + using std::mem_fun1_ref_t; + using std::const_mem_fun1_ref_t; + + /** The @c identity_element functions are not part of the C++ + * standard; SGI provided them as an extension. Its argument is an + * operation, and its return value is the identity element for that + * operation. It is overloaded for addition and multiplication, + * and you can overload it for your own nefarious operations. + * + * @addtogroup SGIextensions + * @{ + */ + /// An \link SGIextensions SGI extension \endlink. + template <class _Tp> + inline _Tp + identity_element(std::plus<_Tp>) + { return _Tp(0); } + + /// An \link SGIextensions SGI extension \endlink. + template <class _Tp> + inline _Tp + identity_element(std::multiplies<_Tp>) + { return _Tp(1); } + /** @} */ + + /** As an extension to the binders, SGI provided composition functors and + * wrapper functions to aid in their creation. The @c unary_compose + * functor is constructed from two functions/functors, @c f and @c g. + * Calling @c operator() with a single argument @c x returns @c f(g(x)). + * The function @c compose1 takes the two functions and constructs a + * @c unary_compose variable for you. + * + * @c binary_compose is constructed from three functors, @c f, @c g1, + * and @c g2. Its @c operator() returns @c f(g1(x),g2(x)). The function + * @compose2 takes f, g1, and g2, and constructs the @c binary_compose + * instance for you. For example, if @c f returns an int, then + * \code + * int answer = (compose2(f,g1,g2))(x); + * \endcode + * is equivalent to + * \code + * int temp1 = g1(x); + * int temp2 = g2(x); + * int answer = f(temp1,temp2); + * \endcode + * But the first form is more compact, and can be passed around as a + * functor to other algorithms. + * + * @addtogroup SGIextensions + * @{ + */ + /// An \link SGIextensions SGI extension \endlink. + template <class _Operation1, class _Operation2> + class unary_compose + : public unary_function<typename _Operation2::argument_type, + typename _Operation1::result_type> + { + protected: + _Operation1 _M_fn1; + _Operation2 _M_fn2; + + public: + unary_compose(const _Operation1& __x, const _Operation2& __y) + : _M_fn1(__x), _M_fn2(__y) {} + + typename _Operation1::result_type + operator()(const typename _Operation2::argument_type& __x) const + { return _M_fn1(_M_fn2(__x)); } + }; + + /// An \link SGIextensions SGI extension \endlink. + template <class _Operation1, class _Operation2> + inline unary_compose<_Operation1, _Operation2> + compose1(const _Operation1& __fn1, const _Operation2& __fn2) + { return unary_compose<_Operation1,_Operation2>(__fn1, __fn2); } + + /// An \link SGIextensions SGI extension \endlink. + template <class _Operation1, class _Operation2, class _Operation3> + class binary_compose + : public unary_function<typename _Operation2::argument_type, + typename _Operation1::result_type> + { + protected: + _Operation1 _M_fn1; + _Operation2 _M_fn2; + _Operation3 _M_fn3; + + public: + binary_compose(const _Operation1& __x, const _Operation2& __y, + const _Operation3& __z) + : _M_fn1(__x), _M_fn2(__y), _M_fn3(__z) { } + + typename _Operation1::result_type + operator()(const typename _Operation2::argument_type& __x) const + { return _M_fn1(_M_fn2(__x), _M_fn3(__x)); } + }; + + /// An \link SGIextensions SGI extension \endlink. + template <class _Operation1, class _Operation2, class _Operation3> + inline binary_compose<_Operation1, _Operation2, _Operation3> + compose2(const _Operation1& __fn1, const _Operation2& __fn2, + const _Operation3& __fn3) + { return binary_compose<_Operation1, _Operation2, _Operation3> + (__fn1, __fn2, __fn3); } + /** @} */ + + /** As an extension, SGI provided a functor called @c identity. When a + * functor is required but no operations are desired, this can be used as a + * pass-through. Its @c operator() returns its argument unchanged. + * + * @addtogroup SGIextensions + */ + template <class _Tp> + struct identity : public std::_Identity<_Tp> {}; + + /** @c select1st and @c select2nd are extensions provided by SGI. Their + * @c operator()s + * take a @c std::pair as an argument, and return either the first member + * or the second member, respectively. They can be used (especially with + * the composition functors) to "strip" data from a sequence before + * performing the remainder of an algorithm. + * + * @addtogroup SGIextensions + * @{ + */ + /// An \link SGIextensions SGI extension \endlink. + template <class _Pair> + struct select1st : public std::_Select1st<_Pair> {}; + + /// An \link SGIextensions SGI extension \endlink. + template <class _Pair> + struct select2nd : public std::_Select2nd<_Pair> {}; + /** @} */ + + // extension documented next + template <class _Arg1, class _Arg2> + struct _Project1st : public binary_function<_Arg1, _Arg2, _Arg1> + { + _Arg1 + operator()(const _Arg1& __x, const _Arg2&) const + { return __x; } + }; + + template <class _Arg1, class _Arg2> + struct _Project2nd : public binary_function<_Arg1, _Arg2, _Arg2> + { + _Arg2 + operator()(const _Arg1&, const _Arg2& __y) const + { return __y; } + }; + + /** The @c operator() of the @c project1st functor takes two arbitrary + * arguments and returns the first one, while @c project2nd returns the + * second one. They are extensions provided by SGI. + * + * @addtogroup SGIextensions + * @{ + */ + + /// An \link SGIextensions SGI extension \endlink. + template <class _Arg1, class _Arg2> + struct project1st : public _Project1st<_Arg1, _Arg2> {}; + + /// An \link SGIextensions SGI extension \endlink. + template <class _Arg1, class _Arg2> + struct project2nd : public _Project2nd<_Arg1, _Arg2> {}; + /** @} */ + + // extension documented next + template <class _Result> + struct _Constant_void_fun + { + typedef _Result result_type; + result_type _M_val; + + _Constant_void_fun(const result_type& __v) : _M_val(__v) {} + + const result_type& + operator()() const + { return _M_val; } + }; + + template <class _Result, class _Argument> + struct _Constant_unary_fun + { + typedef _Argument argument_type; + typedef _Result result_type; + result_type _M_val; + + _Constant_unary_fun(const result_type& __v) : _M_val(__v) {} + + const result_type& + operator()(const _Argument&) const + { return _M_val; } + }; + + template <class _Result, class _Arg1, class _Arg2> + struct _Constant_binary_fun + { + typedef _Arg1 first_argument_type; + typedef _Arg2 second_argument_type; + typedef _Result result_type; + _Result _M_val; + + _Constant_binary_fun(const _Result& __v) : _M_val(__v) {} + + const result_type& + operator()(const _Arg1&, const _Arg2&) const + { return _M_val; } + }; + + /** These three functors are each constructed from a single arbitrary + * variable/value. Later, their @c operator()s completely ignore any + * arguments passed, and return the stored value. + * - @c constant_void_fun's @c operator() takes no arguments + * - @c constant_unary_fun's @c operator() takes one argument (ignored) + * - @c constant_binary_fun's @c operator() takes two arguments (ignored) + * + * The helper creator functions @c constant0, @c constant1, and + * @c constant2 each take a "result" argument and construct variables of + * the appropriate functor type. + * + * @addtogroup SGIextensions + * @{ + */ + /// An \link SGIextensions SGI extension \endlink. + template <class _Result> + struct constant_void_fun + : public _Constant_void_fun<_Result> + { + constant_void_fun(const _Result& __v) + : _Constant_void_fun<_Result>(__v) {} + }; + + /// An \link SGIextensions SGI extension \endlink. + template <class _Result, class _Argument = _Result> + struct constant_unary_fun : public _Constant_unary_fun<_Result, _Argument> + { + constant_unary_fun(const _Result& __v) + : _Constant_unary_fun<_Result, _Argument>(__v) {} + }; + + /// An \link SGIextensions SGI extension \endlink. + template <class _Result, class _Arg1 = _Result, class _Arg2 = _Arg1> + struct constant_binary_fun + : public _Constant_binary_fun<_Result, _Arg1, _Arg2> + { + constant_binary_fun(const _Result& __v) + : _Constant_binary_fun<_Result, _Arg1, _Arg2>(__v) {} + }; + + /// An \link SGIextensions SGI extension \endlink. + template <class _Result> + inline constant_void_fun<_Result> + constant0(const _Result& __val) + { return constant_void_fun<_Result>(__val); } + + /// An \link SGIextensions SGI extension \endlink. + template <class _Result> + inline constant_unary_fun<_Result, _Result> + constant1(const _Result& __val) + { return constant_unary_fun<_Result, _Result>(__val); } + + /// An \link SGIextensions SGI extension \endlink. + template <class _Result> + inline constant_binary_fun<_Result,_Result,_Result> + constant2(const _Result& __val) + { return constant_binary_fun<_Result, _Result, _Result>(__val); } + /** @} */ + + /** The @c subtractive_rng class is documented on + * <a href="http://www.sgi.com/tech/stl/">SGI's site</a>. + * Note that this code assumes that @c int is 32 bits. + * + * @ingroup SGIextensions + */ + class subtractive_rng + : public unary_function<unsigned int, unsigned int> { - 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]; + private: + unsigned int _M_table[55]; + size_t _M_index1; + size_t _M_index2; + + public: + /// Returns a number less than the argument. + 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; } - for (int __loop = 0; __loop < 4; __loop++) { - for (__i = 0; __i < 55; __i++) + + void + _M_initialize(unsigned int __seed) + { + 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++) _M_table[__i] = _M_table[__i] - _M_table[(1 + __i + 30) % 55]; + } + _M_index1 = 0; + _M_index2 = 31; } - _M_index1 = 0; - _M_index2 = 31; - } - - /// Ctor allowing you to initialize the seed. - subtractive_rng(unsigned int __seed) { _M_initialize(__seed); } - /// Default ctor; initializes its state with some number you don't see. - subtractive_rng() { _M_initialize(161803398u); } -}; - -// Mem_fun adaptor helper functions mem_fun1 and mem_fun1_ref, -// provided for backward compatibility, they are no longer part of -// the C++ standard. - -template <class _Ret, class _Tp, class _Arg> -inline mem_fun1_t<_Ret,_Tp,_Arg> mem_fun1(_Ret (_Tp::*__f)(_Arg)) - { return mem_fun1_t<_Ret,_Tp,_Arg>(__f); } - -template <class _Ret, class _Tp, class _Arg> -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 <class _Ret, class _Tp, class _Arg> -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 <class _Ret, class _Tp, class _Arg> -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); } -} // namespace __gnu_cxx + + /// Ctor allowing you to initialize the seed. + subtractive_rng(unsigned int __seed) + { _M_initialize(__seed); } + + /// Default ctor; initializes its state with some number you don't see. + subtractive_rng() + { _M_initialize(161803398u); } + }; + + // Mem_fun adaptor helper functions mem_fun1 and mem_fun1_ref, + // provided for backward compatibility, they are no longer part of + // the C++ standard. + + template <class _Ret, class _Tp, class _Arg> + inline mem_fun1_t<_Ret, _Tp, _Arg> + mem_fun1(_Ret (_Tp::*__f)(_Arg)) + { return mem_fun1_t<_Ret, _Tp, _Arg>(__f); } + + template <class _Ret, class _Tp, class _Arg> + 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 <class _Ret, class _Tp, class _Arg> + 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 <class _Ret, class _Tp, class _Arg> + 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); } + +_GLIBCXX_END_NAMESPACE #endif diff --git a/contrib/libstdc++/include/ext/hash_fun.h b/contrib/libstdc++/include/ext/hash_fun.h index 27453a6b006b..16c045807547 100644 --- a/contrib/libstdc++/include/ext/hash_fun.h +++ b/contrib/libstdc++/include/ext/hash_fun.h @@ -1,6 +1,6 @@ // 'struct hash' from SGI -*- C++ -*- -// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -15,7 +15,7 @@ // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, // USA. // As a special exception, you may use this file as part of a free software @@ -55,8 +55,7 @@ /** @file ext/hash_fun.h * This file is a GNU extension to the Standard C++ Library (possibly - * containing extensions from the HP/SGI STL subset). You should only - * include this header if you are using GCC 3 or later. + * containing extensions from the HP/SGI STL subset). */ #ifndef _HASH_FUN_H @@ -64,59 +63,110 @@ #include <cstddef> -namespace __gnu_cxx -{ +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + using std::size_t; - template <class _Key> struct hash { }; + template<class _Key> + struct hash { }; inline size_t __stl_hash_string(const char* __s) { unsigned long __h = 0; for ( ; *__s; ++__s) - __h = 5*__h + *__s; + __h = 5 * __h + *__s; return size_t(__h); } - template<> struct hash<char*> - { - size_t operator()(const char* __s) const - { return __stl_hash_string(__s); } - }; - - template<> struct hash<const char*> - { - size_t operator()(const char* __s) const - { return __stl_hash_string(__s); } - }; - - template<> struct hash<char> - { size_t operator()(char __x) const { return __x; } }; - - template<> struct hash<unsigned char> - { size_t operator()(unsigned char __x) const { return __x; } }; - - template<> struct hash<signed char> - { size_t operator()(unsigned char __x) const { return __x; } }; - - template<> struct hash<short> - { size_t operator()(short __x) const { return __x; } }; - - template<> struct hash<unsigned short> - { size_t operator()(unsigned short __x) const { return __x; } }; - - template<> struct hash<int> - { size_t operator()(int __x) const { return __x; } }; - - template<> struct hash<unsigned int> - { size_t operator()(unsigned int __x) const { return __x; } }; - - template<> struct hash<long> - { size_t operator()(long __x) const { return __x; } }; - - template<> struct hash<unsigned long> - { size_t operator()(unsigned long __x) const { return __x; } }; -} // namespace __gnu_cxx + template<> + struct hash<char*> + { + size_t + operator()(const char* __s) const + { return __stl_hash_string(__s); } + }; + + template<> + struct hash<const char*> + { + size_t + operator()(const char* __s) const + { return __stl_hash_string(__s); } + }; + + template<> + struct hash<char> + { + size_t + operator()(char __x) const + { return __x; } + }; + + template<> + struct hash<unsigned char> + { + size_t + operator()(unsigned char __x) const + { return __x; } + }; + + template<> + struct hash<signed char> + { + size_t + operator()(unsigned char __x) const + { return __x; } + }; + + template<> + struct hash<short> + { + size_t + operator()(short __x) const + { return __x; } + }; + + template<> + struct hash<unsigned short> + { + size_t + operator()(unsigned short __x) const + { return __x; } + }; + + template<> + struct hash<int> + { + size_t + operator()(int __x) const + { return __x; } + }; + + template<> + struct hash<unsigned int> + { + size_t + operator()(unsigned int __x) const + { return __x; } + }; + + template<> + struct hash<long> + { + size_t + operator()(long __x) const + { return __x; } + }; + + template<> + struct hash<unsigned long> + { + size_t + operator()(unsigned long __x) const + { return __x; } + }; + +_GLIBCXX_END_NAMESPACE #endif diff --git a/contrib/libstdc++/include/ext/hash_map b/contrib/libstdc++/include/ext/hash_map index 5032c7b3f21f..b6855ebb3beb 100644 --- a/contrib/libstdc++/include/ext/hash_map +++ b/contrib/libstdc++/include/ext/hash_map @@ -1,6 +1,6 @@ // Hashing map implementation -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2004, 2005, 2006 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -15,7 +15,7 @@ // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, // USA. // As a special exception, you may use this file as part of a free software @@ -55,393 +55,551 @@ /** @file ext/hash_map * This file is a GNU extension to the Standard C++ Library (possibly - * containing extensions from the HP/SGI STL subset). You should only - * include this header if you are using GCC 3 or later. + * containing extensions from the HP/SGI STL subset). */ #ifndef _HASH_MAP #define _HASH_MAP 1 +#include <bits/c++config.h> #include <ext/hashtable.h> #include <bits/concept_check.h> -namespace __gnu_cxx -{ +_GLIBCXX_BEGIN_NESTED_NAMESPACE(__gnu_cxx, _GLIBCXX_EXT) + using std::equal_to; using std::allocator; using std::pair; using std::_Select1st; - // Forward declaration of equality operator; needed for friend - // declaration. - template<class _Key, class _Tp, class _HashFcn = hash<_Key>, - class _EqualKey = equal_to<_Key>, class _Alloc = allocator<_Tp> > - class hash_map; - - template<class _Key, class _Tp, class _HashFn, class _EqKey, class _Alloc> - inline bool operator==(const hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc>&, - const hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc>&); -/** - * This is an SGI extension. - * @ingroup SGIextensions - * @doctodo -*/ -template <class _Key, class _Tp, class _HashFcn, class _EqualKey, - class _Alloc> -class hash_map -{ -private: - typedef hashtable<pair<const _Key,_Tp>,_Key,_HashFcn, - _Select1st<pair<const _Key,_Tp> >,_EqualKey,_Alloc> _Ht; - _Ht _M_ht; - -public: - 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() : _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) {} - - template <class _InputIterator> - hash_map(_InputIterator __f, _InputIterator __l) - : _M_ht(100, hasher(), key_equal(), allocator_type()) - { _M_ht.insert_unique(__f, __l); } - template <class _InputIterator> - hash_map(_InputIterator __f, _InputIterator __l, size_type __n) - : _M_ht(__n, hasher(), key_equal(), allocator_type()) - { _M_ht.insert_unique(__f, __l); } - template <class _InputIterator> - 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 <class _InputIterator> - 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); } - -public: - 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); } - - template <class _K1, class _T1, class _HF, class _EqK, class _Al> - friend bool operator== (const hash_map<_K1, _T1, _HF, _EqK, _Al>&, - const hash_map<_K1, _T1, _HF, _EqK, _Al>&); - - 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<iterator,bool> insert(const value_type& __obj) - { return _M_ht.insert_unique(__obj); } - template <class _InputIterator> - void insert(_InputIterator __f, _InputIterator __l) - { _M_ht.insert_unique(__f,__l); } - pair<iterator,bool> insert_noresize(const value_type& __obj) - { return _M_ht.insert_unique_noresize(__obj); } - - iterator find(const key_type& __key) { return _M_ht.find(__key); } - const_iterator find(const key_type& __key) const - { return _M_ht.find(__key); } - - _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 _M_ht.count(__key); } - - pair<iterator, iterator> equal_range(const key_type& __key) - { return _M_ht.equal_range(__key); } - pair<const_iterator, const_iterator> - 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 <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc> -inline bool -operator==(const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1, - const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2) -{ - return __hm1._M_ht == __hm2._M_ht; -} - -template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc> -inline bool -operator!=(const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1, - const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2) { - return !(__hm1 == __hm2); -} - -template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc> -inline void -swap(hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1, - hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2) -{ - __hm1.swap(__hm2); -} - -// Forward declaration of equality operator; needed for friend declaration. - -template <class _Key, class _Tp, - class _HashFcn = hash<_Key>, - class _EqualKey = equal_to<_Key>, - class _Alloc = allocator<_Tp> > -class hash_multimap; - -template <class _Key, class _Tp, class _HF, class _EqKey, class _Alloc> -inline bool -operator==(const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm1, - const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm2); - -/** - * This is an SGI extension. - * @ingroup SGIextensions - * @doctodo -*/ -template <class _Key, class _Tp, class _HashFcn, class _EqualKey, class _Alloc> -class hash_multimap -{ - // concept requirements - __glibcxx_class_requires(_Key, _SGIAssignableConcept) - __glibcxx_class_requires(_Tp, _SGIAssignableConcept) - __glibcxx_class_requires3(_HashFcn, size_t, _Key, _UnaryFunctionConcept) - __glibcxx_class_requires3(_EqualKey, _Key, _Key, _BinaryPredicateConcept) - -private: - typedef hashtable<pair<const _Key, _Tp>, _Key, _HashFcn, - _Select1st<pair<const _Key, _Tp> >, _EqualKey, _Alloc> + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template<class _Key, class _Tp, class _HashFn = hash<_Key>, + class _EqualKey = equal_to<_Key>, class _Alloc = allocator<_Tp> > + class hash_map + { + private: + typedef hashtable<pair<const _Key, _Tp>,_Key, _HashFn, + _Select1st<pair<const _Key, _Tp> >, + _EqualKey, _Alloc> _Ht; + + _Ht _M_ht; + + public: + 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() + : _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) {} + + template<class _InputIterator> + hash_map(_InputIterator __f, _InputIterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + + template<class _InputIterator> + hash_map(_InputIterator __f, _InputIterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + + template<class _InputIterator> + 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<class _InputIterator> + 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); } + + public: + 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); } + + template<class _K1, class _T1, class _HF, class _EqK, class _Al> + friend bool + operator== (const hash_map<_K1, _T1, _HF, _EqK, _Al>&, + const hash_map<_K1, _T1, _HF, _EqK, _Al>&); + + 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<iterator, bool> + insert(const value_type& __obj) + { return _M_ht.insert_unique(__obj); } + + template<class _InputIterator> + void + insert(_InputIterator __f, _InputIterator __l) + { _M_ht.insert_unique(__f, __l); } + + pair<iterator, bool> + insert_noresize(const value_type& __obj) + { return _M_ht.insert_unique_noresize(__obj); } + + iterator + find(const key_type& __key) + { return _M_ht.find(__key); } + + const_iterator + find(const key_type& __key) const + { return _M_ht.find(__key); } + + _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 _M_ht.count(__key); } + + pair<iterator, iterator> + equal_range(const key_type& __key) + { return _M_ht.equal_range(__key); } + + pair<const_iterator, const_iterator> + 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<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc> + inline bool + operator==(const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1, + const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2) + { return __hm1._M_ht == __hm2._M_ht; } + + template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc> + inline bool + operator!=(const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1, + const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2) + { return !(__hm1 == __hm2); } + + template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc> + inline void + swap(hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1, + hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2) + { __hm1.swap(__hm2); } + + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template<class _Key, class _Tp, + class _HashFn = hash<_Key>, + class _EqualKey = equal_to<_Key>, + class _Alloc = allocator<_Tp> > + class hash_multimap + { + // concept requirements + __glibcxx_class_requires(_Key, _SGIAssignableConcept) + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + __glibcxx_class_requires3(_HashFn, size_t, _Key, _UnaryFunctionConcept) + __glibcxx_class_requires3(_EqualKey, _Key, _Key, _BinaryPredicateConcept) + + private: + typedef hashtable<pair<const _Key, _Tp>, _Key, _HashFn, + _Select1st<pair<const _Key, _Tp> >, _EqualKey, _Alloc> _Ht; - _Ht _M_ht; - -public: - 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() : _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) {} - - template <class _InputIterator> - hash_multimap(_InputIterator __f, _InputIterator __l) - : _M_ht(100, hasher(), key_equal(), allocator_type()) - { _M_ht.insert_equal(__f, __l); } - template <class _InputIterator> - hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n) - : _M_ht(__n, hasher(), key_equal(), allocator_type()) - { _M_ht.insert_equal(__f, __l); } - template <class _InputIterator> - 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 <class _InputIterator> - 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); } - -public: - 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); } - - template <class _K1, class _T1, class _HF, class _EqK, class _Al> - friend bool operator== (const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&, - const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&); - - 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 _M_ht.insert_equal(__obj); } - template <class _InputIterator> - void insert(_InputIterator __f, _InputIterator __l) - { _M_ht.insert_equal(__f,__l); } - iterator insert_noresize(const value_type& __obj) - { return _M_ht.insert_equal_noresize(__obj); } - - 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 _M_ht.count(__key); } - - pair<iterator, iterator> equal_range(const key_type& __key) - { return _M_ht.equal_range(__key); } - pair<const_iterator, const_iterator> - 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(); } - -public: - 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 <class _Key, class _Tp, class _HF, class _EqKey, class _Alloc> -inline bool -operator==(const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm1, - const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm2) -{ - return __hm1._M_ht == __hm2._M_ht; -} - -template <class _Key, class _Tp, class _HF, class _EqKey, class _Alloc> -inline bool -operator!=(const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm1, - const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm2) { - return !(__hm1 == __hm2); -} - -template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc> -inline void -swap(hash_multimap<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1, - hash_multimap<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2) -{ - __hm1.swap(__hm2); -} - -} // namespace __gnu_cxx - -namespace std -{ -// Specialization of insert_iterator so that it will work for hash_map -// and hash_multimap. - -template <class _Key, class _Tp, class _HashFn, class _EqKey, class _Alloc> -class insert_iterator<__gnu_cxx::hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc> > { -protected: - typedef __gnu_cxx::hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc> _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; - - insert_iterator(_Container& __x) : container(&__x) {} - insert_iterator(_Container& __x, typename _Container::iterator) - : container(&__x) {} - insert_iterator<_Container>& - operator=(const typename _Container::value_type& __value) { - container->insert(__value); - return *this; - } - insert_iterator<_Container>& operator*() { return *this; } - insert_iterator<_Container>& operator++() { return *this; } - insert_iterator<_Container>& operator++(int) { return *this; } -}; - -template <class _Key, class _Tp, class _HashFn, class _EqKey, class _Alloc> -class insert_iterator<__gnu_cxx::hash_multimap<_Key, _Tp, _HashFn, _EqKey, _Alloc> > { -protected: - typedef __gnu_cxx::hash_multimap<_Key, _Tp, _HashFn, _EqKey, _Alloc> _Container; - _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) : container(&__x) {} - insert_iterator(_Container& __x, typename _Container::iterator) - : container(&__x) {} - insert_iterator<_Container>& - operator=(const typename _Container::value_type& __value) { - container->insert(__value); - return *this; - } - insert_iterator<_Container>& operator*() { return *this; } - insert_iterator<_Container>& operator++() { return *this; } - insert_iterator<_Container>& operator++(int) { return *this; } -}; -} // namespace std + + _Ht _M_ht; + + public: + 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() + : _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) {} + + template<class _InputIterator> + hash_multimap(_InputIterator __f, _InputIterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + + template<class _InputIterator> + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + + template<class _InputIterator> + 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<class _InputIterator> + 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); } + + public: + 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); } + + template<class _K1, class _T1, class _HF, class _EqK, class _Al> + friend bool + operator==(const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&, + const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&); + + 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 _M_ht.insert_equal(__obj); } + + template<class _InputIterator> + void + insert(_InputIterator __f, _InputIterator __l) + { _M_ht.insert_equal(__f,__l); } + + iterator + insert_noresize(const value_type& __obj) + { return _M_ht.insert_equal_noresize(__obj); } + + 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 _M_ht.count(__key); } + + pair<iterator, iterator> + equal_range(const key_type& __key) + { return _M_ht.equal_range(__key); } + + pair<const_iterator, const_iterator> + 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(); } + + public: + 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<class _Key, class _Tp, class _HF, class _EqKey, class _Alloc> + inline bool + operator==(const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1, + const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2) + { return __hm1._M_ht == __hm2._M_ht; } + + template<class _Key, class _Tp, class _HF, class _EqKey, class _Alloc> + inline bool + operator!=(const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1, + const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2) + { return !(__hm1 == __hm2); } + + template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc> + inline void + swap(hash_multimap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1, + hash_multimap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2) + { __hm1.swap(__hm2); } + +_GLIBCXX_END_NESTED_NAMESPACE + +#ifdef _GLIBCXX_DEBUG +# include <debug/hash_map> +#endif + +_GLIBCXX_BEGIN_NAMESPACE(std) + + // Specialization of insert_iterator so that it will work for hash_map + // and hash_multimap. + template<class _Key, class _Tp, class _HashFn, class _EqKey, class _Alloc> + class insert_iterator<__gnu_cxx::hash_map<_Key, _Tp, _HashFn, + _EqKey, _Alloc> > + { + protected: + typedef __gnu_cxx::hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc> + _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; + + insert_iterator(_Container& __x) + : container(&__x) {} + + insert_iterator(_Container& __x, typename _Container::iterator) + : container(&__x) {} + + insert_iterator<_Container>& + operator=(const typename _Container::value_type& __value) + { + container->insert(__value); + return *this; + } + + insert_iterator<_Container>& + operator*() + { return *this; } + + insert_iterator<_Container>& + operator++() { return *this; } + + insert_iterator<_Container>& + operator++(int) + { return *this; } + }; + + template<class _Key, class _Tp, class _HashFn, class _EqKey, class _Alloc> + class insert_iterator<__gnu_cxx::hash_multimap<_Key, _Tp, _HashFn, + _EqKey, _Alloc> > + { + protected: + typedef __gnu_cxx::hash_multimap<_Key, _Tp, _HashFn, _EqKey, _Alloc> + _Container; + _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) + : container(&__x) {} + + insert_iterator(_Container& __x, typename _Container::iterator) + : container(&__x) {} + + insert_iterator<_Container>& + operator=(const typename _Container::value_type& __value) + { + container->insert(__value); + return *this; + } + + insert_iterator<_Container>& + operator*() + { return *this; } + + insert_iterator<_Container>& + operator++() + { return *this; } + + insert_iterator<_Container>& + operator++(int) + { return *this; } + }; + +_GLIBCXX_END_NAMESPACE #endif diff --git a/contrib/libstdc++/include/ext/hash_set b/contrib/libstdc++/include/ext/hash_set index fee64fcbdb0e..668fe13bd2a4 100644 --- a/contrib/libstdc++/include/ext/hash_set +++ b/contrib/libstdc++/include/ext/hash_set @@ -1,6 +1,6 @@ // Hashing set implementation -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2004, 2005, 2006 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -15,7 +15,7 @@ // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, // USA. // As a special exception, you may use this file as part of a free software @@ -55,385 +55,520 @@ /** @file ext/hash_set * This file is a GNU extension to the Standard C++ Library (possibly - * containing extensions from the HP/SGI STL subset). You should only - * include this header if you are using GCC 3 or later. + * containing extensions from the HP/SGI STL subset). */ #ifndef _HASH_SET #define _HASH_SET 1 +#include <bits/c++config.h> #include <ext/hashtable.h> #include <bits/concept_check.h> -namespace __gnu_cxx -{ +_GLIBCXX_BEGIN_NESTED_NAMESPACE(__gnu_cxx, _GLIBCXX_EXT) + using std::equal_to; using std::allocator; using std::pair; using std::_Identity; - // Forward declaration of equality operator; needed for friend - // declaration. - template <class _Value, class _HashFcn = hash<_Value>, - class _EqualKey = equal_to<_Value>, - class _Alloc = allocator<_Value> > - class hash_set; + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template<class _Value, class _HashFcn = hash<_Value>, + class _EqualKey = equal_to<_Value>, + class _Alloc = allocator<_Value> > + class hash_set + { + // concept requirements + __glibcxx_class_requires(_Value, _SGIAssignableConcept) + __glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept) + __glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept) + + private: + 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::size_type size_type; + typedef typename _Ht::difference_type difference_type; + typedef typename _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; + + typedef typename _Ht::const_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_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) {} + + template<class _InputIterator> + hash_set(_InputIterator __f, _InputIterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + + template<class _InputIterator> + hash_set(_InputIterator __f, _InputIterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + + template<class _InputIterator> + 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<class _InputIterator> + 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); } + + public: + 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); } + + template<class _Val, class _HF, class _EqK, class _Al> + friend bool + operator==(const hash_set<_Val, _HF, _EqK, _Al>&, + const hash_set<_Val, _HF, _EqK, _Al>&); + + iterator + begin() const + { return _M_ht.begin(); } + + iterator + end() const + { return _M_ht.end(); } + + public: + pair<iterator, bool> + insert(const value_type& __obj) + { + pair<typename _Ht::iterator, bool> __p = _M_ht.insert_unique(__obj); + return pair<iterator,bool>(__p.first, __p.second); + } + + template<class _InputIterator> + void + insert(_InputIterator __f, _InputIterator __l) + { _M_ht.insert_unique(__f, __l); } + + pair<iterator, bool> + insert_noresize(const value_type& __obj) + { + pair<typename _Ht::iterator, bool> __p + = _M_ht.insert_unique_noresize(__obj); + return pair<iterator, bool>(__p.first, __p.second); + } + + iterator + find(const key_type& __key) const + { return _M_ht.find(__key); } + + size_type + count(const key_type& __key) const + { return _M_ht.count(__key); } + + pair<iterator, iterator> + 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(); } + + public: + 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<class _Value, class _HashFcn, class _EqualKey, class _Alloc> + inline bool + operator==(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1, + const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2) + { return __hs1._M_ht == __hs2._M_ht; } + + template<class _Value, class _HashFcn, class _EqualKey, class _Alloc> + inline bool + operator!=(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1, + const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2) + { return !(__hs1 == __hs2); } + + template<class _Val, class _HashFcn, class _EqualKey, class _Alloc> + inline void + swap(hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1, + hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2) + { __hs1.swap(__hs2); } + + + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template<class _Value, + class _HashFcn = hash<_Value>, + class _EqualKey = equal_to<_Value>, + class _Alloc = allocator<_Value> > + class hash_multiset + { + // concept requirements + __glibcxx_class_requires(_Value, _SGIAssignableConcept) + __glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept) + __glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept) + + private: + 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::size_type size_type; + typedef typename _Ht::difference_type difference_type; + typedef typename _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; + + typedef typename _Ht::const_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_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) {} + + template<class _InputIterator> + hash_multiset(_InputIterator __f, _InputIterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + + template<class _InputIterator> + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + + template<class _InputIterator> + 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<class _InputIterator> + 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); } + + public: + 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); } + + template<class _Val, class _HF, class _EqK, class _Al> + friend bool + operator==(const hash_multiset<_Val, _HF, _EqK, _Al>&, + const hash_multiset<_Val, _HF, _EqK, _Al>&); + + iterator + begin() const + { return _M_ht.begin(); } + + iterator + end() const + { return _M_ht.end(); } + + public: + iterator + insert(const value_type& __obj) + { return _M_ht.insert_equal(__obj); } + + template<class _InputIterator> + void + insert(_InputIterator __f, _InputIterator __l) + { _M_ht.insert_equal(__f,__l); } + + iterator + insert_noresize(const value_type& __obj) + { return _M_ht.insert_equal_noresize(__obj); } + + iterator + find(const key_type& __key) const + { return _M_ht.find(__key); } + + size_type + count(const key_type& __key) const + { return _M_ht.count(__key); } + + pair<iterator, iterator> + 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(); } + + public: + 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<class _Val, class _HashFcn, class _EqualKey, class _Alloc> + inline bool + operator==(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1, + const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2) + { return __hs1._M_ht == __hs2._M_ht; } - template <class _Value, class _HashFcn, class _EqualKey, class _Alloc> + template<class _Val, class _HashFcn, class _EqualKey, class _Alloc> inline bool - operator==(const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs1, - const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs2); - -/** - * This is an SGI extension. - * @ingroup SGIextensions - * @doctodo -*/ -template <class _Value, class _HashFcn, class _EqualKey, class _Alloc> -class hash_set -{ - // concept requirements - __glibcxx_class_requires(_Value, _SGIAssignableConcept) - __glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept) - __glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept) - -private: - 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::size_type size_type; - typedef typename _Ht::difference_type difference_type; - typedef typename _Alloc::pointer pointer; - typedef typename _Alloc::const_pointer const_pointer; - typedef typename _Alloc::reference reference; - typedef typename _Alloc::const_reference const_reference; - - typedef typename _Ht::const_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_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) {} - - template <class _InputIterator> - hash_set(_InputIterator __f, _InputIterator __l) - : _M_ht(100, hasher(), key_equal(), allocator_type()) - { _M_ht.insert_unique(__f, __l); } - template <class _InputIterator> - hash_set(_InputIterator __f, _InputIterator __l, size_type __n) - : _M_ht(__n, hasher(), key_equal(), allocator_type()) - { _M_ht.insert_unique(__f, __l); } - template <class _InputIterator> - 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 <class _InputIterator> - 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); } - -public: - 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); } - - template <class _Val, class _HF, class _EqK, class _Al> - friend bool operator== (const hash_set<_Val, _HF, _EqK, _Al>&, - const hash_set<_Val, _HF, _EqK, _Al>&); - - iterator begin() const { return _M_ht.begin(); } - iterator end() const { return _M_ht.end(); } - -public: - pair<iterator, bool> insert(const value_type& __obj) + operator!=(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1, + const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2) + { return !(__hs1 == __hs2); } + + template<class _Val, class _HashFcn, class _EqualKey, class _Alloc> + inline void + swap(hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1, + hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2) + { __hs1.swap(__hs2); } + +_GLIBCXX_END_NESTED_NAMESPACE + +#ifdef _GLIBCXX_DEBUG +# include <debug/hash_set> +#endif + +_GLIBCXX_BEGIN_NAMESPACE(std) + + // Specialization of insert_iterator so that it will work for hash_set + // and hash_multiset. + template<class _Value, class _HashFcn, class _EqualKey, class _Alloc> + class insert_iterator<__gnu_cxx::hash_set<_Value, _HashFcn, + _EqualKey, _Alloc> > + { + protected: + typedef __gnu_cxx::hash_set<_Value, _HashFcn, _EqualKey, _Alloc> + _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; + + insert_iterator(_Container& __x) + : container(&__x) {} + + insert_iterator(_Container& __x, typename _Container::iterator) + : container(&__x) {} + + insert_iterator<_Container>& + operator=(const typename _Container::value_type& __value) + { + container->insert(__value); + return *this; + } + + insert_iterator<_Container>& + operator*() + { return *this; } + + insert_iterator<_Container>& + operator++() + { return *this; } + + insert_iterator<_Container>& + operator++(int) + { return *this; } + }; + + template<class _Value, class _HashFcn, class _EqualKey, class _Alloc> + class insert_iterator<__gnu_cxx::hash_multiset<_Value, _HashFcn, + _EqualKey, _Alloc> > { - pair<typename _Ht::iterator, bool> __p = _M_ht.insert_unique(__obj); - return pair<iterator,bool>(__p.first, __p.second); - } - template <class _InputIterator> - void insert(_InputIterator __f, _InputIterator __l) - { _M_ht.insert_unique(__f,__l); } - pair<iterator, bool> insert_noresize(const value_type& __obj) - { - pair<typename _Ht::iterator, bool> __p = - _M_ht.insert_unique_noresize(__obj); - return pair<iterator, bool>(__p.first, __p.second); - } - - iterator find(const key_type& __key) const { return _M_ht.find(__key); } - - size_type count(const key_type& __key) const { return _M_ht.count(__key); } - - pair<iterator, iterator> 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(); } - -public: - 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 <class _Value, class _HashFcn, class _EqualKey, class _Alloc> -inline bool -operator==(const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs1, - const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs2) -{ - return __hs1._M_ht == __hs2._M_ht; -} - -template <class _Value, class _HashFcn, class _EqualKey, class _Alloc> -inline bool -operator!=(const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs1, - const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs2) { - return !(__hs1 == __hs2); -} - -template <class _Val, class _HashFcn, class _EqualKey, class _Alloc> -inline void -swap(hash_set<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, - hash_set<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2) -{ - __hs1.swap(__hs2); -} - - -template <class _Value, - class _HashFcn = hash<_Value>, - class _EqualKey = equal_to<_Value>, - class _Alloc = allocator<_Value> > -class hash_multiset; - -template <class _Val, class _HashFcn, class _EqualKey, class _Alloc> -inline bool -operator==(const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, - const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2); - - -/** - * This is an SGI extension. - * @ingroup SGIextensions - * @doctodo -*/ -template <class _Value, class _HashFcn, class _EqualKey, class _Alloc> -class hash_multiset -{ - // concept requirements - __glibcxx_class_requires(_Value, _SGIAssignableConcept) - __glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept) - __glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept) - -private: - 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::size_type size_type; - typedef typename _Ht::difference_type difference_type; - typedef typename _Alloc::pointer pointer; - typedef typename _Alloc::const_pointer const_pointer; - typedef typename _Alloc::reference reference; - typedef typename _Alloc::const_reference const_reference; - - typedef typename _Ht::const_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_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) {} - - template <class _InputIterator> - hash_multiset(_InputIterator __f, _InputIterator __l) - : _M_ht(100, hasher(), key_equal(), allocator_type()) - { _M_ht.insert_equal(__f, __l); } - template <class _InputIterator> - hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n) - : _M_ht(__n, hasher(), key_equal(), allocator_type()) - { _M_ht.insert_equal(__f, __l); } - template <class _InputIterator> - 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 <class _InputIterator> - 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); } - -public: - 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); } - - template <class _Val, class _HF, class _EqK, class _Al> - friend bool operator== (const hash_multiset<_Val, _HF, _EqK, _Al>&, - const hash_multiset<_Val, _HF, _EqK, _Al>&); - - iterator begin() const { return _M_ht.begin(); } - iterator end() const { return _M_ht.end(); } - -public: - iterator insert(const value_type& __obj) - { return _M_ht.insert_equal(__obj); } - template <class _InputIterator> - void insert(_InputIterator __f, _InputIterator __l) - { _M_ht.insert_equal(__f,__l); } - iterator insert_noresize(const value_type& __obj) - { return _M_ht.insert_equal_noresize(__obj); } - - iterator find(const key_type& __key) const { return _M_ht.find(__key); } - - size_type count(const key_type& __key) const { return _M_ht.count(__key); } - - pair<iterator, iterator> 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(); } - -public: - 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 <class _Val, class _HashFcn, class _EqualKey, class _Alloc> -inline bool -operator==(const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, - const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2) -{ - return __hs1._M_ht == __hs2._M_ht; -} - -template <class _Val, class _HashFcn, class _EqualKey, class _Alloc> -inline bool -operator!=(const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, - const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2) { - return !(__hs1 == __hs2); -} - -template <class _Val, class _HashFcn, class _EqualKey, class _Alloc> -inline void -swap(hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, - hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2) { - __hs1.swap(__hs2); -} - -} // namespace __gnu_cxx - -namespace std -{ -// Specialization of insert_iterator so that it will work for hash_set -// and hash_multiset. - -template <class _Value, class _HashFcn, class _EqualKey, class _Alloc> -class insert_iterator<__gnu_cxx::hash_set<_Value, _HashFcn, _EqualKey, _Alloc> > { -protected: - typedef __gnu_cxx::hash_set<_Value, _HashFcn, _EqualKey, _Alloc> _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; - - insert_iterator(_Container& __x) : container(&__x) {} - insert_iterator(_Container& __x, typename _Container::iterator) - : container(&__x) {} - insert_iterator<_Container>& - operator=(const typename _Container::value_type& __value) { - container->insert(__value); - return *this; - } - insert_iterator<_Container>& operator*() { return *this; } - insert_iterator<_Container>& operator++() { return *this; } - insert_iterator<_Container>& operator++(int) { return *this; } -}; - -template <class _Value, class _HashFcn, class _EqualKey, class _Alloc> -class insert_iterator<__gnu_cxx::hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc> > { -protected: - typedef __gnu_cxx::hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc> _Container; - _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) : container(&__x) {} - insert_iterator(_Container& __x, typename _Container::iterator) - : container(&__x) {} - insert_iterator<_Container>& - operator=(const typename _Container::value_type& __value) { - container->insert(__value); - return *this; - } - insert_iterator<_Container>& operator*() { return *this; } - insert_iterator<_Container>& operator++() { return *this; } - insert_iterator<_Container>& operator++(int) { return *this; } -}; -} // namespace std + protected: + typedef __gnu_cxx::hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc> + _Container; + _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) + : container(&__x) {} + + insert_iterator(_Container& __x, typename _Container::iterator) + : container(&__x) {} + + insert_iterator<_Container>& + operator=(const typename _Container::value_type& __value) + { + container->insert(__value); + return *this; + } + + insert_iterator<_Container>& + operator*() + { return *this; } + + insert_iterator<_Container>& + operator++() + { return *this; } + + insert_iterator<_Container>& + operator++(int) { return *this; } + }; + +_GLIBCXX_END_NAMESPACE #endif diff --git a/contrib/libstdc++/include/ext/hashtable.h b/contrib/libstdc++/include/ext/hashtable.h index 9f2fb1ef151d..233806fb7459 100644 --- a/contrib/libstdc++/include/ext/hashtable.h +++ b/contrib/libstdc++/include/ext/hashtable.h @@ -1,6 +1,7 @@ // Hashtable implementation used by containers -*- C++ -*- -// Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 +// Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -15,7 +16,7 @@ // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, // USA. // As a special exception, you may use this file as part of a free software @@ -55,8 +56,7 @@ /** @file ext/hashtable.h * This file is a GNU extension to the Standard C++ Library (possibly - * containing extensions from the HP/SGI STL subset). You should only - * include this header if you are using GCC 3 or later. + * containing extensions from the HP/SGI STL subset). */ #ifndef _HASHTABLE_H @@ -71,924 +71,1060 @@ #include <bits/stl_function.h> #include <ext/hash_fun.h> -namespace __gnu_cxx -{ -using std::size_t; -using std::ptrdiff_t; -using std::forward_iterator_tag; -using std::input_iterator_tag; -using std::_Construct; -using std::_Destroy; -using std::distance; -using std::vector; -using std::pair; -using std::__iterator_category; - -template <class _Val> -struct _Hashtable_node -{ - _Hashtable_node* _M_next; - _Val _M_val; -}; - -template <class _Val, class _Key, class _HashFcn, class _ExtractKey, - class _EqualKey, class _Alloc = std::allocator<_Val> > -class hashtable; - -template <class _Val, class _Key, class _HashFcn, - class _ExtractKey, class _EqualKey, class _Alloc> -struct _Hashtable_iterator; - -template <class _Val, class _Key, class _HashFcn, - class _ExtractKey, class _EqualKey, class _Alloc> -struct _Hashtable_const_iterator; - -template <class _Val, class _Key, class _HashFcn, - class _ExtractKey, class _EqualKey, class _Alloc> -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<_Val, _Key, _HashFcn, - _ExtractKey, _EqualKey, _Alloc> - const_iterator; - typedef _Hashtable_node<_Val> _Node; - - typedef forward_iterator_tag iterator_category; - typedef _Val value_type; - typedef ptrdiff_t difference_type; - typedef size_t size_type; - typedef _Val& reference; - typedef _Val* pointer; - - _Node* _M_cur; - _Hashtable* _M_ht; - - _Hashtable_iterator(_Node* __n, _Hashtable* __tab) - : _M_cur(__n), _M_ht(__tab) {} - _Hashtable_iterator() {} - reference operator*() const { return _M_cur->_M_val; } - pointer operator->() const { return &(operator*()); } - iterator& operator++(); - iterator operator++(int); - 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 <class _Val, class _Key, class _HashFcn, - class _ExtractKey, class _EqualKey, class _Alloc> -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<_Val, _Key, _HashFcn, - _ExtractKey, _EqualKey, _Alloc> - const_iterator; - typedef _Hashtable_node<_Val> _Node; - - typedef forward_iterator_tag iterator_category; - typedef _Val value_type; - typedef ptrdiff_t difference_type; - typedef size_t size_type; - 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; } - pointer operator->() const { return &(operator*()); } - const_iterator& operator++(); - const_iterator operator++(int); - 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. -enum { _S_num_primes = 28 }; - -static const unsigned long __stl_prime_list[_S_num_primes] = -{ - 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) -{ - const unsigned long* __first = __stl_prime_list; - const unsigned long* __last = __stl_prime_list + (int)_S_num_primes; - const unsigned long* pos = std::lower_bound(__first, __last, __n); - return pos == __last ? *(__last - 1) : *pos; -} - -// Forward declaration of operator==. - -template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -class hashtable; - -template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -bool operator==(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1, - const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2); - - -// 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 _Val, class _Key, class _HashFcn, - class _ExtractKey, class _EqualKey, class _Alloc> -class hashtable { -public: - 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; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef value_type& reference; - typedef const value_type& const_reference; - - hasher hash_funct() const { return _M_hash; } - key_equal key_eq() const { return _M_equals; } - -private: - typedef _Hashtable_node<_Val> _Node; - -public: - typedef typename _Alloc::template rebind<value_type>::other allocator_type; - allocator_type get_allocator() const { return _M_node_allocator; } -private: - typedef typename _Alloc::template rebind<_Node>::other _Node_Alloc; - typedef typename _Alloc::template rebind<_Node*>::other _Nodeptr_Alloc; - typedef vector<_Node*, _Nodeptr_Alloc> _Vector_type; - - _Node_Alloc _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); } - -private: - hasher _M_hash; - key_equal _M_equals; - _ExtractKey _M_get_key; - _Vector_type _M_buckets; - size_type _M_num_elements; - -public: - 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<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>; - friend struct - _Hashtable_const_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>; - -public: - hashtable(size_type __n, - const _HashFcn& __hf, - const _EqualKey& __eql, - const _ExtractKey& __ext, - const allocator_type& __a = allocator_type()) - : _M_node_allocator(__a), - _M_hash(__hf), - _M_equals(__eql), - _M_get_key(__ext), - _M_buckets(__a), - _M_num_elements(0) - { - _M_initialize_buckets(__n); - } +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + using std::size_t; + using std::ptrdiff_t; + using std::forward_iterator_tag; + using std::input_iterator_tag; + using std::_Construct; + using std::_Destroy; + using std::distance; + using std::vector; + using std::pair; + using std::__iterator_category; + + template<class _Val> + struct _Hashtable_node + { + _Hashtable_node* _M_next; + _Val _M_val; + }; - hashtable(size_type __n, - const _HashFcn& __hf, - const _EqualKey& __eql, - const allocator_type& __a = allocator_type()) - : _M_node_allocator(__a), - _M_hash(__hf), - _M_equals(__eql), - _M_get_key(_ExtractKey()), - _M_buckets(__a), - _M_num_elements(0) - { - _M_initialize_buckets(__n); - } + template<class _Val, class _Key, class _HashFcn, class _ExtractKey, + class _EqualKey, class _Alloc = std::allocator<_Val> > + class hashtable; - hashtable(const hashtable& __ht) - : _M_node_allocator(__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) - { - _M_copy_from(__ht); - } + template<class _Val, class _Key, class _HashFcn, + class _ExtractKey, class _EqualKey, class _Alloc> + struct _Hashtable_iterator; + + template<class _Val, class _Key, class _HashFcn, + class _ExtractKey, class _EqualKey, class _Alloc> + struct _Hashtable_const_iterator; - hashtable& operator= (const hashtable& __ht) + template<class _Val, class _Key, class _HashFcn, + class _ExtractKey, class _EqualKey, class _Alloc> + 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<_Val, _Key, _HashFcn, + _ExtractKey, _EqualKey, _Alloc> + const_iterator; + typedef _Hashtable_node<_Val> _Node; + typedef forward_iterator_tag iterator_category; + typedef _Val value_type; + typedef ptrdiff_t difference_type; + typedef size_t size_type; + typedef _Val& reference; + typedef _Val* pointer; + + _Node* _M_cur; + _Hashtable* _M_ht; + + _Hashtable_iterator(_Node* __n, _Hashtable* __tab) + : _M_cur(__n), _M_ht(__tab) { } + + _Hashtable_iterator() { } + + reference + operator*() const + { return _M_cur->_M_val; } + + pointer + operator->() const + { return &(operator*()); } + + iterator& + operator++(); + + iterator + operator++(int); + + 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<class _Val, class _Key, class _HashFcn, + class _ExtractKey, class _EqualKey, class _Alloc> + 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<_Val, _Key, _HashFcn, + _ExtractKey, _EqualKey, _Alloc> + const_iterator; + typedef _Hashtable_node<_Val> _Node; + + typedef forward_iterator_tag iterator_category; + typedef _Val value_type; + typedef ptrdiff_t difference_type; + typedef size_t size_type; + 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; } + + pointer + operator->() const + { return &(operator*()); } + + const_iterator& + operator++(); + + const_iterator + operator++(int); + + 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. + enum { _S_num_primes = 28 }; + + static const unsigned long __stl_prime_list[_S_num_primes] = + { + 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) { - if (&__ht != this) { - clear(); - _M_hash = __ht._M_hash; - _M_equals = __ht._M_equals; - _M_get_key = __ht._M_get_key; - _M_copy_from(__ht); - } - return *this; + const unsigned long* __first = __stl_prime_list; + const unsigned long* __last = __stl_prime_list + (int)_S_num_primes; + const unsigned long* pos = std::lower_bound(__first, __last, __n); + return pos == __last ? *(__last - 1) : *pos; } - ~hashtable() { clear(); } + // Forward declaration of operator==. + template<class _Val, class _Key, class _HF, class _Ex, + class _Eq, class _All> + class hashtable; + + template<class _Val, class _Key, class _HF, class _Ex, + class _Eq, class _All> + bool + operator==(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1, + const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2); + + // 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 _Val, class _Key, class _HashFcn, + class _ExtractKey, class _EqualKey, class _Alloc> + class hashtable + { + public: + 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; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + + hasher + hash_funct() const + { return _M_hash; } + + key_equal + key_eq() const + { return _M_equals; } + + private: + typedef _Hashtable_node<_Val> _Node; + + public: + typedef typename _Alloc::template rebind<value_type>::other allocator_type; + allocator_type + get_allocator() const + { return _M_node_allocator; } + + private: + typedef typename _Alloc::template rebind<_Node>::other _Node_Alloc; + typedef typename _Alloc::template rebind<_Node*>::other _Nodeptr_Alloc; + typedef vector<_Node*, _Nodeptr_Alloc> _Vector_type; + + _Node_Alloc _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); } + + private: + hasher _M_hash; + key_equal _M_equals; + _ExtractKey _M_get_key; + _Vector_type _M_buckets; + size_type _M_num_elements; + + public: + 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<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc>; + + friend struct + _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey, + _EqualKey, _Alloc>; + + public: + hashtable(size_type __n, const _HashFcn& __hf, + const _EqualKey& __eql, const _ExtractKey& __ext, + const allocator_type& __a = allocator_type()) + : _M_node_allocator(__a), _M_hash(__hf), _M_equals(__eql), + _M_get_key(__ext), _M_buckets(__a), _M_num_elements(0) + { _M_initialize_buckets(__n); } + + hashtable(size_type __n, const _HashFcn& __hf, + const _EqualKey& __eql, + const allocator_type& __a = allocator_type()) + : _M_node_allocator(__a), _M_hash(__hf), _M_equals(__eql), + _M_get_key(_ExtractKey()), _M_buckets(__a), _M_num_elements(0) + { _M_initialize_buckets(__n); } + + hashtable(const hashtable& __ht) + : _M_node_allocator(__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) + { _M_copy_from(__ht); } + + hashtable& + operator= (const hashtable& __ht) + { + if (&__ht != this) + { + clear(); + _M_hash = __ht._M_hash; + _M_equals = __ht._M_equals; + _M_get_key = __ht._M_get_key; + _M_copy_from(__ht); + } + return *this; + } - size_type size() const { return _M_num_elements; } - size_type max_size() const { return size_type(-1); } - bool empty() const { return size() == 0; } + ~hashtable() + { clear(); } - void swap(hashtable& __ht) - { - 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); - } + size_type + size() const + { return _M_num_elements; } - iterator begin() - { - for (size_type __n = 0; __n < _M_buckets.size(); ++__n) - if (_M_buckets[__n]) - return iterator(_M_buckets[__n], this); - return end(); - } + size_type + max_size() const + { return size_type(-1); } - iterator end() { return iterator(0, this); } + bool + empty() const + { return size() == 0; } - const_iterator begin() const - { - for (size_type __n = 0; __n < _M_buckets.size(); ++__n) - if (_M_buckets[__n]) - return const_iterator(_M_buckets[__n], this); - return end(); - } + void + swap(hashtable& __ht) + { + 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); + } - const_iterator end() const { return const_iterator(0, this); } + iterator + begin() + { + for (size_type __n = 0; __n < _M_buckets.size(); ++__n) + if (_M_buckets[__n]) + return iterator(_M_buckets[__n], this); + return end(); + } - template <class _Vl, class _Ky, class _HF, class _Ex, class _Eq, class _Al> - friend bool operator== (const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&, - const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&); -public: + iterator + end() + { return iterator(0, this); } - size_type bucket_count() const { return _M_buckets.size(); } + const_iterator + begin() const + { + for (size_type __n = 0; __n < _M_buckets.size(); ++__n) + if (_M_buckets[__n]) + return const_iterator(_M_buckets[__n], this); + return end(); + } - size_type max_bucket_count() const - { return __stl_prime_list[(int)_S_num_primes - 1]; } + const_iterator + end() const + { return const_iterator(0, this); } - size_type elems_in_bucket(size_type __bucket) const - { - size_type __result = 0; - for (_Node* __cur = _M_buckets[__bucket]; __cur; __cur = __cur->_M_next) - __result += 1; - return __result; - } + template<class _Vl, class _Ky, class _HF, class _Ex, class _Eq, + class _Al> + friend bool + operator==(const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&, + const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&); - pair<iterator, bool> insert_unique(const value_type& __obj) - { - resize(_M_num_elements + 1); - return insert_unique_noresize(__obj); - } + public: + size_type + bucket_count() const + { return _M_buckets.size(); } - iterator insert_equal(const value_type& __obj) - { - resize(_M_num_elements + 1); - return insert_equal_noresize(__obj); - } + size_type + max_bucket_count() const + { return __stl_prime_list[(int)_S_num_primes - 1]; } - pair<iterator, bool> insert_unique_noresize(const value_type& __obj); - iterator insert_equal_noresize(const value_type& __obj); + size_type + elems_in_bucket(size_type __bucket) const + { + size_type __result = 0; + for (_Node* __n = _M_buckets[__bucket]; __n; __n = __n->_M_next) + __result += 1; + return __result; + } - template <class _InputIterator> - void insert_unique(_InputIterator __f, _InputIterator __l) - { - insert_unique(__f, __l, __iterator_category(__f)); - } + pair<iterator, bool> + insert_unique(const value_type& __obj) + { + resize(_M_num_elements + 1); + return insert_unique_noresize(__obj); + } - template <class _InputIterator> - void insert_equal(_InputIterator __f, _InputIterator __l) - { - insert_equal(__f, __l, __iterator_category(__f)); - } + iterator + insert_equal(const value_type& __obj) + { + resize(_M_num_elements + 1); + return insert_equal_noresize(__obj); + } - template <class _InputIterator> - void insert_unique(_InputIterator __f, _InputIterator __l, - input_iterator_tag) - { - for ( ; __f != __l; ++__f) - insert_unique(*__f); - } + pair<iterator, bool> + insert_unique_noresize(const value_type& __obj); - template <class _InputIterator> - void insert_equal(_InputIterator __f, _InputIterator __l, - input_iterator_tag) - { - for ( ; __f != __l; ++__f) - insert_equal(*__f); - } + iterator + insert_equal_noresize(const value_type& __obj); - template <class _ForwardIterator> - void insert_unique(_ForwardIterator __f, _ForwardIterator __l, - forward_iterator_tag) - { - size_type __n = distance(__f, __l); - resize(_M_num_elements + __n); - for ( ; __n > 0; --__n, ++__f) - insert_unique_noresize(*__f); - } + template<class _InputIterator> + void + insert_unique(_InputIterator __f, _InputIterator __l) + { insert_unique(__f, __l, __iterator_category(__f)); } - template <class _ForwardIterator> - void insert_equal(_ForwardIterator __f, _ForwardIterator __l, - forward_iterator_tag) - { - size_type __n = distance(__f, __l); - resize(_M_num_elements + __n); - for ( ; __n > 0; --__n, ++__f) - insert_equal_noresize(*__f); - } + template<class _InputIterator> + void + insert_equal(_InputIterator __f, _InputIterator __l) + { insert_equal(__f, __l, __iterator_category(__f)); } - reference find_or_insert(const value_type& __obj); + template<class _InputIterator> + void + insert_unique(_InputIterator __f, _InputIterator __l, + input_iterator_tag) + { + for ( ; __f != __l; ++__f) + insert_unique(*__f); + } + + template<class _InputIterator> + void + insert_equal(_InputIterator __f, _InputIterator __l, + input_iterator_tag) + { + for ( ; __f != __l; ++__f) + insert_equal(*__f); + } + + template<class _ForwardIterator> + void + insert_unique(_ForwardIterator __f, _ForwardIterator __l, + forward_iterator_tag) + { + size_type __n = distance(__f, __l); + resize(_M_num_elements + __n); + for ( ; __n > 0; --__n, ++__f) + insert_unique_noresize(*__f); + } + + template<class _ForwardIterator> + void + insert_equal(_ForwardIterator __f, _ForwardIterator __l, + forward_iterator_tag) + { + size_type __n = distance(__f, __l); + resize(_M_num_elements + __n); + for ( ; __n > 0; --__n, ++__f) + insert_equal_noresize(*__f); + } - iterator find(const key_type& __key) - { - 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); - } + reference + find_or_insert(const value_type& __obj); - const_iterator find(const key_type& __key) const - { - 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); - } + iterator + find(const key_type& __key) + { + 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); + } - size_type count(const key_type& __key) const - { - const size_type __n = _M_bkt_num_key(__key); - size_type __result = 0; + const_iterator + find(const key_type& __key) const + { + 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); + } - 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; - } + size_type + count(const key_type& __key) const + { + const size_type __n = _M_bkt_num_key(__key); + size_type __result = 0; + + 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<iterator, iterator> - equal_range(const key_type& __key); + pair<iterator, iterator> + equal_range(const key_type& __key); - pair<const_iterator, const_iterator> - equal_range(const key_type& __key) const; + pair<const_iterator, const_iterator> + equal_range(const key_type& __key) const; - size_type erase(const key_type& __key); - void erase(const iterator& __it); - void erase(iterator __first, iterator __last); + size_type + erase(const key_type& __key); + + void + erase(const iterator& __it); - void erase(const const_iterator& __it); - void erase(const_iterator __first, const_iterator __last); + void + erase(iterator __first, iterator __last); - void resize(size_type __num_elements_hint); - void clear(); + void + erase(const const_iterator& __it); -private: - size_type _M_next_size(size_type __n) const - { return __stl_next_prime(__n); } + void + erase(const_iterator __first, const_iterator __last); - void _M_initialize_buckets(size_type __n) - { - 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; - } + void + resize(size_type __num_elements_hint); - size_type _M_bkt_num_key(const key_type& __key) const - { - return _M_bkt_num_key(__key, _M_buckets.size()); - } + void + clear(); - size_type _M_bkt_num(const value_type& __obj) const - { - return _M_bkt_num_key(_M_get_key(__obj)); - } + private: + size_type + _M_next_size(size_type __n) const + { return __stl_next_prime(__n); } - size_type _M_bkt_num_key(const key_type& __key, size_t __n) const - { - return _M_hash(__key) % __n; - } + void + _M_initialize_buckets(size_type __n) + { + 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 _M_bkt_num(const value_type& __obj, size_t __n) const - { - return _M_bkt_num_key(_M_get_key(__obj), __n); - } + size_type + _M_bkt_num_key(const key_type& __key) const + { return _M_bkt_num_key(__key, _M_buckets.size()); } - _Node* _M_new_node(const value_type& __obj) - { - _Node* __n = _M_get_node(); - __n->_M_next = 0; - try { - _Construct(&__n->_M_val, __obj); - return __n; - } - catch(...) + size_type + _M_bkt_num(const value_type& __obj) const + { return _M_bkt_num_key(_M_get_key(__obj)); } + + size_type + _M_bkt_num_key(const key_type& __key, size_t __n) const + { return _M_hash(__key) % __n; } + + size_type + _M_bkt_num(const value_type& __obj, size_t __n) const + { return _M_bkt_num_key(_M_get_key(__obj), __n); } + + _Node* + _M_new_node(const value_type& __obj) + { + _Node* __n = _M_get_node(); + __n->_M_next = 0; + try + { + this->get_allocator().construct(&__n->_M_val, __obj); + return __n; + } + catch(...) + { + _M_put_node(__n); + __throw_exception_again; + } + } + + void + _M_delete_node(_Node* __n) { + this->get_allocator().destroy(&__n->_M_val); _M_put_node(__n); - __throw_exception_again; } - } + + void + _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last); + + void + _M_erase_bucket(const size_type __n, _Node* __last); + + void + _M_copy_from(const hashtable& __ht); + }; + + template<class _Val, class _Key, class _HF, class _ExK, class _EqK, + class _All> + _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>& + _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>:: + operator++() + { + 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; + } - void _M_delete_node(_Node* __n) - { - _Destroy(&__n->_M_val); - _M_put_node(__n); - } + template<class _Val, class _Key, class _HF, class _ExK, class _EqK, + class _All> + inline _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All> + _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>:: + operator++(int) + { + iterator __tmp = *this; + ++*this; + return __tmp; + } - void _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last); - void _M_erase_bucket(const size_type __n, _Node* __last); + template<class _Val, class _Key, class _HF, class _ExK, class _EqK, + class _All> + _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>& + _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>:: + operator++() + { + 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; + } - void _M_copy_from(const hashtable& __ht); + template<class _Val, class _Key, class _HF, class _ExK, class _EqK, + class _All> + 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; + ++*this; + return __tmp; + } -}; + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + bool + operator==(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1, + const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2) + { + typedef typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_Node _Node; + + if (__ht1._M_buckets.size() != __ht2._M_buckets.size()) + return false; + + for (size_t __n = 0; __n < __ht1._M_buckets.size(); ++__n) + { + _Node* __cur1 = __ht1._M_buckets[__n]; + _Node* __cur2 = __ht2._M_buckets[__n]; + // Check same length of lists + for (; __cur1 && __cur2; + __cur1 = __cur1->_M_next, __cur2 = __cur2->_M_next) + { } + if (__cur1 || __cur2) + return false; + // Now check one's elements are in the other + for (__cur1 = __ht1._M_buckets[__n] ; __cur1; + __cur1 = __cur1->_M_next) + { + bool _found__cur1 = false; + for (__cur2 = __ht2._M_buckets[__n]; + __cur2; __cur2 = __cur2->_M_next) + { + if (__cur1->_M_val == __cur2->_M_val) + { + _found__cur1 = true; + break; + } + } + if (!_found__cur1) + return false; + } + } + return true; + } -template <class _Val, class _Key, class _HF, class _ExK, class _EqK, - class _All> -_Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>& -_Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++() -{ - 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 <class _Val, class _Key, class _HF, class _ExK, class _EqK, - class _All> -inline _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All> -_Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++(int) -{ - iterator __tmp = *this; - ++*this; - return __tmp; -} - -template <class _Val, class _Key, class _HF, class _ExK, class _EqK, - class _All> -_Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>& -_Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++() -{ - 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 <class _Val, class _Key, class _HF, class _ExK, class _EqK, - class _All> -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; - ++*this; - return __tmp; -} - -template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -bool operator==(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1, - const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2) -{ - typedef typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::_Node _Node; - if (__ht1._M_buckets.size() != __ht2._M_buckets.size()) - return false; - for (size_t __n = 0; __n < __ht1._M_buckets.size(); ++__n) { - _Node* __cur1 = __ht1._M_buckets[__n]; - _Node* __cur2 = __ht2._M_buckets[__n]; - // Check same length of lists - for ( ; __cur1 && __cur2; - __cur1 = __cur1->_M_next, __cur2 = __cur2->_M_next) - {} - if (__cur1 || __cur2) - return false; - // Now check one's elements are in the other - for (__cur1 = __ht1._M_buckets[__n] ; __cur1; __cur1 = __cur1->_M_next) + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + inline bool + operator!=(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1, + const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2) + { return !(__ht1 == __ht2); } + + template<class _Val, class _Key, class _HF, class _Extract, class _EqKey, + class _All> + inline void + swap(hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht1, + hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht2) + { __ht1.swap(__ht2); } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator, bool> + hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: + insert_unique_noresize(const value_type& __obj) { - bool _found__cur1 = false; - for (_Node* __cur2 = __ht2._M_buckets[__n]; - __cur2; __cur2 = __cur2->_M_next) - { - if (__cur1->_M_val == __cur2->_M_val) - { - _found__cur1 = true; - break; - } - } - if (!_found__cur1) - return false; + 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, bool>(iterator(__cur, this), false); + + _Node* __tmp = _M_new_node(__obj); + __tmp->_M_next = __first; + _M_buckets[__n] = __tmp; + ++_M_num_elements; + return pair<iterator, bool>(iterator(__tmp, this), true); } - } - return true; -} - -template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -inline bool operator!=(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1, - const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2) { - return !(__ht1 == __ht2); -} - -template <class _Val, class _Key, class _HF, class _Extract, class _EqKey, - class _All> -inline void swap(hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht1, - hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht2) { - __ht1.swap(__ht2); -} - - -template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -pair<typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator, bool> -hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> - ::insert_unique_noresize(const value_type& __obj) -{ - 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, bool>(iterator(__cur, this), false); - - _Node* __tmp = _M_new_node(__obj); - __tmp->_M_next = __first; - _M_buckets[__n] = __tmp; - ++_M_num_elements; - return pair<iterator, bool>(iterator(__tmp, this), true); -} - -template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -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 = _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))) { + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + 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 = _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 = _M_new_node(__obj); - __tmp->_M_next = __cur->_M_next; - __cur->_M_next = __tmp; + __tmp->_M_next = __first; + _M_buckets[__n] = __tmp; ++_M_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 <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::reference -hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::find_or_insert(const value_type& __obj) -{ - resize(_M_num_elements + 1); - - 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 __cur->_M_val; - - _Node* __tmp = _M_new_node(__obj); - __tmp->_M_next = __first; - _M_buckets[__n] = __tmp; - ++_M_num_elements; - return __tmp->_M_val; -} - -template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -pair<typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::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<iterator, iterator> _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()); + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::reference + hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: + find_or_insert(const value_type& __obj) + { + resize(_M_num_elements + 1); + + 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 __cur->_M_val; + + _Node* __tmp = _M_new_node(__obj); + __tmp->_M_next = __first; + _M_buckets[__n] = __tmp; + ++_M_num_elements; + return __tmp->_M_val; } - return _Pii(end(), end()); -} - -template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -pair<typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::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<const_iterator, const_iterator> _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()); + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::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<iterator, iterator> _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 <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -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 = _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->_M_next; - } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::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<const_iterator, const_iterator> _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()); } - if (_M_equals(_M_get_key(__first->_M_val), __key)) { - _M_buckets[__n] = __first->_M_next; - _M_delete_node(__first); - ++__erased; - --_M_num_elements; + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + 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 = _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->_M_next; + } + } + 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 <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const iterator& __it) -{ - _Node* __p = __it._M_cur; - if (__p) { - 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; + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: + erase(const iterator& __it) + { + _Node* __p = __it._M_cur; + if (__p) + { + 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->_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->_M_next; + } + } + } + } } - else { - _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->_M_next; - } - } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + void + hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: + erase(iterator __first, iterator __last) + { + 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._M_cur == __last._M_cur) + return; + else if (__f_bucket == __l_bucket) + _M_erase_bucket(__f_bucket, __first._M_cur, __last._M_cur); + else + { + _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 <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> - ::erase(iterator __first, iterator __last) -{ - 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._M_cur == __last._M_cur) - return; - else if (__f_bucket == __l_bucket) - _M_erase_bucket(__f_bucket, __first._M_cur, __last._M_cur); - else { - _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 <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -inline void -hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const_iterator __first, - const_iterator __last) -{ - erase(iterator(const_cast<_Node*>(__first._M_cur), - const_cast<hashtable*>(__first._M_ht)), - iterator(const_cast<_Node*>(__last._M_cur), - const_cast<hashtable*>(__last._M_ht))); -} - -template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -inline void -hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const const_iterator& __it) -{ - erase(iterator(const_cast<_Node*>(__it._M_cur), - const_cast<hashtable*>(__it._M_ht))); -} - -template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> - ::resize(size_type __num_elements_hint) -{ - 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_type __tmp(__n, (_Node*)(0), _M_buckets.get_allocator()); - try { - 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]; - } - } - _M_buckets.swap(__tmp); - } - catch(...) { - 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_exception_again; - } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + inline void + hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: + erase(const_iterator __first, const_iterator __last) + { + erase(iterator(const_cast<_Node*>(__first._M_cur), + const_cast<hashtable*>(__first._M_ht)), + iterator(const_cast<_Node*>(__last._M_cur), + const_cast<hashtable*>(__last._M_ht))); } - } -} - -template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> - ::_M_erase_bucket(const size_type __n, _Node* __first, _Node* __last) -{ - _Node* __cur = _M_buckets[__n]; - if (__cur == __first) - _M_erase_bucket(__n, __last); - else { - _Node* __next; - for (__next = __cur->_M_next; - __next != __first; - __cur = __next, __next = __cur->_M_next) - ; - while (__next != __last) { - __cur->_M_next = __next->_M_next; - _M_delete_node(__next); - __next = __cur->_M_next; - --_M_num_elements; + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + inline void + hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: + erase(const const_iterator& __it) + { erase(iterator(const_cast<_Node*>(__it._M_cur), + const_cast<hashtable*>(__it._M_ht))); } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + void + hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: + resize(size_type __num_elements_hint) + { + 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_type __tmp(__n, (_Node*)(0), _M_buckets.get_allocator()); + try + { + 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]; + } + } + _M_buckets.swap(__tmp); + } + catch(...) + { + 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_exception_again; + } + } + } } - } -} - -template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> - ::_M_erase_bucket(const size_type __n, _Node* __last) -{ - _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 <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::clear() -{ - 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; + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + void + hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: + _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last) + { + _Node* __cur = _M_buckets[__n]; + if (__cur == __first) + _M_erase_bucket(__n, __last); + else + { + _Node* __next; + for (__next = __cur->_M_next; + __next != __first; + __cur = __next, __next = __cur->_M_next) + ; + while (__next != __last) + { + __cur->_M_next = __next->_M_next; + _M_delete_node(__next); + __next = __cur->_M_next; + --_M_num_elements; + } + } } - _M_buckets[__i] = 0; - } - _M_num_elements = 0; -} - - -template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> - ::_M_copy_from(const hashtable& __ht) -{ - _M_buckets.clear(); - _M_buckets.reserve(__ht._M_buckets.size()); - _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*) 0); - try { - for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) { - const _Node* __cur = __ht._M_buckets[__i]; - if (__cur) { - _Node* __local_copy = _M_new_node(__cur->_M_val); - _M_buckets[__i] = __local_copy; - - for (_Node* __next = __cur->_M_next; - __next; - __cur = __next, __next = __cur->_M_next) { - __local_copy->_M_next = _M_new_node(__next->_M_val); - __local_copy = __local_copy->_M_next; - } - } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + void + hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: + _M_erase_bucket(const size_type __n, _Node* __last) + { + _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; + } } - _M_num_elements = __ht._M_num_elements; - } - catch(...) + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + void + hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: + clear() { - clear(); - __throw_exception_again; + 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; + } + _M_buckets[__i] = 0; + } + _M_num_elements = 0; } -} -} // namespace __gnu_cxx + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + void + hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: + _M_copy_from(const hashtable& __ht) + { + _M_buckets.clear(); + _M_buckets.reserve(__ht._M_buckets.size()); + _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*) 0); + try + { + for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) { + const _Node* __cur = __ht._M_buckets[__i]; + if (__cur) + { + _Node* __local_copy = _M_new_node(__cur->_M_val); + _M_buckets[__i] = __local_copy; + + for (_Node* __next = __cur->_M_next; + __next; + __cur = __next, __next = __cur->_M_next) + { + __local_copy->_M_next = _M_new_node(__next->_M_val); + __local_copy = __local_copy->_M_next; + } + } + } + _M_num_elements = __ht._M_num_elements; + } + catch(...) + { + clear(); + __throw_exception_again; + } + } + +_GLIBCXX_END_NAMESPACE #endif diff --git a/contrib/libstdc++/include/ext/iterator b/contrib/libstdc++/include/ext/iterator index 094313c76e47..b59e5ca34490 100644 --- a/contrib/libstdc++/include/ext/iterator +++ b/contrib/libstdc++/include/ext/iterator @@ -1,6 +1,6 @@ // HP/SGI iterator extensions -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2004, 2005 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -15,7 +15,7 @@ // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, // USA. // As a special exception, you may use this file as part of a free software @@ -55,8 +55,7 @@ /** @file ext/iterator * This file is a GNU extension to the Standard C++ Library (possibly - * containing extensions from the HP/SGI STL subset). You should only - * include this header if you are using GCC 3 or later. + * containing extensions from the HP/SGI STL subset). */ #ifndef _EXT_ITERATOR @@ -67,8 +66,8 @@ #include <bits/concept_check.h> #include <iterator> -namespace __gnu_cxx -{ +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + // There are two signatures for distance. In addition to the one // taking two iterators and returning a result, there is another // taking two iterators and a reference-to-result variable, and @@ -81,7 +80,11 @@ namespace __gnu_cxx { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) - while (__first != __last) { ++__first; ++__n; } + while (__first != __last) + { + ++__first; + ++__n; + } } template<typename _RandomAccessIterator, typename _Distance> @@ -90,7 +93,8 @@ namespace __gnu_cxx _Distance& __n, std::random_access_iterator_tag) { // concept requirements - __glibcxx_function_requires(_RandomAccessIteratorConcept<_RandomAccessIterator>) + __glibcxx_function_requires(_RandomAccessIteratorConcept< + _RandomAccessIterator>) __n += __last - __first; } @@ -107,7 +111,8 @@ namespace __gnu_cxx // concept requirements -- taken care of in __distance __distance(__first, __last, __n, std::__iterator_category(__first)); } -} // namespace __gnu_cxx + +_GLIBCXX_END_NAMESPACE #endif diff --git a/contrib/libstdc++/include/ext/malloc_allocator.h b/contrib/libstdc++/include/ext/malloc_allocator.h index 938380c36f6e..0f23e06c8e8a 100644 --- a/contrib/libstdc++/include/ext/malloc_allocator.h +++ b/contrib/libstdc++/include/ext/malloc_allocator.h @@ -1,6 +1,6 @@ // Allocator that wraps "C" malloc -*- C++ -*- -// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -15,7 +15,7 @@ // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, // USA. // As a special exception, you may use this file as part of a free software @@ -27,21 +27,28 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. +/** @file ext/malloc_allocator.h + * This file is a GNU extension to the Standard C++ Library. + */ + #ifndef _MALLOC_ALLOCATOR_H #define _MALLOC_ALLOCATOR_H 1 +#include <cstdlib> #include <new> +#include <bits/functexcept.h> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + using std::size_t; + using std::ptrdiff_t; -namespace __gnu_cxx -{ /** - * @brief An allocator that uses malloc + * @brief An allocator that uses malloc. * * This is precisely the allocator defined in the C++ Standard. * - all allocation calls malloc * - all deallocation calls free - * - * (See @link Allocators allocators info @endlink for more.) */ template<typename _Tp> class malloc_allocator @@ -79,9 +86,12 @@ namespace __gnu_cxx pointer allocate(size_type __n, const void* = 0) { + if (__builtin_expect(__n > this->max_size(), false)) + std::__throw_bad_alloc(); + pointer __ret = static_cast<_Tp*>(malloc(__n * sizeof(_Tp))); if (!__ret) - throw std::bad_alloc(); + std::__throw_bad_alloc(); return __ret; } @@ -113,6 +123,7 @@ namespace __gnu_cxx inline bool operator!=(const malloc_allocator<_Tp>&, const malloc_allocator<_Tp>&) { return false; } -} // namespace __gnu_cxx + +_GLIBCXX_END_NAMESPACE #endif diff --git a/contrib/libstdc++/include/ext/memory b/contrib/libstdc++/include/ext/memory index 1d93f90ac7ab..0755d897507f 100644 --- a/contrib/libstdc++/include/ext/memory +++ b/contrib/libstdc++/include/ext/memory @@ -1,6 +1,6 @@ // Memory extensions -*- C++ -*- -// Copyright (C) 2002 Free Software Foundation, Inc. +// Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -15,7 +15,7 @@ // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, // USA. // As a special exception, you may use this file as part of a free software @@ -55,8 +55,7 @@ /** @file ext/memory * This file is a GNU extension to the Standard C++ Library (possibly - * containing extensions from the HP/SGI STL subset). You should only - * include this header if you are using GCC 3 or later. + * containing extensions from the HP/SGI STL subset). */ #ifndef _EXT_MEMORY @@ -67,8 +66,8 @@ #include <memory> #include <bits/stl_tempbuf.h> -namespace __gnu_cxx -{ +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + using std::ptrdiff_t; using std::pair; using std::__iterator_category; @@ -82,7 +81,7 @@ namespace __gnu_cxx _ForwardIter __cur = __result; try { - for ( ; __count > 0 ; --__count, ++__first, ++__cur) + for (; __count > 0 ; --__count, ++__first, ++__cur) std::_Construct(&*__cur, *__first); return pair<_InputIter, _ForwardIter>(__first, __cur); } @@ -100,19 +99,16 @@ namespace __gnu_cxx std::random_access_iterator_tag) { _RandomAccessIter __last = __first + __count; - return pair<_RandomAccessIter, _ForwardIter>( - __last, - std::uninitialized_copy(__first, __last, __result)); + return (pair<_RandomAccessIter, _ForwardIter> + (__last, std::uninitialized_copy(__first, __last, __result))); } template<typename _InputIter, typename _Size, typename _ForwardIter> inline pair<_InputIter, _ForwardIter> __uninitialized_copy_n(_InputIter __first, _Size __count, _ForwardIter __result) - { - return __uninitialized_copy_n(__first, __count, __result, - __iterator_category(__first)); - } + { return __uninitialized_copy_n(__first, __count, __result, + __iterator_category(__first)); } /** * @brief Copies the range [first,last) into result. @@ -128,11 +124,42 @@ namespace __gnu_cxx inline pair<_InputIter, _ForwardIter> uninitialized_copy_n(_InputIter __first, _Size __count, _ForwardIter __result) + { return __uninitialized_copy_n(__first, __count, __result, + __iterator_category(__first)); } + + + // An alternative version of uninitialized_copy_n that constructs + // and destroys objects with a user-provided allocator. + template<typename _InputIter, typename _Size, typename _ForwardIter, + typename _Allocator> + pair<_InputIter, _ForwardIter> + __uninitialized_copy_n_a(_InputIter __first, _Size __count, + _ForwardIter __result, + _Allocator __alloc) { - return __uninitialized_copy_n(__first, __count, __result, - __iterator_category(__first)); + _ForwardIter __cur = __result; + try + { + for (; __count > 0 ; --__count, ++__first, ++__cur) + __alloc.construct(&*__cur, *__first); + return pair<_InputIter, _ForwardIter>(__first, __cur); + } + catch(...) + { + std::_Destroy(__result, __cur, __alloc); + __throw_exception_again; + } } + template<typename _InputIter, typename _Size, typename _ForwardIter, + typename _Tp> + inline pair<_InputIter, _ForwardIter> + __uninitialized_copy_n_a(_InputIter __first, _Size __count, + _ForwardIter __result, + std::allocator<_Tp>) + { + return uninitialized_copy_n(__first, __count, __result); + } /** * This class provides similar behavior and semantics of the standard @@ -155,17 +182,18 @@ namespace __gnu_cxx * @ingroup SGIextensions */ template <class _ForwardIterator, class _Tp - = typename std::iterator_traits<_ForwardIterator>::value_type > - struct temporary_buffer : public _Temporary_buffer<_ForwardIterator, _Tp> - { - /// Requests storage large enough to hold a copy of [first,last). - temporary_buffer(_ForwardIterator __first, _ForwardIterator __last) - : _Temporary_buffer<_ForwardIterator, _Tp>(__first, __last) { } - - /// Destroys objects and frees storage. - ~temporary_buffer() { } - }; -} // namespace __gnu_cxx + = typename std::iterator_traits<_ForwardIterator>::value_type > + struct temporary_buffer : public _Temporary_buffer<_ForwardIterator, _Tp> + { + /// Requests storage large enough to hold a copy of [first,last). + temporary_buffer(_ForwardIterator __first, _ForwardIterator __last) + : _Temporary_buffer<_ForwardIterator, _Tp>(__first, __last) { } + + /// Destroys objects and frees storage. + ~temporary_buffer() { } + }; + +_GLIBCXX_END_NAMESPACE #endif diff --git a/contrib/libstdc++/include/ext/mt_allocator.h b/contrib/libstdc++/include/ext/mt_allocator.h index f0ee2ebd26db..bc2d61f6eecd 100644 --- a/contrib/libstdc++/include/ext/mt_allocator.h +++ b/contrib/libstdc++/include/ext/mt_allocator.h @@ -1,6 +1,6 @@ // MT-optimized allocator -*- C++ -*- -// Copyright (C) 2003, 2004 Free Software Foundation, Inc. +// Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -15,7 +15,7 @@ // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, // USA. // As a special exception, you may use this file as part of a free software @@ -29,7 +29,6 @@ /** @file ext/mt_allocator.h * This file is a GNU extension to the Standard C++ Library. - * You should only include this header if you are using GCC 3 or later. */ #ifndef _MT_ALLOCATOR_H @@ -38,170 +37,231 @@ #include <new> #include <cstdlib> #include <bits/functexcept.h> -#include <bits/gthr.h> -#include <bits/atomicity.h> - -namespace __gnu_cxx -{ - /** - * This is a fixed size (power of 2) allocator which - when - * compiled with thread support - will maintain one freelist per - * size per thread plus a "global" one. Steps are taken to limit - * the per thread freelist sizes (by returning excess back to - * "global"). - * - * Further details: - * http://gcc.gnu.org/onlinedocs/libstdc++/ext/mt_allocator.html - */ - template<typename _Tp> - class __mt_alloc +#include <ext/atomicity.h> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + using std::size_t; + using std::ptrdiff_t; + + typedef void (*__destroy_handler)(void*); + + /// @brief Base class for pool object. + struct __pool_base + { + // Using short int as type for the binmap implies we are never + // caching blocks larger than 32768 with this allocator. + typedef unsigned short int _Binmap_type; + + // Variables used to configure the behavior of the allocator, + // assigned and explained in detail below. + struct _Tune + { + // Compile time constants for the default _Tune values. + enum { _S_align = 8 }; + enum { _S_max_bytes = 128 }; + enum { _S_min_bin = 8 }; + enum { _S_chunk_size = 4096 - 4 * sizeof(void*) }; + enum { _S_max_threads = 4096 }; + enum { _S_freelist_headroom = 10 }; + + // Alignment needed. + // NB: In any case must be >= sizeof(_Block_record), that + // is 4 on 32 bit machines and 8 on 64 bit machines. + size_t _M_align; + + // Allocation requests (after round-up to power of 2) below + // this value will be handled by the allocator. A raw new/ + // call will be used for requests larger than this value. + // NB: Must be much smaller than _M_chunk_size and in any + // case <= 32768. + size_t _M_max_bytes; + + // Size in bytes of the smallest bin. + // NB: Must be a power of 2 and >= _M_align (and of course + // much smaller than _M_max_bytes). + size_t _M_min_bin; + + // In order to avoid fragmenting and minimize the number of + // new() calls we always request new memory using this + // value. Based on previous discussions on the libstdc++ + // mailing list we have choosen the value below. + // See http://gcc.gnu.org/ml/libstdc++/2001-07/msg00077.html + // NB: At least one order of magnitude > _M_max_bytes. + size_t _M_chunk_size; + + // The maximum number of supported threads. For + // single-threaded operation, use one. Maximum values will + // vary depending on details of the underlying system. (For + // instance, Linux 2.4.18 reports 4070 in + // /proc/sys/kernel/threads-max, while Linux 2.6.6 reports + // 65534) + size_t _M_max_threads; + + // Each time a deallocation occurs in a threaded application + // we make sure that there are no more than + // _M_freelist_headroom % of used memory on the freelist. If + // the number of additional records is more than + // _M_freelist_headroom % of the freelist, we move these + // records back to the global pool. + size_t _M_freelist_headroom; + + // Set to true forces all allocations to use new(). + bool _M_force_new; + + explicit + _Tune() + : _M_align(_S_align), _M_max_bytes(_S_max_bytes), _M_min_bin(_S_min_bin), + _M_chunk_size(_S_chunk_size), _M_max_threads(_S_max_threads), + _M_freelist_headroom(_S_freelist_headroom), + _M_force_new(std::getenv("GLIBCXX_FORCE_NEW") ? true : false) + { } + + explicit + _Tune(size_t __align, size_t __maxb, size_t __minbin, size_t __chunk, + size_t __maxthreads, size_t __headroom, bool __force) + : _M_align(__align), _M_max_bytes(__maxb), _M_min_bin(__minbin), + _M_chunk_size(__chunk), _M_max_threads(__maxthreads), + _M_freelist_headroom(__headroom), _M_force_new(__force) + { } + }; + + struct _Block_address { - 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; + void* _M_initial; + _Block_address* _M_next; + }; + + const _Tune& + _M_get_options() const + { return _M_options; } - template<typename _Tp1> - struct rebind - { typedef __mt_alloc<_Tp1> other; }; + void + _M_set_options(_Tune __t) + { + if (!_M_init) + _M_options = __t; + } - __mt_alloc() throw() - { - // XXX - } + bool + _M_check_threshold(size_t __bytes) + { return __bytes > _M_options._M_max_bytes || _M_options._M_force_new; } - __mt_alloc(const __mt_alloc&) throw() - { - // XXX - } + size_t + _M_get_binmap(size_t __bytes) + { return _M_binmap[__bytes]; } - template<typename _Tp1> - __mt_alloc(const __mt_alloc<_Tp1>& obj) throw() - { - // XXX - } + const size_t + _M_get_align() + { return _M_options._M_align; } - ~__mt_alloc() throw() { } + explicit + __pool_base() + : _M_options(_Tune()), _M_binmap(NULL), _M_init(false) { } - pointer - address(reference __x) const - { return &__x; } + explicit + __pool_base(const _Tune& __options) + : _M_options(__options), _M_binmap(NULL), _M_init(false) { } - const_pointer - address(const_reference __x) const - { return &__x; } + private: + explicit + __pool_base(const __pool_base&); - size_type - max_size() const throw() - { return size_t(-1) / sizeof(_Tp); } + __pool_base& + operator=(const __pool_base&); - // _GLIBCXX_RESOLVE_LIB_DEFECTS - // 402. wrong new expression in [some_] allocator::construct - void - construct(pointer __p, const _Tp& __val) - { ::new(__p) _Tp(__val); } + protected: + // Configuration options. + _Tune _M_options; + + _Binmap_type* _M_binmap; - void - destroy(pointer __p) { __p->~_Tp(); } + // Configuration of the pool object via _M_options can happen + // after construction but before initialization. After + // initialization is complete, this variable is set to true. + bool _M_init; + }; - pointer - allocate(size_type __n, const void* = 0); - void - deallocate(pointer __p, size_type __n); + /** + * @brief Data describing the underlying memory pool, parameterized on + * threading support. + */ + template<bool _Thread> + class __pool; - // Variables used to configure the behavior of the allocator, - // assigned and explained in detail below. - struct _Tune + /// Specialization for single thread. + template<> + class __pool<false> : public __pool_base + { + public: + union _Block_record { - // Alignment needed. - // NB: In any case must be >= sizeof(_Block_record), that - // is 4 on 32 bit machines and 8 on 64 bit machines. - size_t _M_align; - - // Allocation requests (after round-up to power of 2) below - // this value will be handled by the allocator. A raw new/ - // call will be used for requests larger than this value. - size_t _M_max_bytes; - - // Size in bytes of the smallest bin. - // NB: Must be a power of 2 and >= _M_align. - size_t _M_min_bin; - - // In order to avoid fragmenting and minimize the number of - // new() calls we always request new memory using this - // value. Based on previous discussions on the libstdc++ - // mailing list we have choosen the value below. - // See http://gcc.gnu.org/ml/libstdc++/2001-07/msg00077.html - size_t _M_chunk_size; - - // The maximum number of supported threads. Our Linux 2.4.18 - // reports 4070 in /proc/sys/kernel/threads-max - size_t _M_max_threads; - - // Each time a deallocation occurs in a threaded application - // we make sure that there are no more than - // _M_freelist_headroom % of used memory on the freelist. If - // the number of additional records is more than - // _M_freelist_headroom % of the freelist, we move these - // records back to the global pool. - size_t _M_freelist_headroom; - - // Set to true forces all allocations to use new(). - bool _M_force_new; - - explicit - _Tune() - : _M_align(8), _M_max_bytes(128), _M_min_bin(8), - _M_chunk_size(4096 - 4 * sizeof(void*)), - _M_max_threads(4096), _M_freelist_headroom(10), - _M_force_new(getenv("GLIBCXX_FORCE_NEW") ? true : false) - { } - - explicit - _Tune(size_t __align, size_t __maxb, size_t __minbin, - size_t __chunk, size_t __maxthreads, size_t __headroom, - bool __force) - : _M_align(__align), _M_max_bytes(__maxb), _M_min_bin(__minbin), - _M_chunk_size(__chunk), _M_max_threads(__maxthreads), - _M_freelist_headroom(__headroom), _M_force_new(__force) - { } + // Points to the block_record of the next free block. + _Block_record* _M_next; }; - private: - // We need to create the initial lists and set up some variables - // before we can answer to the first request for memory. -#ifdef __GTHREADS - static __gthread_once_t _S_once; -#endif - static bool _S_init; + struct _Bin_record + { + // An "array" of pointers to the first free block. + _Block_record** _M_first; - static void - _S_initialize(); + // A list of the initial addresses of all allocated blocks. + _Block_address* _M_address; + }; + + void + _M_initialize_once() + { + if (__builtin_expect(_M_init == false, false)) + _M_initialize(); + } - // Configuration options. - static _Tune _S_options; + void + _M_destroy() throw(); - static const _Tune - _S_get_options() - { return _S_options; } + char* + _M_reserve_block(size_t __bytes, const size_t __thread_id); + + void + _M_reclaim_block(char* __p, size_t __bytes); + + size_t + _M_get_thread_id() { return 0; } + + const _Bin_record& + _M_get_bin(size_t __which) + { return _M_bin[__which]; } + + void + _M_adjust_freelist(const _Bin_record&, _Block_record*, size_t) + { } - static void - _S_set_options(_Tune __t) - { - if (!_S_init) - _S_options = __t; - } + explicit __pool() + : _M_bin(NULL), _M_bin_size(1) { } + + explicit __pool(const __pool_base::_Tune& __tune) + : __pool_base(__tune), _M_bin(NULL), _M_bin_size(1) { } - // Using short int as type for the binmap implies we are never - // caching blocks larger than 65535 with this allocator - typedef unsigned short int _Binmap_type; - static _Binmap_type* _S_binmap; + private: + // An "array" of bin_records each of which represents a specific + // power of 2 size. Memory to this "array" is allocated in + // _M_initialize(). + _Bin_record* _M_bin; + + // Actual value calculated in _M_initialize(). + size_t _M_bin_size; + void + _M_initialize(); + }; + +#ifdef __GTHREADS + /// Specialization for thread enabled, via gthreads.h. + template<> + class __pool<true> : public __pool_base + { + public: // Each requesting thread is assigned an id ranging from 1 to // _S_max_threads. Thread id 0 is used as a global memory pool. // In order to get constant performance on the thread assignment @@ -211,508 +271,476 @@ namespace __gnu_cxx // __gthread_key we specify a destructor. When this destructor // (i.e. the thread dies) is called, we return the thread id to // the front of this list. -#ifdef __GTHREADS struct _Thread_record { - // Points to next free thread id record. NULL if last record in list. - _Thread_record* volatile _M_next; - + // Points to next free thread id record. NULL if last record in list. + _Thread_record* _M_next; + // Thread id ranging from 1 to _S_max_threads. - size_t _M_id; + size_t _M_id; }; - - static _Thread_record* volatile _S_thread_freelist_first; - static __gthread_mutex_t _S_thread_freelist_mutex; - static __gthread_key_t _S_thread_key; - - static void - _S_destroy_thread_key(void* __freelist_pos); -#endif - - static size_t - _S_get_thread_id(); - + union _Block_record { // Points to the block_record of the next free block. - _Block_record* volatile _M_next; - -#ifdef __GTHREADS + _Block_record* _M_next; + // The thread id of the thread which has requested this block. - size_t _M_thread_id; -#endif + size_t _M_thread_id; }; - + struct _Bin_record { // An "array" of pointers to the first free block for each - // thread id. Memory to this "array" is allocated in _S_initialize() - // for _S_max_threads + global pool 0. - _Block_record** volatile _M_first; + // thread id. Memory to this "array" is allocated in + // _S_initialize() for _S_max_threads + global pool 0. + _Block_record** _M_first; + + // A list of the initial addresses of all allocated blocks. + _Block_address* _M_address; -#ifdef __GTHREADS // An "array" of counters used to keep track of the amount of // blocks that are on the freelist/used for each thread id. - // Memory to these "arrays" is allocated in _S_initialize() for - // _S_max_threads + global pool 0. - size_t* volatile _M_free; - size_t* volatile _M_used; - + // - Note that the second part of the allocated _M_used "array" + // actually hosts (atomic) counters of reclaimed blocks: in + // _M_reserve_block and in _M_reclaim_block those numbers are + // subtracted from the first ones to obtain the actual size + // of the "working set" of the given thread. + // - Memory to these "arrays" is allocated in _S_initialize() + // for _S_max_threads + global pool 0. + size_t* _M_free; + size_t* _M_used; + // Each bin has its own mutex which is used to ensure data // integrity while changing "ownership" on a block. The mutex // is initialized in _S_initialize(). - __gthread_mutex_t* _M_mutex; -#endif + __gthread_mutex_t* _M_mutex; }; + + // XXX GLIBCXX_ABI Deprecated + void + _M_initialize(__destroy_handler); + void + _M_initialize_once() + { + if (__builtin_expect(_M_init == false, false)) + _M_initialize(); + } + + void + _M_destroy() throw(); + + char* + _M_reserve_block(size_t __bytes, const size_t __thread_id); + + void + _M_reclaim_block(char* __p, size_t __bytes); + + const _Bin_record& + _M_get_bin(size_t __which) + { return _M_bin[__which]; } + + void + _M_adjust_freelist(const _Bin_record& __bin, _Block_record* __block, + size_t __thread_id) + { + if (__gthread_active_p()) + { + __block->_M_thread_id = __thread_id; + --__bin._M_free[__thread_id]; + ++__bin._M_used[__thread_id]; + } + } + + // XXX GLIBCXX_ABI Deprecated + void + _M_destroy_thread_key(void*); + + size_t + _M_get_thread_id(); + + explicit __pool() + : _M_bin(NULL), _M_bin_size(1), _M_thread_freelist(NULL) + { } + + explicit __pool(const __pool_base::_Tune& __tune) + : __pool_base(__tune), _M_bin(NULL), _M_bin_size(1), + _M_thread_freelist(NULL) + { } + + private: // An "array" of bin_records each of which represents a specific // power of 2 size. Memory to this "array" is allocated in - // _S_initialize(). - static _Bin_record* volatile _S_bin; + // _M_initialize(). + _Bin_record* _M_bin; + + // Actual value calculated in _M_initialize(). + size_t _M_bin_size; - // Actual value calculated in _S_initialize(). - static size_t _S_bin_size; + _Thread_record* _M_thread_freelist; + void* _M_thread_freelist_initial; + + void + _M_initialize(); }; +#endif - template<typename _Tp> - typename __mt_alloc<_Tp>::pointer - __mt_alloc<_Tp>:: - allocate(size_type __n, const void*) + template<template <bool> class _PoolTp, bool _Thread> + struct __common_pool { - // Although the test in __gthread_once() would suffice, we wrap - // test of the once condition in our own unlocked check. This - // saves one function call to pthread_once() (which itself only - // tests for the once value unlocked anyway and immediately - // returns if set) - if (!_S_init) - { + typedef _PoolTp<_Thread> pool_type; + + static pool_type& + _S_get_pool() + { + static pool_type _S_pool; + return _S_pool; + } + }; + + template<template <bool> class _PoolTp, bool _Thread> + struct __common_pool_base; + + template<template <bool> class _PoolTp> + struct __common_pool_base<_PoolTp, false> + : public __common_pool<_PoolTp, false> + { + using __common_pool<_PoolTp, false>::_S_get_pool; + + static void + _S_initialize_once() + { + static bool __init; + if (__builtin_expect(__init == false, false)) + { + _S_get_pool()._M_initialize_once(); + __init = true; + } + } + }; + #ifdef __GTHREADS - if (__gthread_active_p()) - __gthread_once(&_S_once, _S_initialize); -#endif - if (!_S_init) - _S_initialize(); - } + template<template <bool> class _PoolTp> + struct __common_pool_base<_PoolTp, true> + : public __common_pool<_PoolTp, true> + { + using __common_pool<_PoolTp, true>::_S_get_pool; - // Requests larger than _M_max_bytes are handled by new/delete - // directly. - const size_t __bytes = __n * sizeof(_Tp); - if (__bytes > _S_options._M_max_bytes || _S_options._M_force_new) - { - void* __ret = ::operator new(__bytes); - return static_cast<_Tp*>(__ret); - } + static void + _S_initialize() + { _S_get_pool()._M_initialize_once(); } - // Round up to power of 2 and figure out which bin to use. - const size_t __which = _S_binmap[__bytes]; - const size_t __thread_id = _S_get_thread_id(); + static void + _S_initialize_once() + { + static bool __init; + if (__builtin_expect(__init == false, false)) + { + if (__gthread_active_p()) + { + // On some platforms, __gthread_once_t is an aggregate. + static __gthread_once_t __once = __GTHREAD_ONCE_INIT; + __gthread_once(&__once, _S_initialize); + } + + // Double check initialization. May be necessary on some + // systems for proper construction when not compiling with + // thread flags. + _S_get_pool()._M_initialize_once(); + __init = true; + } + } + }; +#endif + + /// @brief Policy for shared __pool objects. + template<template <bool> class _PoolTp, bool _Thread> + struct __common_pool_policy : public __common_pool_base<_PoolTp, _Thread> + { + template<typename _Tp1, template <bool> class _PoolTp1 = _PoolTp, + bool _Thread1 = _Thread> + struct _M_rebind + { typedef __common_pool_policy<_PoolTp1, _Thread1> other; }; + + using __common_pool_base<_PoolTp, _Thread>::_S_get_pool; + using __common_pool_base<_PoolTp, _Thread>::_S_initialize_once; + }; + + + template<typename _Tp, template <bool> class _PoolTp, bool _Thread> + struct __per_type_pool + { + typedef _Tp value_type; + typedef _PoolTp<_Thread> pool_type; - // Find out if we have blocks on our freelist. If so, go ahead - // and use them directly without having to lock anything. - const _Bin_record& __bin = _S_bin[__which]; - _Block_record* __block = NULL; - if (__bin._M_first[__thread_id] == NULL) - { - // NB: For alignment reasons, we can't use the first _M_align - // bytes, even when sizeof(_Block_record) < _M_align. - const size_t __bin_size = ((_S_options._M_min_bin << __which) - + _S_options._M_align); - size_t __block_count = _S_options._M_chunk_size / __bin_size; - - // Are we using threads? - // - Yes, check if there are free blocks on the global - // list. If so, grab up to __block_count blocks in one - // lock and change ownership. If the global list is - // empty, we allocate a new chunk and add those blocks - // directly to our own freelist (with us as owner). - // - No, all operations are made directly to global pool 0 - // no need to lock or change ownership but check for free - // blocks on global list (and if not add new ones) and - // get the first one. -#ifdef __GTHREADS - if (__gthread_active_p()) - { - __gthread_mutex_lock(__bin._M_mutex); - if (__bin._M_first[0] == NULL) - { - // No need to hold the lock when we are adding a - // whole chunk to our own list. - __gthread_mutex_unlock(__bin._M_mutex); - - void* __v = ::operator new(_S_options._M_chunk_size); - __bin._M_first[__thread_id] = static_cast<_Block_record*>(__v); - __bin._M_free[__thread_id] = __block_count; - - --__block_count; - __block = __bin._M_first[__thread_id]; - while (__block_count-- > 0) - { - char* __c = reinterpret_cast<char*>(__block) + __bin_size; - __block->_M_next = reinterpret_cast<_Block_record*>(__c); - __block = __block->_M_next; - } - __block->_M_next = NULL; - } - else - { - // Is the number of required blocks greater than or - // equal to the number that can be provided by the - // global free list? - __bin._M_first[__thread_id] = __bin._M_first[0]; - if (__block_count >= __bin._M_free[0]) - { - __bin._M_free[__thread_id] = __bin._M_free[0]; - __bin._M_free[0] = 0; - __bin._M_first[0] = NULL; - } - else - { - __bin._M_free[__thread_id] = __block_count; - __bin._M_free[0] -= __block_count; - --__block_count; - __block = __bin._M_first[0]; - while (__block_count-- > 0) - __block = __block->_M_next; - __bin._M_first[0] = __block->_M_next; - __block->_M_next = NULL; - } - __gthread_mutex_unlock(__bin._M_mutex); - } - } - else + static pool_type& + _S_get_pool() + { + // Sane defaults for the _PoolTp. + typedef typename pool_type::_Block_record _Block_record; + const static size_t __a = (__alignof__(_Tp) >= sizeof(_Block_record) + ? __alignof__(_Tp) : sizeof(_Block_record)); + + typedef typename __pool_base::_Tune _Tune; + static _Tune _S_tune(__a, sizeof(_Tp) * 64, + sizeof(_Tp) * 2 >= __a ? sizeof(_Tp) * 2 : __a, + sizeof(_Tp) * size_t(_Tune::_S_chunk_size), + _Tune::_S_max_threads, + _Tune::_S_freelist_headroom, + std::getenv("GLIBCXX_FORCE_NEW") ? true : false); + static pool_type _S_pool(_S_tune); + return _S_pool; + } + }; + + template<typename _Tp, template <bool> class _PoolTp, bool _Thread> + struct __per_type_pool_base; + + template<typename _Tp, template <bool> class _PoolTp> + struct __per_type_pool_base<_Tp, _PoolTp, false> + : public __per_type_pool<_Tp, _PoolTp, false> + { + using __per_type_pool<_Tp, _PoolTp, false>::_S_get_pool; + + static void + _S_initialize_once() + { + static bool __init; + if (__builtin_expect(__init == false, false)) + { + _S_get_pool()._M_initialize_once(); + __init = true; + } + } + }; + + #ifdef __GTHREADS + template<typename _Tp, template <bool> class _PoolTp> + struct __per_type_pool_base<_Tp, _PoolTp, true> + : public __per_type_pool<_Tp, _PoolTp, true> + { + using __per_type_pool<_Tp, _PoolTp, true>::_S_get_pool; + + static void + _S_initialize() + { _S_get_pool()._M_initialize_once(); } + + static void + _S_initialize_once() + { + static bool __init; + if (__builtin_expect(__init == false, false)) + { + if (__gthread_active_p()) + { + // On some platforms, __gthread_once_t is an aggregate. + static __gthread_once_t __once = __GTHREAD_ONCE_INIT; + __gthread_once(&__once, _S_initialize); + } + + // Double check initialization. May be necessary on some + // systems for proper construction when not compiling with + // thread flags. + _S_get_pool()._M_initialize_once(); + __init = true; + } + } + }; #endif - { - void* __v = ::operator new(_S_options._M_chunk_size); - __bin._M_first[0] = static_cast<_Block_record*>(__v); - - --__block_count; - __block = __bin._M_first[0]; - while (__block_count-- > 0) - { - char* __c = reinterpret_cast<char*>(__block) + __bin_size; - __block->_M_next = reinterpret_cast<_Block_record*>(__c); - __block = __block->_M_next; - } - __block->_M_next = NULL; - } - } - __block = __bin._M_first[__thread_id]; - __bin._M_first[__thread_id] = __bin._M_first[__thread_id]->_M_next; + /// @brief Policy for individual __pool objects. + template<typename _Tp, template <bool> class _PoolTp, bool _Thread> + struct __per_type_pool_policy + : public __per_type_pool_base<_Tp, _PoolTp, _Thread> + { + template<typename _Tp1, template <bool> class _PoolTp1 = _PoolTp, + bool _Thread1 = _Thread> + struct _M_rebind + { typedef __per_type_pool_policy<_Tp1, _PoolTp1, _Thread1> other; }; + + using __per_type_pool_base<_Tp, _PoolTp, _Thread>::_S_get_pool; + using __per_type_pool_base<_Tp, _PoolTp, _Thread>::_S_initialize_once; + }; + + + /// @brief Base class for _Tp dependent member functions. + template<typename _Tp> + class __mt_alloc_base + { + 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; + + pointer + address(reference __x) const + { return &__x; } + + const_pointer + address(const_reference __x) const + { return &__x; } + + size_type + max_size() const throw() + { return size_t(-1) / sizeof(_Tp); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 402. wrong new expression in [some_] allocator::construct + void + construct(pointer __p, const _Tp& __val) + { ::new(__p) _Tp(__val); } + + void + destroy(pointer __p) { __p->~_Tp(); } + }; + #ifdef __GTHREADS - if (__gthread_active_p()) - { - __block->_M_thread_id = __thread_id; - --__bin._M_free[__thread_id]; - ++__bin._M_used[__thread_id]; - } +#define __thread_default true +#else +#define __thread_default false #endif - char* __c = reinterpret_cast<char*>(__block) + _S_options._M_align; - return static_cast<_Tp*>(static_cast<void*>(__c)); - } - - template<typename _Tp> - void - __mt_alloc<_Tp>:: - deallocate(pointer __p, size_type __n) + /** + * @brief This is a fixed size (power of 2) allocator which - when + * compiled with thread support - will maintain one freelist per + * size per thread plus a "global" one. Steps are taken to limit + * the per thread freelist sizes (by returning excess back to + * the "global" list). + * + * Further details: + * http://gcc.gnu.org/onlinedocs/libstdc++/ext/mt_allocator.html + */ + template<typename _Tp, + typename _Poolp = __common_pool_policy<__pool, __thread_default> > + class __mt_alloc : public __mt_alloc_base<_Tp> + { + 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; + typedef _Poolp __policy_type; + typedef typename _Poolp::pool_type __pool_type; + + template<typename _Tp1, typename _Poolp1 = _Poolp> + struct rebind + { + typedef typename _Poolp1::template _M_rebind<_Tp1>::other pol_type; + typedef __mt_alloc<_Tp1, pol_type> other; + }; + + __mt_alloc() throw() { } + + __mt_alloc(const __mt_alloc&) throw() { } + + template<typename _Tp1, typename _Poolp1> + __mt_alloc(const __mt_alloc<_Tp1, _Poolp1>&) throw() { } + + ~__mt_alloc() throw() { } + + pointer + allocate(size_type __n, const void* = 0); + + void + deallocate(pointer __p, size_type __n); + + const __pool_base::_Tune + _M_get_options() + { + // Return a copy, not a reference, for external consumption. + return __policy_type::_S_get_pool()._M_get_options(); + } + + void + _M_set_options(__pool_base::_Tune __t) + { __policy_type::_S_get_pool()._M_set_options(__t); } + }; + + template<typename _Tp, typename _Poolp> + typename __mt_alloc<_Tp, _Poolp>::pointer + __mt_alloc<_Tp, _Poolp>:: + allocate(size_type __n, const void*) { - // Requests larger than _M_max_bytes are handled by operators + if (__builtin_expect(__n > this->max_size(), false)) + std::__throw_bad_alloc(); + + __policy_type::_S_initialize_once(); + + // Requests larger than _M_max_bytes are handled by operator // new/delete directly. + __pool_type& __pool = __policy_type::_S_get_pool(); const size_t __bytes = __n * sizeof(_Tp); - if (__bytes > _S_options._M_max_bytes || _S_options._M_force_new) + if (__pool._M_check_threshold(__bytes)) { - ::operator delete(__p); - return; + void* __ret = ::operator new(__bytes); + return static_cast<_Tp*>(__ret); } // Round up to power of 2 and figure out which bin to use. - const size_t __which = _S_binmap[__bytes]; - const _Bin_record& __bin = _S_bin[__which]; - - char* __c = reinterpret_cast<char*>(__p) - _S_options._M_align; - _Block_record* __block = reinterpret_cast<_Block_record*>(__c); + const size_t __which = __pool._M_get_binmap(__bytes); + const size_t __thread_id = __pool._M_get_thread_id(); -#ifdef __GTHREADS - if (__gthread_active_p()) + // Find out if we have blocks on our freelist. If so, go ahead + // and use them directly without having to lock anything. + char* __c; + typedef typename __pool_type::_Bin_record _Bin_record; + const _Bin_record& __bin = __pool._M_get_bin(__which); + if (__bin._M_first[__thread_id]) { - // Calculate the number of records to remove from our freelist: - // in order to avoid too much contention we wait until the - // number of records is "high enough". - const size_t __thread_id = _S_get_thread_id(); - - long __remove = ((__bin._M_free[__thread_id] - * _S_options._M_freelist_headroom) - - __bin._M_used[__thread_id]); - if (__remove > static_cast<long>(100 * (_S_bin_size - __which) - * _S_options._M_freelist_headroom) - && __remove > static_cast<long>(__bin._M_free[__thread_id])) - { - _Block_record* __tmp = __bin._M_first[__thread_id]; - _Block_record* __first = __tmp; - __remove /= _S_options._M_freelist_headroom; - const long __removed = __remove; - --__remove; - while (__remove-- > 0) - __tmp = __tmp->_M_next; - __bin._M_first[__thread_id] = __tmp->_M_next; - __bin._M_free[__thread_id] -= __removed; - - __gthread_mutex_lock(__bin._M_mutex); - __tmp->_M_next = __bin._M_first[0]; - __bin._M_first[0] = __first; - __bin._M_free[0] += __removed; - __gthread_mutex_unlock(__bin._M_mutex); - } + // Already reserved. + typedef typename __pool_type::_Block_record _Block_record; + _Block_record* __block = __bin._M_first[__thread_id]; + __bin._M_first[__thread_id] = __block->_M_next; - // Return this block to our list and update counters and - // owner id as needed. - --__bin._M_used[__block->_M_thread_id]; - - __block->_M_next = __bin._M_first[__thread_id]; - __bin._M_first[__thread_id] = __block; - - ++__bin._M_free[__thread_id]; + __pool._M_adjust_freelist(__bin, __block, __thread_id); + __c = reinterpret_cast<char*>(__block) + __pool._M_get_align(); } else -#endif { - // Single threaded application - return to global pool. - __block->_M_next = __bin._M_first[0]; - __bin._M_first[0] = __block; + // Null, reserve. + __c = __pool._M_reserve_block(__bytes, __thread_id); } + return static_cast<_Tp*>(static_cast<void*>(__c)); } - template<typename _Tp> + template<typename _Tp, typename _Poolp> void - __mt_alloc<_Tp>:: - _S_initialize() + __mt_alloc<_Tp, _Poolp>:: + deallocate(pointer __p, size_type __n) { - // This method is called on the first allocation (when _S_init is still - // false) to create the bins. - - // Ensure that the static initialization of _S_options has - // happened. This depends on (a) _M_align == 0 being an invalid - // value that is only present at startup, and (b) the real - // static initialization that happens later not actually - // changing anything. - if (_S_options._M_align == 0) - new (&_S_options) _Tune; - - // _M_force_new must not change after the first allocate(), - // which in turn calls this method, so if it's false, it's false - // forever and we don't need to return here ever again. - if (_S_options._M_force_new) - { - _S_init = true; - return; - } - - // Calculate the number of bins required based on _M_max_bytes. - // _S_bin_size is statically-initialized to one. - size_t __bin_size = _S_options._M_min_bin; - while (_S_options._M_max_bytes > __bin_size) + if (__builtin_expect(__p != 0, true)) { - __bin_size <<= 1; - ++_S_bin_size; - } - - // Setup the bin map for quick lookup of the relevant bin. - const size_t __j = (_S_options._M_max_bytes + 1) * sizeof(_Binmap_type); - _S_binmap = static_cast<_Binmap_type*>(::operator new(__j)); - - _Binmap_type* __bp = _S_binmap; - _Binmap_type __bin_max = _S_options._M_min_bin; - _Binmap_type __bint = 0; - for (_Binmap_type __ct = 0; __ct <= _S_options._M_max_bytes; ++__ct) - { - if (__ct > __bin_max) - { - __bin_max <<= 1; - ++__bint; - } - *__bp++ = __bint; - } - - // Initialize _S_bin and its members. - void* __v = ::operator new(sizeof(_Bin_record) * _S_bin_size); - _S_bin = static_cast<_Bin_record*>(__v); - - // If __gthread_active_p() create and initialize the list of - // free thread ids. Single threaded applications use thread id 0 - // directly and have no need for this. -#ifdef __GTHREADS - if (__gthread_active_p()) - { - const size_t __k = sizeof(_Thread_record) * _S_options._M_max_threads; - __v = ::operator new(__k); - _S_thread_freelist_first = static_cast<_Thread_record*>(__v); - - // NOTE! The first assignable thread id is 1 since the - // global pool uses id 0 - size_t __i; - for (__i = 1; __i < _S_options._M_max_threads; ++__i) - { - _Thread_record& __tr = _S_thread_freelist_first[__i - 1]; - __tr._M_next = &_S_thread_freelist_first[__i]; - __tr._M_id = __i; - } - - // Set last record. - _S_thread_freelist_first[__i - 1]._M_next = NULL; - _S_thread_freelist_first[__i - 1]._M_id = __i; - - // Make sure this is initialized. -#ifndef __GTHREAD_MUTEX_INIT - __GTHREAD_MUTEX_INIT_FUNCTION(&_S_thread_freelist_mutex); -#endif - // Initialize per thread key to hold pointer to - // _S_thread_freelist. - __gthread_key_create(&_S_thread_key, _S_destroy_thread_key); - - const size_t __max_threads = _S_options._M_max_threads + 1; - for (size_t __n = 0; __n < _S_bin_size; ++__n) - { - _Bin_record& __bin = _S_bin[__n]; - __v = ::operator new(sizeof(_Block_record*) * __max_threads); - __bin._M_first = static_cast<_Block_record**>(__v); - - __v = ::operator new(sizeof(size_t) * __max_threads); - __bin._M_free = static_cast<size_t*>(__v); - - __v = ::operator new(sizeof(size_t) * __max_threads); - __bin._M_used = static_cast<size_t*>(__v); - - __v = ::operator new(sizeof(__gthread_mutex_t)); - __bin._M_mutex = static_cast<__gthread_mutex_t*>(__v); - -#ifdef __GTHREAD_MUTEX_INIT - { - // Do not copy a POSIX/gthr mutex once in use. - __gthread_mutex_t __tmp = __GTHREAD_MUTEX_INIT; - *__bin._M_mutex = __tmp; - } -#else - { __GTHREAD_MUTEX_INIT_FUNCTION(__bin._M_mutex); } -#endif - - for (size_t __threadn = 0; __threadn < __max_threads; - ++__threadn) - { - __bin._M_first[__threadn] = NULL; - __bin._M_free[__threadn] = 0; - __bin._M_used[__threadn] = 0; - } - } + // Requests larger than _M_max_bytes are handled by + // operators new/delete directly. + __pool_type& __pool = __policy_type::_S_get_pool(); + const size_t __bytes = __n * sizeof(_Tp); + if (__pool._M_check_threshold(__bytes)) + ::operator delete(__p); + else + __pool._M_reclaim_block(reinterpret_cast<char*>(__p), __bytes); } - else -#endif - for (size_t __n = 0; __n < _S_bin_size; ++__n) - { - _Bin_record& __bin = _S_bin[__n]; - __v = ::operator new(sizeof(_Block_record*)); - __bin._M_first = static_cast<_Block_record**>(__v); - __bin._M_first[0] = NULL; - } - - _S_init = true; - } - - template<typename _Tp> - size_t - __mt_alloc<_Tp>:: - _S_get_thread_id() - { -#ifdef __GTHREADS - // If we have thread support and it's active we check the thread - // key value and return its id or if it's not set we take the - // first record from _S_thread_freelist and sets the key and - // returns it's id. - if (__gthread_active_p()) - { - _Thread_record* __freelist_pos = - static_cast<_Thread_record*>(__gthread_getspecific(_S_thread_key)); - if (__freelist_pos == NULL) - { - // Since _S_options._M_max_threads must be larger than - // the theoretical max number of threads of the OS the - // list can never be empty. - __gthread_mutex_lock(&_S_thread_freelist_mutex); - __freelist_pos = _S_thread_freelist_first; - _S_thread_freelist_first = _S_thread_freelist_first->_M_next; - __gthread_mutex_unlock(&_S_thread_freelist_mutex); - - __gthread_setspecific(_S_thread_key, - static_cast<void*>(__freelist_pos)); - } - return __freelist_pos->_M_id; - } -#endif - // Otherwise (no thread support or inactive) all requests are - // served from the global pool 0. - return 0; } - -#ifdef __GTHREADS - template<typename _Tp> - void - __mt_alloc<_Tp>:: - _S_destroy_thread_key(void* __freelist_pos) - { - // Return this thread id record to front of thread_freelist. - __gthread_mutex_lock(&_S_thread_freelist_mutex); - _Thread_record* __tr = static_cast<_Thread_record*>(__freelist_pos); - __tr->_M_next = _S_thread_freelist_first; - _S_thread_freelist_first = __tr; - __gthread_mutex_unlock(&_S_thread_freelist_mutex); - } -#endif - - template<typename _Tp> + + template<typename _Tp, typename _Poolp> inline bool - operator==(const __mt_alloc<_Tp>&, const __mt_alloc<_Tp>&) + operator==(const __mt_alloc<_Tp, _Poolp>&, const __mt_alloc<_Tp, _Poolp>&) { return true; } - template<typename _Tp> + template<typename _Tp, typename _Poolp> inline bool - operator!=(const __mt_alloc<_Tp>&, const __mt_alloc<_Tp>&) + operator!=(const __mt_alloc<_Tp, _Poolp>&, const __mt_alloc<_Tp, _Poolp>&) { return false; } - template<typename _Tp> - bool __mt_alloc<_Tp>::_S_init = false; - - template<typename _Tp> - typename __mt_alloc<_Tp>::_Tune __mt_alloc<_Tp>::_S_options; +#undef __thread_default - template<typename _Tp> - typename __mt_alloc<_Tp>::_Binmap_type* __mt_alloc<_Tp>::_S_binmap; - - template<typename _Tp> - typename __mt_alloc<_Tp>::_Bin_record* volatile __mt_alloc<_Tp>::_S_bin; - - template<typename _Tp> - size_t __mt_alloc<_Tp>::_S_bin_size = 1; - - // Actual initialization in _S_initialize(). -#ifdef __GTHREADS - template<typename _Tp> - __gthread_once_t __mt_alloc<_Tp>::_S_once = __GTHREAD_ONCE_INIT; - - template<typename _Tp> - typename __mt_alloc<_Tp>::_Thread_record* - volatile __mt_alloc<_Tp>::_S_thread_freelist_first = NULL; - - template<typename _Tp> - __gthread_key_t __mt_alloc<_Tp>::_S_thread_key; - - template<typename _Tp> - __gthread_mutex_t -#ifdef __GTHREAD_MUTEX_INIT - __mt_alloc<_Tp>::_S_thread_freelist_mutex = __GTHREAD_MUTEX_INIT; -#else - __mt_alloc<_Tp>::_S_thread_freelist_mutex; -#endif -#endif -} // namespace __gnu_cxx +_GLIBCXX_END_NAMESPACE #endif diff --git a/contrib/libstdc++/include/ext/new_allocator.h b/contrib/libstdc++/include/ext/new_allocator.h index 1b0b4f610796..938783c4b1e4 100644 --- a/contrib/libstdc++/include/ext/new_allocator.h +++ b/contrib/libstdc++/include/ext/new_allocator.h @@ -1,6 +1,6 @@ // Allocator that wraps operator new -*- C++ -*- -// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -15,7 +15,7 @@ // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, // USA. // As a special exception, you may use this file as part of a free software @@ -27,21 +27,27 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. +/** @file ext/new_allocator.h + * This file is a GNU extension to the Standard C++ Library. + */ + #ifndef _NEW_ALLOCATOR_H #define _NEW_ALLOCATOR_H 1 #include <new> +#include <bits/functexcept.h> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + using std::size_t; + using std::ptrdiff_t; -namespace __gnu_cxx -{ /** * @brief An allocator that uses global new, as per [20.4]. * * This is precisely the allocator defined in the C++ Standard. * - all allocation calls operator new * - all deallocation calls operator delete - * - * (See @link Allocators allocators info @endlink for more.) */ template<typename _Tp> class new_allocator @@ -78,7 +84,12 @@ namespace __gnu_cxx // about what the return value is when __n == 0. pointer allocate(size_type __n, const void* = 0) - { return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp))); } + { + if (__builtin_expect(__n > this->max_size(), false)) + std::__throw_bad_alloc(); + + return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp))); + } // __p is not permitted to be a null pointer. void @@ -108,6 +119,7 @@ namespace __gnu_cxx inline bool operator!=(const new_allocator<_Tp>&, const new_allocator<_Tp>&) { return false; } -} // namespace __gnu_cxx + +_GLIBCXX_END_NAMESPACE #endif diff --git a/contrib/libstdc++/include/ext/numeric b/contrib/libstdc++/include/ext/numeric index 40edf07fe3da..290d032836a7 100644 --- a/contrib/libstdc++/include/ext/numeric +++ b/contrib/libstdc++/include/ext/numeric @@ -1,6 +1,6 @@ // Numeric extensions -*- C++ -*- -// Copyright (C) 2002 Free Software Foundation, Inc. +// Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -15,7 +15,7 @@ // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, // USA. // As a special exception, you may use this file as part of a free software @@ -55,8 +55,7 @@ /** @file ext/numeric * This file is a GNU extension to the Standard C++ Library (possibly - * containing extensions from the HP/SGI STL subset). You should only - * include this header if you are using GCC 3 or later. + * containing extensions from the HP/SGI STL subset). */ #ifndef _EXT_NUMERIC @@ -69,8 +68,8 @@ #include <ext/functional> // For identity_element -namespace __gnu_cxx -{ +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + // Returns __x ** __n, where __n >= 0. _Note that "multiplication" // is required to be associative, but not necessarily commutative. template<typename _Tp, typename _Integer, typename _MonoidOperation> @@ -79,22 +78,25 @@ namespace __gnu_cxx { if (__n == 0) return identity_element(__monoid_op); - else { - while ((__n & 1) == 0) { + else + { + while ((__n & 1) == 0) + { + __n >>= 1; + __x = __monoid_op(__x, __x); + } + + _Tp __result = __x; __n >>= 1; - __x = __monoid_op(__x, __x); + while (__n != 0) + { + __x = __monoid_op(__x, __x); + if ((__n & 1) != 0) + __result = __monoid_op(__result, __x); + __n >>= 1; + } + return __result; } - - _Tp __result = __x; - __n >>= 1; - while (__n != 0) { - __x = __monoid_op(__x, __x); - if ((__n & 1) != 0) - __result = __monoid_op(__result, __x); - __n >>= 1; - } - return __result; - } } template<typename _Tp, typename _Integer> @@ -142,7 +144,8 @@ namespace __gnu_cxx while (__first != __last) *__first++ = __value++; } -} // namespace __gnu_cxx + +_GLIBCXX_END_NAMESPACE #endif diff --git a/contrib/libstdc++/include/ext/numeric_traits.h b/contrib/libstdc++/include/ext/numeric_traits.h new file mode 100644 index 000000000000..cff5b7066d6f --- /dev/null +++ b/contrib/libstdc++/include/ext/numeric_traits.h @@ -0,0 +1,98 @@ +// -*- C++ -*- + +// Copyright (C) 2007 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +/** @file ext/numeric_traits.h + * This file is a GNU extension to the Standard C++ Library. + */ + +#ifndef _EXT_NUMERIC_TRAITS +#define _EXT_NUMERIC_TRAITS 1 + +#pragma GCC system_header + +#include <limits> +#include <bits/cpp_type_traits.h> +#include <ext/type_traits.h> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + // Compile time constants for builtin types. + // Sadly std::numeric_limits member functions cannot be used for this. +#define __glibcxx_signed(_Tp) ((_Tp)(-1) < 0) +#define __glibcxx_digits(_Tp) \ + (sizeof(_Tp) * __CHAR_BIT__ - __glibcxx_signed(_Tp)) + +#define __glibcxx_min(_Tp) \ + (__glibcxx_signed(_Tp) ? (_Tp)1 << __glibcxx_digits(_Tp) : (_Tp)0) + +#define __glibcxx_max(_Tp) \ + (__glibcxx_signed(_Tp) ? \ + (((((_Tp)1 << (__glibcxx_digits(_Tp) - 1)) - 1) << 1) + 1) : ~(_Tp)0) + + template<typename _Value> + struct __numeric_traits_integer + { + // Only integers for initialization of member constant. + static const _Value __min = __glibcxx_min(_Value); + static const _Value __max = __glibcxx_max(_Value); + }; + + template<typename _Value> + const _Value __numeric_traits_integer<_Value>::__min; + + template<typename _Value> + const _Value __numeric_traits_integer<_Value>::__max; + + template<typename _Value> + struct __numeric_traits_floating + { + // Only floating point types. See N1822. + static const int __max_digits10 = + 2 + std::numeric_limits<_Value>::digits * 3010/10000; + }; + + template<typename _Value> + const int __numeric_traits_floating<_Value>::__max_digits10; + + template<typename _Value> + struct __numeric_traits + : public __conditional_type<std::__is_integer<_Value>::__value, + __numeric_traits_integer<_Value>, + __numeric_traits_floating<_Value> >::__type + { }; + +_GLIBCXX_END_NAMESPACE + +#undef __glibcxx_signed +#undef __glibcxx_min +#undef __glibcxx_max +#undef __glibcxx_digits + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/assoc_container.hpp b/contrib/libstdc++/include/ext/pb_ds/assoc_container.hpp new file mode 100644 index 000000000000..271cc7600f14 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/assoc_container.hpp @@ -0,0 +1,689 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file assoc_container.hpp + * Contains associative containers. + */ + +#ifndef PB_DS_ASSOC_CNTNR_HPP +#define PB_DS_ASSOC_CNTNR_HPP + +#include <ext/typelist.h> +#include <ext/pb_ds/tag_and_trait.hpp> +#include <ext/pb_ds/detail/standard_policies.hpp> +#include <ext/pb_ds/detail/container_base_dispatch.hpp> +#include <ext/pb_ds/detail/basic_tree_policy/traits.hpp> + +namespace pb_ds +{ +#define PB_DS_BASE_C_DEC \ + detail::container_base_dispatch<Key, Mapped, Tag, Policy_Tl, Allocator>::type + + // An abstract basic associative container. + template<typename Key, + typename Mapped, + typename Tag, + typename Policy_Tl, + typename Allocator> + class container_base : public PB_DS_BASE_C_DEC + { + private: + typedef typename PB_DS_BASE_C_DEC base_type; + + public: + typedef Tag container_category; + typedef Allocator allocator; + typedef typename allocator::size_type size_type; + typedef typename allocator::difference_type difference_type; + + // key_type + typedef typename allocator::template rebind<Key>::other::value_type key_type; + typedef typename allocator::template rebind<key_type>::other key_rebind; + typedef typename key_rebind::reference key_reference; + typedef typename key_rebind::const_reference const_key_reference; + typedef typename key_rebind::pointer key_pointer; + typedef typename key_rebind::const_pointer const_key_pointer; + + // mapped_type + typedef Mapped mapped_type; + typedef typename allocator::template rebind<mapped_type>::other mapped_rebind; + typedef typename mapped_rebind::reference mapped_reference; + typedef typename mapped_rebind::const_reference const_mapped_reference; + typedef typename mapped_rebind::pointer mapped_pointer; + typedef typename mapped_rebind::const_pointer const_mapped_pointer; + + // value_type + typedef typename base_type::value_type value_type; + typedef typename allocator::template rebind<value_type>::other value_rebind; + typedef typename value_rebind::reference reference; + typedef typename value_rebind::const_reference const_reference; + typedef typename value_rebind::pointer pointer; + typedef typename value_rebind::const_pointer const_pointer; + + // iterators + typedef typename base_type::iterator iterator; + typedef typename base_type::const_iterator const_iterator; + typedef typename base_type::point_iterator point_iterator; + typedef typename base_type::const_point_iterator const_point_iterator; + + virtual + ~container_base() { } + + protected: +#define PB_DS_CLASS_NAME container_base +#include <ext/pb_ds/detail/constructors_destructor_fn_imps.hpp> +#undef PB_DS_CLASS_NAME + }; + +#undef PB_DS_BASE_C_DEC + + +#define PB_DS_BASE_C_DEC \ + container_base<Key, Mapped, Tag, typename __gnu_cxx::typelist::append< \ + typename __gnu_cxx::typelist::create4<Hash_Fn, Eq_Fn, Resize_Policy, detail::integral_constant<int, Store_Hash> >::type, Policy_TL>::type, Allocator> + + // An abstract basic hash-based associative container. + template<typename Key, + typename Mapped, + typename Hash_Fn, + typename Eq_Fn, + typename Resize_Policy, + bool Store_Hash, + typename Tag, + typename Policy_TL, + typename Allocator> + class basic_hash_table : public PB_DS_BASE_C_DEC + { + private: + typedef PB_DS_BASE_C_DEC base_type; + + public: + virtual + ~basic_hash_table() { } + + protected: +#define PB_DS_CLASS_NAME basic_hash_table +#include <ext/pb_ds/detail/constructors_destructor_fn_imps.hpp> +#undef PB_DS_CLASS_NAME + + private: + basic_hash_table& + operator=(const base_type&); + }; + +#undef PB_DS_BASE_C_DEC + + +#define PB_DS_BASE_C_DEC \ + basic_hash_table<Key, Mapped, Hash_Fn, Eq_Fn, Resize_Policy, Store_Hash, \ + cc_hash_tag, \ + typename __gnu_cxx::typelist::create1<Comb_Hash_Fn>::type, Allocator> + + // A concrete collision-chaining hash-based associative container. + template<typename Key, + typename Mapped, + typename Hash_Fn = typename detail::default_hash_fn<Key>::type, + typename Eq_Fn = typename detail::default_eq_fn<Key>::type, + typename Comb_Hash_Fn = detail::default_comb_hash_fn::type, + typename Resize_Policy = typename detail::default_resize_policy<Comb_Hash_Fn>::type, + bool Store_Hash = detail::default_store_hash, + typename Allocator = std::allocator<char> > + class cc_hash_table : public PB_DS_BASE_C_DEC + { + private: + typedef PB_DS_BASE_C_DEC base_type; + + public: + typedef Hash_Fn hash_fn; + typedef Eq_Fn eq_fn; + typedef Resize_Policy resize_policy; + typedef Comb_Hash_Fn comb_hash_fn; + + // Default constructor. + cc_hash_table() { } + + // Constructor taking some policy objects. r_hash_fn will be + // copied by the Hash_Fn object of the container object. + cc_hash_table(const hash_fn& h) + : base_type(h) { } + + // Constructor taking some policy objects. r_hash_fn will be + // copied by the hash_fn object of the container object, and + // r_eq_fn will be copied by the eq_fn object of the container + // object. + cc_hash_table(const hash_fn& h, const eq_fn& e) + : base_type(h, e) { } + + // Constructor taking some policy objects. r_hash_fn will be + // copied by the hash_fn object of the container object, r_eq_fn + // will be copied by the eq_fn object of the container object, and + // r_comb_hash_fn will be copied by the comb_hash_fn object of the + // container object. + cc_hash_table(const hash_fn& h, const eq_fn& e, const comb_hash_fn& ch) + : base_type(h, e, ch) { } + + // Constructor taking some policy objects. r_hash_fn will be + // copied by the hash_fn object of the container object, r_eq_fn + // will be copied by the eq_fn object of the container object, + // r_comb_hash_fn will be copied by the comb_hash_fn object of the + // container object, and r_resize_policy will be copied by the + // resize_policy object of the container object. + cc_hash_table(const hash_fn& h, const eq_fn& e, const comb_hash_fn& ch, + const resize_policy& rp) + : base_type(h, e, ch, rp) { } + + // Constructor taking __iterators to a range of value_types. The + // value_types between first_it and last_it will be inserted into + // the container object. + template<typename It> + cc_hash_table(It first, It last) + { base_type::copy_from_range(first, last); } + + // Constructor taking __iterators to a range of value_types and + // some policy objects. The value_types between first_it and + // last_it will be inserted into the container object. + template<typename It> + cc_hash_table(It first, It last, const hash_fn& h) + : base_type(h) + { copy_from_range(first, last); } + + // Constructor taking __iterators to a range of value_types and + // some policy objects The value_types between first_it and + // last_it will be inserted into the container object. r_hash_fn + // will be copied by the hash_fn object of the container object, + // and r_eq_fn will be copied by the eq_fn object of the container + // object. + template<typename It> + cc_hash_table(It first, It last, const hash_fn& h, const eq_fn& e) + : base_type(h, e) + { copy_from_range(first, last); } + + // Constructor taking __iterators to a range of value_types and + // some policy objects The value_types between first_it and + // last_it will be inserted into the container object. r_hash_fn + // will be copied by the hash_fn object of the container object, + // r_eq_fn will be copied by the eq_fn object of the container + // object, and r_comb_hash_fn will be copied by the comb_hash_fn + // object of the container object. + template<typename It> + cc_hash_table(It first, It last, const hash_fn& h, const eq_fn& e, + const comb_hash_fn& ch) + : base_type(h, e, ch) + { copy_from_range(first, last); } + + // Constructor taking __iterators to a range of value_types and + // some policy objects The value_types between first_it and + // last_it will be inserted into the container object. r_hash_fn + // will be copied by the hash_fn object of the container object, + // r_eq_fn will be copied by the eq_fn object of the container + // object, r_comb_hash_fn will be copied by the comb_hash_fn + // object of the container object, and r_resize_policy will be + // copied by the resize_policy object of the container object. + template<typename It> + cc_hash_table(It first, It last, const hash_fn& h, const eq_fn& e, + const comb_hash_fn& ch, const resize_policy& rp) + : base_type(h, e, ch, rp) + { copy_from_range(first, last); } + + cc_hash_table(const cc_hash_table& other) + : base_type((const base_type&)other) + { } + + virtual + ~cc_hash_table() { } + + cc_hash_table& + operator=(const cc_hash_table& other) + { + if (this != &other) + { + cc_hash_table tmp(other); + swap(tmp); + } + return *this; + } + + void + swap(cc_hash_table& other) + { base_type::swap(other); } + }; + +#undef PB_DS_BASE_C_DEC + + +#define PB_DS_BASE_C_DEC \ + basic_hash_table<Key, Mapped, Hash_Fn, Eq_Fn, Resize_Policy, Store_Hash, \ + gp_hash_tag, \ + typename __gnu_cxx::typelist::create2<Comb_Probe_Fn, Probe_Fn>::type, Allocator> + + // A concrete general-probing hash-based associative container. + template<typename Key, + typename Mapped, + typename Hash_Fn = typename detail::default_hash_fn<Key>::type, + typename Eq_Fn = typename detail::default_eq_fn<Key>::type, + typename Comb_Probe_Fn = detail::default_comb_hash_fn::type, + typename Probe_Fn = typename detail::default_probe_fn<Comb_Probe_Fn>::type, + typename Resize_Policy = typename detail::default_resize_policy<Comb_Probe_Fn>::type, + bool Store_Hash = detail::default_store_hash, + typename Allocator = std::allocator<char> > + class gp_hash_table : public PB_DS_BASE_C_DEC + { + private: + typedef PB_DS_BASE_C_DEC base_type; + + public: + typedef Hash_Fn hash_fn; + typedef Eq_Fn eq_fn; + typedef Comb_Probe_Fn comb_probe_fn; + typedef Probe_Fn probe_fn; + typedef Resize_Policy resize_policy; + + // Default constructor. + gp_hash_table() { } + + // Constructor taking some policy objects. r_hash_fn will be + // copied by the hash_fn object of the container object. + gp_hash_table(const hash_fn& h) + : base_type(h) { } + + // Constructor taking some policy objects. r_hash_fn will be + // copied by the hash_fn object of the container object, and + // r_eq_fn will be copied by the eq_fn object of the container + // object. + gp_hash_table(const hash_fn& h, const eq_fn& e) + : base_type(h, e) { } + + // Constructor taking some policy objects. r_hash_fn will be + // copied by the hash_fn object of the container object, r_eq_fn + // will be copied by the eq_fn object of the container object, and + // r_comb_probe_fn will be copied by the comb_probe_fn object of + // the container object. + gp_hash_table(const hash_fn& h, const eq_fn& e, const comb_probe_fn& cp) + : base_type(h, e, cp) { } + + // Constructor taking some policy objects. r_hash_fn will be + // copied by the hash_fn object of the container object, r_eq_fn + // will be copied by the eq_fn object of the container object, + // r_comb_probe_fn will be copied by the comb_probe_fn object of + // the container object, and r_probe_fn will be copied by the + // probe_fn object of the container object. + gp_hash_table(const hash_fn& h, const eq_fn& e, const comb_probe_fn& cp, + const probe_fn& p) + : base_type(h, e, cp, p) { } + + // Constructor taking some policy objects. r_hash_fn will be + // copied by the hash_fn object of the container object, r_eq_fn + // will be copied by the eq_fn object of the container object, + // r_comb_probe_fn will be copied by the comb_probe_fn object of + // the container object, r_probe_fn will be copied by the probe_fn + // object of the container object, and r_resize_policy will be + // copied by the Resize_Policy object of the container object. + gp_hash_table(const hash_fn& h, const eq_fn& e, const comb_probe_fn& cp, + const probe_fn& p, const resize_policy& rp) + : base_type(h, e, cp, p, rp) { } + + // Constructor taking __iterators to a range of value_types. The + // value_types between first_it and last_it will be inserted into + // the container object. + template<typename It> + gp_hash_table(It first, It last) + { base_type::copy_from_range(first, last); } + + // Constructor taking __iterators to a range of value_types and + // some policy objects. The value_types between first_it and + // last_it will be inserted into the container object. r_hash_fn + // will be copied by the hash_fn object of the container object. + template<typename It> + gp_hash_table(It first, It last, const hash_fn& h) + : base_type(h) + { base_type::copy_from_range(first, last); } + + // Constructor taking __iterators to a range of value_types and + // some policy objects. The value_types between first_it and + // last_it will be inserted into the container object. r_hash_fn + // will be copied by the hash_fn object of the container object, + // and r_eq_fn will be copied by the eq_fn object of the container + // object. + template<typename It> + gp_hash_table(It first, It last, const hash_fn& h, const eq_fn& e) + : base_type(h, e) + { base_type::copy_from_range(first, last); } + + // Constructor taking __iterators to a range of value_types and + // some policy objects. The value_types between first_it and + // last_it will be inserted into the container object. r_hash_fn + // will be copied by the hash_fn object of the container object, + // r_eq_fn will be copied by the eq_fn object of the container + // object, and r_comb_probe_fn will be copied by the comb_probe_fn + // object of the container object. + template<typename It> + gp_hash_table(It first, It last, const hash_fn& h, const eq_fn& e, + const comb_probe_fn& cp) + : base_type(h, e, cp) + { base_type::copy_from_range(first, last); } + + // Constructor taking __iterators to a range of value_types and + // some policy objects. The value_types between first_it and + // last_it will be inserted into the container object. r_hash_fn + // will be copied by the hash_fn object of the container object, + // r_eq_fn will be copied by the eq_fn object of the container + // object, r_comb_probe_fn will be copied by the comb_probe_fn + // object of the container object, and r_probe_fn will be copied + // by the probe_fn object of the container object. + template<typename It> + gp_hash_table(It first, It last, const hash_fn& h, const eq_fn& e, + const comb_probe_fn& cp, const probe_fn& p) + : base_type(h, e, cp, p) + { base_type::copy_from_range(first, last); } + + // Constructor taking __iterators to a range of value_types and + // some policy objects. The value_types between first_it and + // last_it will be inserted into the container object. r_hash_fn + // will be copied by the hash_fn object of the container object, + // r_eq_fn will be copied by the eq_fn object of the container + // object, r_comb_probe_fn will be copied by the comb_probe_fn + // object of the container object, r_probe_fn will be copied by + // the probe_fn object of the container object, and + // r_resize_policy will be copied by the resize_policy object of + // the container object. + template<typename It> + gp_hash_table(It first, It last, const hash_fn& h, const eq_fn& e, + const comb_probe_fn& cp, const probe_fn& p, + const resize_policy& rp) + : base_type(h, e, cp, p, rp) + { base_type::copy_from_range(first, last); } + + gp_hash_table(const gp_hash_table& other) + : base_type((const base_type&)other) + { } + + virtual + ~gp_hash_table() { } + + gp_hash_table& + operator=(const gp_hash_table& other) + { + if (this != &other) + { + gp_hash_table tmp(other); + swap(tmp); + } + return *this; + } + + void + swap(gp_hash_table& other) + { base_type::swap(other); } + }; + +#undef PB_DS_BASE_C_DEC + + +#define PB_DS_BASE_C_DEC \ + container_base<Key, Mapped, Tag, Policy_Tl, Allocator> + + // An abstract basic tree-like (tree, trie) associative container. + template<typename Key, typename Mapped, typename Tag, + typename Node_Update, typename Policy_Tl, typename Allocator> + class basic_tree : public PB_DS_BASE_C_DEC + { + private: + typedef PB_DS_BASE_C_DEC base_type; + + public: + typedef Node_Update node_update; + + virtual + ~basic_tree() { } + + protected: +#define PB_DS_CLASS_NAME basic_tree +#include <ext/pb_ds/detail/constructors_destructor_fn_imps.hpp> +#undef PB_DS_CLASS_NAME + }; + +#undef PB_DS_BASE_C_DEC + + +#define PB_DS_TREE_NODE_AND_IT_TRAITS_C_DEC \ + detail::tree_traits<Key, Mapped,Cmp_Fn,Node_Update,Tag, Allocator> + +#define PB_DS_BASE_C_DEC \ + basic_tree<Key,Mapped,Tag,typename PB_DS_TREE_NODE_AND_IT_TRAITS_C_DEC::node_update, \ + typename __gnu_cxx::typelist::create2<Cmp_Fn, PB_DS_TREE_NODE_AND_IT_TRAITS_C_DEC >::type, Allocator> + + // A concrete basic tree-based associative container. + template<typename Key, typename Mapped, typename Cmp_Fn = std::less<Key>, + typename Tag = rb_tree_tag, + template<typename Const_Node_Iterator, typename Node_Iterator, typename Cmp_Fn_, typename Allocator_> + class Node_Update = pb_ds::null_tree_node_update, + typename Allocator = std::allocator<char> > + class tree : public PB_DS_BASE_C_DEC + { + private: + typedef PB_DS_BASE_C_DEC base_type; + + public: + // Comparison functor type. + typedef Cmp_Fn cmp_fn; + + tree() { } + + // Constructor taking some policy objects. r_cmp_fn will be copied + // by the Cmp_Fn object of the container object. + tree(const cmp_fn& c) + : base_type(c) { } + + // Constructor taking __iterators to a range of value_types. The + // value_types between first_it and last_it will be inserted into + // the container object. + template<typename It> + tree(It first, It last) + { base_type::copy_from_range(first, last); } + + // Constructor taking __iterators to a range of value_types and + // some policy objects The value_types between first_it and + // last_it will be inserted into the container object. r_cmp_fn + // will be copied by the cmp_fn object of the container object. + template<typename It> + tree(It first, It last, const cmp_fn& c) + : base_type(c) + { base_type::copy_from_range(first, last); } + + tree(const tree& other) + : base_type((const base_type&)other) { } + + virtual + ~tree() { } + + tree& + operator=(const tree& other) + { + if (this != &other) + { + tree tmp(other); + swap(tmp); + } + return *this; + } + + void + swap(tree& other) + { base_type::swap(other); } + }; + +#undef PB_DS_BASE_C_DEC +#undef PB_DS_TREE_NODE_AND_IT_TRAITS_C_DEC + + +#define PB_DS_TRIE_NODE_AND_ITS_TRAITS \ + detail::trie_traits<Key,Mapped,E_Access_Traits,Node_Update,Tag,Allocator> + +#define PB_DS_BASE_C_DEC \ + basic_tree<Key,Mapped,Tag, typename PB_DS_TRIE_NODE_AND_ITS_TRAITS::node_update, \ + typename __gnu_cxx::typelist::create2<E_Access_Traits, PB_DS_TRIE_NODE_AND_ITS_TRAITS >::type, Allocator> + + // A concrete basic trie-based associative container. + template<typename Key, + typename Mapped, + typename E_Access_Traits = typename detail::default_trie_e_access_traits<Key>::type, + typename Tag = pat_trie_tag, + template<typename Const_Node_Iterator, + typename Node_Iterator, + typename E_Access_Traits_, + typename Allocator_> + class Node_Update = null_trie_node_update, + typename Allocator = std::allocator<char> > + class trie : public PB_DS_BASE_C_DEC + { + private: + typedef PB_DS_BASE_C_DEC base_type; + + public: + // Element access traits type. + typedef E_Access_Traits e_access_traits; + + trie() { } + + // Constructor taking some policy objects. r_e_access_traits will + // be copied by the E_Access_Traits object of the container + // object. + trie(const e_access_traits& t) + : base_type(t) { } + + // Constructor taking __iterators to a range of value_types. The + // value_types between first_it and last_it will be inserted into + // the container object. + template<typename It> + trie(It first, It last) + { base_type::copy_from_range(first, last); } + + // Constructor taking __iterators to a range of value_types and + // some policy objects. The value_types between first_it and + // last_it will be inserted into the container object. + template<typename It> + trie(It first, It last, const e_access_traits& t) + : base_type(t) + { base_type::copy_from_range(first, last); } + + trie(const trie& other) + : base_type((const base_type&)other) { } + + virtual + ~trie() { } + + trie& + operator=(const trie& other) + { + if (this != &other) + { + trie tmp(other); + swap(tmp); + } + return *this; + } + + void + swap(trie& other) + { base_type::swap(other); } + }; + +#undef PB_DS_BASE_C_DEC +#undef PB_DS_TRIE_NODE_AND_ITS_TRAITS + + +#define PB_DS_BASE_C_DEC \ + container_base<Key, Mapped, list_update_tag, \ + typename __gnu_cxx::typelist::create2<Eq_Fn, Update_Policy>::type, Allocator> + + // A list-update based associative container. + template<typename Key, + typename Mapped, + class Eq_Fn = typename detail::default_eq_fn<Key>::type, + class Update_Policy = detail::default_update_policy::type, + class Allocator = std::allocator<char> > + class list_update : public PB_DS_BASE_C_DEC + { + private: + typedef PB_DS_BASE_C_DEC base_type; + + public: + typedef Eq_Fn eq_fn; + typedef Update_Policy update_policy; + typedef Allocator allocator; + + list_update() { } + + // Constructor taking __iterators to a range of value_types. The + // value_types between first_it and last_it will be inserted into + // the container object. + template<typename It> + list_update(It first, It last) + { base_type::copy_from_range(first, last); } + + list_update(const list_update& other) + : base_type((const base_type&)other) { } + + virtual + ~list_update() { } + + list_update& + operator=(const list_update& other) + { + if (this !=& other) + { + list_update tmp(other); + swap(tmp); + } + return *this; + } + + void + swap(list_update& other) + { base_type::swap(other); } + }; + +#undef PB_DS_BASE_C_DEC + +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/basic_tree_policy/basic_tree_policy_base.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/basic_tree_policy/basic_tree_policy_base.hpp new file mode 100644 index 000000000000..d396d7d5da50 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/basic_tree_policy/basic_tree_policy_base.hpp @@ -0,0 +1,179 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file basic_tree_policy_base.hpp + * Contains a base class for tree_like policies. + */ + +#ifndef PB_DS_TREE_LIKE_POLICY_BASE_HPP +#define PB_DS_TREE_LIKE_POLICY_BASE_HPP + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_CLASS_C_DEC \ + basic_tree_policy_base< \ + Const_Node_Iterator, \ + Node_Iterator, \ + Allocator> + + template<typename Const_Node_Iterator, + typename Node_Iterator, + typename Allocator> + struct basic_tree_policy_base + { + protected: + typedef typename Node_Iterator::value_type it_type; + + typedef typename std::iterator_traits< it_type>::value_type value_type; + + typedef typename value_type::first_type key_type; + + typedef + typename Allocator::template rebind< + typename remove_const< + key_type>::type>::other::const_reference + const_key_reference; + + typedef + typename Allocator::template rebind< + typename remove_const< + value_type>::type>::other::const_reference + const_reference; + + typedef + typename Allocator::template rebind< + typename remove_const< + value_type>::type>::other::reference + reference; + + typedef + typename Allocator::template rebind< + typename remove_const< + value_type>::type>::other::const_pointer + const_pointer; + + static inline const_key_reference + extract_key(const_reference r_val) + { + return (r_val.first); + } + + virtual it_type + end() = 0; + + it_type + end_iterator() const + { + return (const_cast<PB_DS_CLASS_C_DEC* >(this)->end()); + } + + virtual + ~basic_tree_policy_base() + { } + }; + + template<typename Const_Node_Iterator, typename Allocator> + struct basic_tree_policy_base< + Const_Node_Iterator, + Const_Node_Iterator, + Allocator> + { + protected: + typedef typename Const_Node_Iterator::value_type it_type; + + typedef typename std::iterator_traits< it_type>::value_type value_type; + + typedef value_type key_type; + + typedef + typename Allocator::template rebind< + typename remove_const< + key_type>::type>::other::const_reference + const_key_reference; + + typedef + typename Allocator::template rebind< + typename remove_const< + value_type>::type>::other::const_reference + const_reference; + + typedef + typename Allocator::template rebind< + typename remove_const< + value_type>::type>::other::reference + reference; + + typedef + typename Allocator::template rebind< + typename remove_const< + value_type>::type>::other::const_pointer + const_pointer; + + static inline const_key_reference + extract_key(const_reference r_val) + { + return (r_val); + } + + virtual it_type + end() const = 0; + + it_type + end_iterator() const + { + return (end()); + } + + virtual + ~basic_tree_policy_base() + { } + }; + +#undef PB_DS_CLASS_C_DEC + + } // namespace detail +} // namespace pb_ds + +#endif // #ifndef PB_DS_TREE_LIKE_POLICY_BASE_HPP diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/basic_tree_policy/null_node_metadata.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/basic_tree_policy/null_node_metadata.hpp new file mode 100644 index 000000000000..23991987097a --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/basic_tree_policy/null_node_metadata.hpp @@ -0,0 +1,73 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file null_node_metadata.hpp + * Contains an implementation class for tree-like classes. + */ + +#ifndef PB_DS_NULL_NODE_METADATA_HPP +#define PB_DS_NULL_NODE_METADATA_HPP + +#include <ext/pb_ds/detail/types_traits.hpp> + +namespace pb_ds +{ + namespace detail + { + template<typename Key, class Data, class Allocator> + struct dumconst_node_iterator + { + private: + typedef typename types_traits<Key, Data, Allocator, false>::pointer const_iterator; + + public: + typedef const_iterator value_type; + typedef const_iterator const_reference; + typedef const_reference reference; + }; + + struct null_node_metadata + { }; + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/basic_tree_policy/traits.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/basic_tree_policy/traits.hpp new file mode 100644 index 000000000000..c574bc09aa42 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/basic_tree_policy/traits.hpp @@ -0,0 +1,91 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file traits.hpp + * Contains an implementation class for tree-like classes. + */ + +#ifndef PB_DS_NODE_AND_IT_TRAITS_HPP +#define PB_DS_NODE_AND_IT_TRAITS_HPP + +#include <ext/pb_ds/detail/types_traits.hpp> +#include <ext/pb_ds/detail/bin_search_tree_/traits.hpp> +#include <ext/pb_ds/detail/tree_policy/node_metadata_selector.hpp> +#include <ext/pb_ds/detail/trie_policy/node_metadata_selector.hpp> + +namespace pb_ds +{ + namespace detail + { + template<typename Key, + typename Data, + class Cmp_Fn, + template<typename Const_Node_Iterator, + class Node_Iterator, + class Cmp_Fn_, + class Allocator> + class Node_Update, + class Tag, + class Allocator> + struct tree_traits; + + template<typename Key, + typename Data, + class E_Access_Traits, + template<typename Const_Node_Iterator, + class Node_Iterator, + class E_Access_Traits_, + class Allocator> + class Node_Update, + class Tag, + class Allocator> + struct trie_traits; + + } // namespace detail +} // namespace pb_ds + +#include <ext/pb_ds/detail/rb_tree_map_/traits.hpp> +#include <ext/pb_ds/detail/splay_tree_/traits.hpp> +#include <ext/pb_ds/detail/ov_tree_map_/traits.hpp> +#include <ext/pb_ds/detail/pat_trie_/traits.hpp> + +#endif // #ifndef PB_DS_NODE_AND_IT_TRAITS_HPP diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/basic_types.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/basic_types.hpp new file mode 100644 index 000000000000..69288ce5ec50 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/basic_types.hpp @@ -0,0 +1,217 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file basic_types.hpp + * Contains basic types used by containers. + */ + +#ifndef PB_DS_BASIC_TYPES_HPP +#define PB_DS_BASIC_TYPES_HPP + +#include <algorithm> +#include <utility> +#include <ext/pb_ds/tag_and_trait.hpp> +#include <ext/pb_ds/detail/type_utils.hpp> + +namespace pb_ds +{ + namespace detail + { + template<typename Key, typename Mapped, typename Allocator, bool Store_Hash> + struct value_type_base; + + /** + * Specialization of value_type_base for the case where the hash value + * is not stored alongside each value. + **/ + template<typename Key, typename Mapped, typename Allocator> + struct value_type_base<Key, Mapped, Allocator, false> + { + typedef typename Allocator::template rebind<Mapped>::other mapped_type_allocator; + typedef typename mapped_type_allocator::value_type mapped_type; + typedef typename mapped_type_allocator::pointer mapped_pointer; + typedef typename mapped_type_allocator::const_pointer const_mapped_pointer; + typedef typename mapped_type_allocator::reference mapped_reference; + typedef typename mapped_type_allocator::const_reference const_mapped_reference; + + typedef typename Allocator::template rebind<std::pair<const Key, Mapped> >::other value_type_allocator; + typedef typename value_type_allocator::value_type value_type; + typedef typename value_type_allocator::pointer pointer; + typedef typename value_type_allocator::const_pointer const_pointer; + typedef typename value_type_allocator::reference reference; + typedef typename value_type_allocator::const_reference const_reference; + + struct stored_value_type + { + value_type m_value; + }; + }; + + /** + * Specialization of value_type_base for the case where the hash value + * is stored alongside each value. + **/ + template<typename Key, typename Mapped, typename Allocator> + struct value_type_base<Key, Mapped, Allocator, true> + { + typedef typename Allocator::template rebind<Mapped>::other mapped_type_allocator; + typedef typename mapped_type_allocator::value_type mapped_type; + typedef typename mapped_type_allocator::pointer mapped_pointer; + typedef typename mapped_type_allocator::const_pointer const_mapped_pointer; + typedef typename mapped_type_allocator::reference mapped_reference; + typedef typename mapped_type_allocator::const_reference const_mapped_reference; + + typedef typename Allocator::template rebind<std::pair<const Key, Mapped> >::other value_type_allocator; + typedef typename value_type_allocator::value_type value_type; + typedef typename value_type_allocator::pointer pointer; + typedef typename value_type_allocator::const_pointer const_pointer; + typedef typename value_type_allocator::reference reference; + typedef typename value_type_allocator::const_reference const_reference; + + struct stored_value_type + { + value_type m_value; + typename Allocator::size_type m_hash; + }; + }; + +#define PB_DS_CLASS_T_DEC \ + template<typename Key, typename Allocator> + +#define PB_DS_CLASS_C_DEC \ + value_type_base<Key, null_mapped_type, Allocator, false> + + /** + * Specialization of value_type_base for the case where the hash value + * is not stored alongside each value. + **/ + template<typename Key, typename Allocator> + struct value_type_base<Key, null_mapped_type, Allocator, false> + { + typedef typename Allocator::template rebind<null_mapped_type>::other mapped_type_allocator; + typedef typename mapped_type_allocator::value_type mapped_type; + typedef typename mapped_type_allocator::pointer mapped_pointer; + typedef typename mapped_type_allocator::const_pointer const_mapped_pointer; + typedef typename mapped_type_allocator::reference mapped_reference; + typedef typename mapped_type_allocator::const_reference const_mapped_reference; + + typedef Key value_type; + + typedef typename Allocator::template rebind<value_type>::other value_type_allocator; + typedef typename value_type_allocator::pointer pointer; + typedef typename value_type_allocator::const_pointer const_pointer; + typedef typename value_type_allocator::reference reference; + typedef typename value_type_allocator::const_reference const_reference; + + struct stored_value_type + { + value_type m_value; + }; + + static null_mapped_type s_null_mapped; + }; + + PB_DS_CLASS_T_DEC + null_mapped_type PB_DS_CLASS_C_DEC::s_null_mapped; + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +#define PB_DS_CLASS_T_DEC \ + template<typename Key, typename Allocator> + +#define PB_DS_CLASS_C_DEC \ + value_type_base<Key, null_mapped_type, Allocator, true> + + /** + * Specialization of value_type_base for the case where the hash value + * is stored alongside each value. + **/ + template<typename Key, typename Allocator> + struct value_type_base<Key, null_mapped_type, Allocator, true> + { + typedef typename Allocator::template rebind<null_mapped_type>::other mapped_type_allocator; + typedef typename mapped_type_allocator::value_type mapped_type; + typedef typename mapped_type_allocator::pointer mapped_pointer; + typedef typename mapped_type_allocator::const_pointer const_mapped_pointer; + typedef typename mapped_type_allocator::reference mapped_reference; + typedef typename mapped_type_allocator::const_reference const_mapped_reference; + + typedef Key value_type; + + typedef typename Allocator::template rebind<value_type>::other value_type_allocator; + typedef typename value_type_allocator::pointer pointer; + typedef typename value_type_allocator::const_pointer const_pointer; + typedef typename value_type_allocator::reference reference; + typedef typename value_type_allocator::const_reference const_reference; + + struct stored_value_type + { + value_type m_value; + typename Allocator::size_type m_hash; + }; + + static null_mapped_type s_null_mapped; + }; + + PB_DS_CLASS_T_DEC + null_mapped_type PB_DS_CLASS_C_DEC::s_null_mapped; + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + + template<typename Key, typename Mapped> + struct no_throw_copies + { + typedef integral_constant<int, is_simple<Key>::value && is_simple<Mapped>::value> indicator; + }; + + template<typename Key> + struct no_throw_copies<Key, null_mapped_type> + { + typedef integral_constant<int, is_simple<Key>::value> indicator; + }; + } // namespace detail +} // namespace pb_ds + +#endif + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/bin_search_tree_.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/bin_search_tree_.hpp new file mode 100644 index 000000000000..fa0ff416b42a --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/bin_search_tree_.hpp @@ -0,0 +1,503 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file bin_search_tree_.hpp + * Contains an implementation class for bin_search_tree_. + */ +/* + * This implementation uses an idea from the SGI STL (using a "header" node + * which is needed for efficient iteration). + */ + +#include <ext/pb_ds/exception.hpp> +#include <ext/pb_ds/detail/eq_fn/eq_by_less.hpp> +#include <ext/pb_ds/detail/types_traits.hpp> +#include <ext/pb_ds/detail/map_debug_base.hpp> +#include <ext/pb_ds/tree_policy.hpp> +#include <ext/pb_ds/detail/cond_dealtor.hpp> +#include <ext/pb_ds/detail/type_utils.hpp> +#include <ext/pb_ds/detail/tree_trace_base.hpp> +#include <utility> +#include <functional> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_CLASS_T_DEC \ + template<typename Key, typename Mapped, class Cmp_Fn, \ + class Node_And_It_Traits, class Allocator> + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_CLASS_NAME \ + bin_search_tree_data_ +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#define PB_DS_CLASS_NAME \ + bin_search_tree_no_data_ +#endif + +#define PB_DS_CLASS_C_DEC \ + PB_DS_CLASS_NAME< \ + Key, \ + Mapped, \ + Cmp_Fn, \ + Node_And_It_Traits, \ + Allocator> + +#define PB_DS_TYPES_TRAITS_C_DEC \ + types_traits< \ + Key, \ + Mapped, \ + Allocator, \ + false> + +#ifdef _GLIBCXX_DEBUG +#define PB_DS_MAP_DEBUG_BASE_C_DEC \ + map_debug_base<Key, eq_by_less<Key, Cmp_Fn>, \ + typename Allocator::template rebind<Key>::other::const_reference> +#endif + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_V2F(X) (X).first +#define PB_DS_V2S(X) (X).second +#define PB_DS_EP2VP(X)& ((X)->m_value) +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#define PB_DS_V2F(X) (X) +#define PB_DS_V2S(X) Mapped_Data() +#define PB_DS_EP2VP(X)& ((X)->m_value.first) +#endif + +#ifdef PB_DS_TREE_TRACE +#define PB_DS_TREE_TRACE_BASE_C_DEC \ + tree_trace_base< \ + typename Node_And_It_Traits::const_node_iterator, \ + typename Node_And_It_Traits::node_iterator, \ + Cmp_Fn, \ + true, \ + Allocator> +#endif + + /** + * class description = "8i|\|4ree $34rc|-| 7r33 74813."> + **/ + template<typename Key, + typename Mapped, + class Cmp_Fn, + class Node_And_It_Traits, + class Allocator> + class PB_DS_CLASS_NAME : +#ifdef _GLIBCXX_DEBUG + public PB_DS_MAP_DEBUG_BASE_C_DEC, +#endif +#ifdef PB_DS_TREE_TRACE + public PB_DS_TREE_TRACE_BASE_C_DEC, +#endif + public Cmp_Fn, + public PB_DS_TYPES_TRAITS_C_DEC, + public Node_And_It_Traits::node_update + { + + protected: + typedef + typename Allocator::template rebind< + typename Node_And_It_Traits::node>::other + node_allocator; + + typedef typename node_allocator::value_type node; + + typedef typename node_allocator::pointer node_pointer; + + typedef PB_DS_TYPES_TRAITS_C_DEC traits_base; + + typedef + typename Node_And_It_Traits::null_node_update_pointer + null_node_update_pointer; + + private: + typedef cond_dealtor< node, Allocator> cond_dealtor_t; + +#ifdef _GLIBCXX_DEBUG + typedef PB_DS_MAP_DEBUG_BASE_C_DEC map_debug_base; +#endif + + public: + + typedef typename Allocator::size_type size_type; + + typedef typename Allocator::difference_type difference_type; + + typedef typename PB_DS_TYPES_TRAITS_C_DEC::key_type key_type; + + typedef typename PB_DS_TYPES_TRAITS_C_DEC::key_pointer key_pointer; + + typedef + typename PB_DS_TYPES_TRAITS_C_DEC::const_key_pointer + const_key_pointer; + + typedef typename PB_DS_TYPES_TRAITS_C_DEC::key_reference key_reference; + + typedef + typename PB_DS_TYPES_TRAITS_C_DEC::const_key_reference + const_key_reference; + +#ifdef PB_DS_DATA_TRUE_INDICATOR + typedef typename PB_DS_TYPES_TRAITS_C_DEC::mapped_type mapped_type; + + typedef + typename PB_DS_TYPES_TRAITS_C_DEC::mapped_pointer + mapped_pointer; + + typedef + typename PB_DS_TYPES_TRAITS_C_DEC::const_mapped_pointer + const_mapped_pointer; + + typedef + typename PB_DS_TYPES_TRAITS_C_DEC::mapped_reference + mapped_reference; + + typedef + typename PB_DS_TYPES_TRAITS_C_DEC::const_mapped_reference + const_mapped_reference; +#endif + + typedef typename PB_DS_TYPES_TRAITS_C_DEC::value_type value_type; + + typedef typename PB_DS_TYPES_TRAITS_C_DEC::pointer pointer; + + typedef typename PB_DS_TYPES_TRAITS_C_DEC::const_pointer const_pointer; + + typedef typename PB_DS_TYPES_TRAITS_C_DEC::reference reference; + + typedef + typename PB_DS_TYPES_TRAITS_C_DEC::const_reference + const_reference; + + typedef + typename Node_And_It_Traits::const_point_iterator + const_point_iterator; + + typedef const_point_iterator const_iterator; + + typedef typename Node_And_It_Traits::point_iterator point_iterator; + + typedef point_iterator iterator; + + typedef + typename Node_And_It_Traits::const_reverse_iterator + const_reverse_iterator; + + typedef typename Node_And_It_Traits::reverse_iterator reverse_iterator; + + typedef + typename Node_And_It_Traits::const_node_iterator + const_node_iterator; + + typedef typename Node_And_It_Traits::node_iterator node_iterator; + + typedef Cmp_Fn cmp_fn; + + typedef Allocator allocator; + + typedef typename Node_And_It_Traits::node_update node_update; + + public: + + PB_DS_CLASS_NAME(); + + PB_DS_CLASS_NAME(const Cmp_Fn& r_cmp_fn); + + PB_DS_CLASS_NAME(const Cmp_Fn& r_cmp_fn, const node_update& r_update); + + PB_DS_CLASS_NAME(const PB_DS_CLASS_C_DEC& other); + + void + swap(PB_DS_CLASS_C_DEC& other); + + ~PB_DS_CLASS_NAME(); + + inline bool + empty() const; + + inline size_type + size() const; + + inline size_type + max_size() const; + + Cmp_Fn& + get_cmp_fn(); + + const Cmp_Fn& + get_cmp_fn() const; + + inline point_iterator + lower_bound(const_key_reference r_key); + + inline const_point_iterator + lower_bound(const_key_reference r_key) const; + + inline point_iterator + upper_bound(const_key_reference r_key); + + inline const_point_iterator + upper_bound(const_key_reference r_key) const; + + inline point_iterator + find(const_key_reference r_key); + + inline const_point_iterator + find(const_key_reference r_key) const; + + inline iterator + begin(); + + inline const_iterator + begin() const; + + inline iterator + end(); + + inline const_iterator + end() const; + + inline reverse_iterator + rbegin(); + + inline const_reverse_iterator + rbegin() const; + + inline reverse_iterator + rend(); + + inline const_reverse_iterator + rend() const; + + inline const_node_iterator + node_begin() const; + + inline node_iterator + node_begin(); + + inline const_node_iterator + node_end() const; + + inline node_iterator + node_end(); + + void + clear(); + + protected: + + void + value_swap(PB_DS_CLASS_C_DEC& other); + + void + initialize_min_max(); + + inline iterator + insert_imp_empty(const_reference r_value); + + inline iterator + insert_leaf_new(const_reference r_value, node_pointer p_nd, bool left_nd); + + inline node_pointer + get_new_node_for_leaf_insert(const_reference r_val, false_type); + + inline node_pointer + get_new_node_for_leaf_insert(const_reference r_val, true_type); + + inline void + actual_erase_node(node_pointer p_nd); + + inline std::pair<node_pointer, bool> + erase(node_pointer p_nd); + + inline void + update_min_max_for_erased_node(node_pointer p_nd); + + static void + clear_imp(node_pointer p_nd); + + inline std::pair< + point_iterator, + bool> + insert_leaf(const_reference r_value); + + inline void + rotate_left(node_pointer p_x); + + inline void + rotate_right(node_pointer p_y); + + inline void + rotate_parent(node_pointer p_nd); + + inline void + apply_update(node_pointer p_nd, null_node_update_pointer); + + template<typename Node_Update_> + inline void + apply_update(node_pointer p_nd, Node_Update_* p_update); + + inline void + update_to_top(node_pointer p_nd, null_node_update_pointer); + + template<typename Node_Update_> + inline void + update_to_top(node_pointer p_nd, Node_Update_* p_update); + + bool + join_prep(PB_DS_CLASS_C_DEC& other); + + void + join_finish(PB_DS_CLASS_C_DEC& other); + + bool + split_prep(const_key_reference r_key, PB_DS_CLASS_C_DEC& other); + + void + split_finish(PB_DS_CLASS_C_DEC& other); + + size_type + recursive_count(node_pointer p_nd) const; + +#ifdef _GLIBCXX_DEBUG + void + assert_valid() const; + + void + structure_only_assert_valid() const; + + void + assert_node_consistent(const node_pointer p_nd) const; +#endif + + private: +#ifdef _GLIBCXX_DEBUG + void + assert_iterators() const; + + void + assert_consistent_with_debug_base() const; + + void + assert_node_consistent_with_left(const node_pointer p_nd) const; + + void + assert_node_consistent_with_right(const node_pointer p_nd) const; + + void + assert_consistent_with_debug_base(const node_pointer p_nd) const; + + void + assert_min() const; + + void + assert_min_imp(const node_pointer p_nd) const; + + void + assert_max() const; + + void + assert_max_imp(const node_pointer p_nd) const; + + void + assert_size() const; + + typedef std::pair< const_pointer, const_pointer> node_consistent_t; + + node_consistent_t + assert_node_consistent_(const node_pointer p_nd) const; +#endif + + void + initialize(); + + node_pointer + recursive_copy_node(const node_pointer p_nd); + + protected: + node_pointer m_p_head; + + size_type m_size; + + static node_allocator s_node_allocator; + }; + +#include <ext/pb_ds/detail/bin_search_tree_/constructors_destructor_fn_imps.hpp> +#include <ext/pb_ds/detail/bin_search_tree_/iterators_fn_imps.hpp> +#include <ext/pb_ds/detail/bin_search_tree_/debug_fn_imps.hpp> +#include <ext/pb_ds/detail/bin_search_tree_/insert_fn_imps.hpp> +#include <ext/pb_ds/detail/bin_search_tree_/erase_fn_imps.hpp> +#include <ext/pb_ds/detail/bin_search_tree_/find_fn_imps.hpp> +#include <ext/pb_ds/detail/bin_search_tree_/info_fn_imps.hpp> +#include <ext/pb_ds/detail/bin_search_tree_/split_join_fn_imps.hpp> +#include <ext/pb_ds/detail/bin_search_tree_/rotate_fn_imps.hpp> +#include <ext/pb_ds/detail/bin_search_tree_/policy_access_fn_imps.hpp> + +#undef PB_DS_CLASS_C_DEC + +#undef PB_DS_CLASS_T_DEC + +#undef PB_DS_CLASS_NAME + +#undef PB_DS_TYPES_TRAITS_C_DEC + +#undef PB_DS_MAP_DEBUG_BASE_C_DEC + +#ifdef PB_DS_TREE_TRACE +#undef PB_DS_TREE_TRACE_BASE_C_DEC +#endif + +#undef PB_DS_V2F +#undef PB_DS_EP2VP +#undef PB_DS_V2S + + } // namespace detail +} // namespace pb_ds diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/cond_dtor_entry_dealtor.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/cond_dtor_entry_dealtor.hpp new file mode 100644 index 000000000000..d14d7bfaaa4b --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/cond_dtor_entry_dealtor.hpp @@ -0,0 +1,76 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file cond_dtor_entry_dealtor.hpp + * Contains a binary tree container conditional deallocator + */ + +class bin_search_tree_cond_dtor_entry_dealtor_ +{ +public: + inline + bin_search_tree_cond_dtor_entry_dealtor_(node_pointer p_nd) : m_p_nd(p_nd), + m_no_action_dtor(false) + { } + + inline void + set_no_action_dtor() + { + m_no_action_dtor = true; + } + + inline + ~bin_search_tree_cond_dtor_entry_dealtor_() + { + if (m_no_action_dtor) + return; + + typename Allocator::template rebind<Node>::other(). + deallocate(m_p_nd, 1); + } + +protected: + node_pointer m_p_nd; + + bool m_no_action_dtor; +}; + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/cond_key_dtor_entry_dealtor.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/cond_key_dtor_entry_dealtor.hpp new file mode 100644 index 000000000000..5373e548d3bd --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/cond_key_dtor_entry_dealtor.hpp @@ -0,0 +1,87 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file cond_key_dtor_entry_dealtor.hpp + * Contains a binary tree container conditional deallocator + */ + +class bin_seach_tree_cond_key_dtor_entry_dealtor_ +{ +public: + inline + bin_seach_tree_cond_key_dtor_entry_dealtor_(node_pointer p_nd) : m_p_nd(p_nd), + m_no_action_dtor(false), + m_key_destruct(false) + { } + + inline void + set_no_action_dtor() + { + m_no_action_dtor = true; + } + + inline void + set_key_destruct() + { + m_key_destruct = true; + } + + inline + ~bin_seach_tree_cond_key_dtor_entry_dealtor_() + { + if (m_no_action_dtor) + return; + + if (m_key_destruct) + m_p_nd->m_value.first.~Key(); + + bin_tree_base::s_alloc.deallocate(m_p_nd, 1); + } + +protected: + node_pointer m_p_nd; + + bool m_no_action_dtor; + + bool m_key_destruct; +}; + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/constructors_destructor_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/constructors_destructor_fn_imps.hpp new file mode 100644 index 000000000000..a6ee92001279 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/constructors_destructor_fn_imps.hpp @@ -0,0 +1,224 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructors_destructor_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::node_allocator +PB_DS_CLASS_C_DEC::s_node_allocator; + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME() : m_p_head(s_node_allocator.allocate(1)), m_size(0) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(structure_only_assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const Cmp_Fn& r_cmp_fn) : + Cmp_Fn(r_cmp_fn), m_p_head(s_node_allocator.allocate(1)), m_size(0) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(structure_only_assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const Cmp_Fn& r_cmp_fn, const node_update& r_node_update) : + Cmp_Fn(r_cmp_fn), + node_update(r_node_update), + m_p_head(s_node_allocator.allocate(1)), + m_size(0) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(structure_only_assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const PB_DS_CLASS_C_DEC& other) : +#ifdef _GLIBCXX_DEBUG + map_debug_base(other), +#endif +#ifdef PB_DS_TREE_TRACE + PB_DS_TREE_TRACE_BASE_C_DEC(other), +#endif + Cmp_Fn(other), + node_update(other), + m_p_head(s_node_allocator.allocate(1)), + m_size(0) +{ + initialize(); + m_size = other.m_size; + _GLIBCXX_DEBUG_ONLY(other.structure_only_assert_valid();) + + try + { + m_p_head->m_p_parent = recursive_copy_node(other.m_p_head->m_p_parent); + if (m_p_head->m_p_parent != NULL) + m_p_head->m_p_parent->m_p_parent = m_p_head; + m_size = other.m_size; + initialize_min_max(); + } + catch(...) + { + _GLIBCXX_DEBUG_ONLY(map_debug_base::clear();) + s_node_allocator.deallocate(m_p_head, 1); + __throw_exception_again; + } + _GLIBCXX_DEBUG_ONLY(structure_only_assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(structure_only_assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.structure_only_assert_valid();) + value_swap(other); + std::swap((Cmp_Fn& )(*this), (Cmp_Fn& )other); + _GLIBCXX_DEBUG_ONLY(structure_only_assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.structure_only_assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +value_swap(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(map_debug_base::swap(other);) + std::swap(m_p_head, other.m_p_head); + std::swap(m_size, other.m_size); +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +~PB_DS_CLASS_NAME() +{ + clear(); + s_node_allocator.deallocate(m_p_head, 1); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +initialize() +{ + m_p_head->m_p_parent = NULL; + m_p_head->m_p_left = m_p_head; + m_p_head->m_p_right = m_p_head; + m_size = 0; +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +recursive_copy_node(const node_pointer p_nd) +{ + if (p_nd == NULL) + return (NULL); + + node_pointer p_ret = s_node_allocator.allocate(1); + try + { + new (p_ret) node(*p_nd); + } + catch(...) + { + s_node_allocator.deallocate(p_ret, 1); + __throw_exception_again; + } + + p_ret->m_p_left = p_ret->m_p_right = NULL; + + try + { + p_ret->m_p_left = recursive_copy_node(p_nd->m_p_left); + p_ret->m_p_right = recursive_copy_node(p_nd->m_p_right); + } + catch(...) + { + clear_imp(p_ret); + __throw_exception_again; + } + + if (p_ret->m_p_left != NULL) + p_ret->m_p_left->m_p_parent = p_ret; + + if (p_ret->m_p_right != NULL) + p_ret->m_p_right->m_p_parent = p_ret; + + _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_ret);) + return p_ret; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +initialize_min_max() +{ + if (m_p_head->m_p_parent == NULL) + { + m_p_head->m_p_left = m_p_head->m_p_right = m_p_head; + return; + } + + { + node_pointer p_min = m_p_head->m_p_parent; + while (p_min->m_p_left != NULL) + p_min = p_min->m_p_left; + m_p_head->m_p_left = p_min; + } + + { + node_pointer p_max = m_p_head->m_p_parent; + while (p_max->m_p_right != NULL) + p_max = p_max->m_p_right; + m_p_head->m_p_right = p_max; + } +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/debug_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/debug_fn_imps.hpp new file mode 100644 index 000000000000..eff970a36954 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/debug_fn_imps.hpp @@ -0,0 +1,278 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_valid() const +{ + structure_only_assert_valid(); + assert_consistent_with_debug_base(); + assert_size(); + assert_iterators(); + if (m_p_head->m_p_parent == NULL) + { + _GLIBCXX_DEBUG_ASSERT(m_size == 0); + } + else + { + _GLIBCXX_DEBUG_ASSERT(m_size > 0); + } +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +structure_only_assert_valid() const +{ + _GLIBCXX_DEBUG_ASSERT(m_p_head != NULL); + if (m_p_head->m_p_parent == NULL) + { + _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_left == m_p_head); + _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_right == m_p_head); + } + else + { + _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_parent->m_p_parent == m_p_head); + _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_left != m_p_head); + _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_right != m_p_head); + } + + if (m_p_head->m_p_parent != NULL) + assert_node_consistent(m_p_head->m_p_parent); + assert_min(); + assert_max(); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_node_consistent(const node_pointer p_nd) const +{ + assert_node_consistent_(p_nd); +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::node_consistent_t +PB_DS_CLASS_C_DEC:: +assert_node_consistent_(const node_pointer p_nd) const +{ + if (p_nd == NULL) + return (std::make_pair((const_pointer)NULL,(const_pointer)NULL)); + + assert_node_consistent_with_left(p_nd); + assert_node_consistent_with_right(p_nd); + + const std::pair<const_pointer, const_pointer> + l_range = assert_node_consistent_(p_nd->m_p_left); + + if (l_range.second != NULL) + _GLIBCXX_DEBUG_ASSERT(Cmp_Fn::operator()(PB_DS_V2F(*l_range.second), + PB_DS_V2F(p_nd->m_value))); + + const std::pair<const_pointer, const_pointer> + r_range = assert_node_consistent_(p_nd->m_p_right); + + if (r_range.first != NULL) + _GLIBCXX_DEBUG_ASSERT(Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), + PB_DS_V2F(*r_range.first))); + + return (std::make_pair((l_range.first != NULL)? l_range.first :& p_nd->m_value,(r_range.second != NULL)? r_range.second :& p_nd->m_value)); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_node_consistent_with_left(const node_pointer p_nd) const +{ + if (p_nd->m_p_left == NULL) + return; + _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_left->m_p_parent == p_nd); + _GLIBCXX_DEBUG_ASSERT(!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), + PB_DS_V2F(p_nd->m_p_left->m_value))); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_node_consistent_with_right(const node_pointer p_nd) const +{ + if (p_nd->m_p_right == NULL) + return; + _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_right->m_p_parent == p_nd); + _GLIBCXX_DEBUG_ASSERT(!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_p_right->m_value), + PB_DS_V2F(p_nd->m_value))); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_min() const +{ + assert_min_imp(m_p_head->m_p_parent); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_min_imp(const node_pointer p_nd) const +{ + if (p_nd == NULL) + { + _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_left == m_p_head); + return; + } + + if (p_nd->m_p_left == NULL) + { + _GLIBCXX_DEBUG_ASSERT(p_nd == m_p_head->m_p_left); + return; + } + assert_min_imp(p_nd->m_p_left); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_max() const +{ + assert_max_imp(m_p_head->m_p_parent); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_max_imp(const node_pointer p_nd) const +{ + if (p_nd == NULL) + { + _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_right == m_p_head); + return; + } + + if (p_nd->m_p_right == NULL) + { + _GLIBCXX_DEBUG_ASSERT(p_nd == m_p_head->m_p_right); + return; + } + + assert_max_imp(p_nd->m_p_right); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_iterators() const +{ + size_type iterated_num = 0; + const_iterator prev_it = end(); + for (const_iterator it = begin(); it != end(); ++it) + { + ++iterated_num; + _GLIBCXX_DEBUG_ASSERT(lower_bound(PB_DS_V2F(*it)).m_p_nd == it.m_p_nd); + const_iterator upper_bound_it = upper_bound(PB_DS_V2F(*it)); + --upper_bound_it; + _GLIBCXX_DEBUG_ASSERT(upper_bound_it.m_p_nd == it.m_p_nd); + + if (prev_it != end()) + _GLIBCXX_DEBUG_ASSERT(Cmp_Fn::operator()(PB_DS_V2F(*prev_it), + PB_DS_V2F(*it))); + prev_it = it; + } + + _GLIBCXX_DEBUG_ASSERT(iterated_num == m_size); + size_type reverse_iterated_num = 0; + const_reverse_iterator reverse_prev_it = rend(); + for (const_reverse_iterator reverse_it = rbegin(); reverse_it != rend(); + ++reverse_it) + { + ++reverse_iterated_num; + _GLIBCXX_DEBUG_ASSERT(lower_bound( + PB_DS_V2F(*reverse_it)).m_p_nd == reverse_it.m_p_nd); + + const_iterator upper_bound_it = upper_bound(PB_DS_V2F(*reverse_it)); + --upper_bound_it; + _GLIBCXX_DEBUG_ASSERT(upper_bound_it.m_p_nd == reverse_it.m_p_nd); + if (reverse_prev_it != rend()) + _GLIBCXX_DEBUG_ASSERT(!Cmp_Fn::operator()(PB_DS_V2F(*reverse_prev_it), + PB_DS_V2F(*reverse_it))); + reverse_prev_it = reverse_it; + } + _GLIBCXX_DEBUG_ASSERT(reverse_iterated_num == m_size); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_consistent_with_debug_base() const +{ + map_debug_base::check_size(m_size); + assert_consistent_with_debug_base(m_p_head->m_p_parent); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_consistent_with_debug_base(const node_pointer p_nd) const +{ + if (p_nd == NULL) + return; + map_debug_base::check_key_exists(PB_DS_V2F(p_nd->m_value)); + assert_consistent_with_debug_base(p_nd->m_p_left); + assert_consistent_with_debug_base(p_nd->m_p_right); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_size() const +{ + _GLIBCXX_DEBUG_ASSERT(recursive_count(m_p_head->m_p_parent) == m_size); +} + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/erase_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/erase_fn_imps.hpp new file mode 100644 index 000000000000..2006a82b6806 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/erase_fn_imps.hpp @@ -0,0 +1,126 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file erase_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +actual_erase_node(node_pointer p_z) +{ + _GLIBCXX_DEBUG_ASSERT(m_size > 0); + --m_size; + + _GLIBCXX_DEBUG_ONLY(erase_existing(PB_DS_V2F(p_z->m_value))); + + p_z->~node(); + + s_node_allocator.deallocate(p_z, 1); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +update_min_max_for_erased_node(node_pointer p_z) +{ + if (m_size == 1) + { + m_p_head->m_p_left = m_p_head->m_p_right = m_p_head; + + return; + } + + if (m_p_head->m_p_left == p_z) + { + iterator it(p_z); + + ++it; + + m_p_head->m_p_left = it.m_p_nd; + } + else if (m_p_head->m_p_right == p_z) + { + iterator it(p_z); + + --it; + + m_p_head->m_p_right = it.m_p_nd; + } +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +clear() +{ + _GLIBCXX_DEBUG_ONLY(structure_only_assert_valid();) + + clear_imp(m_p_head->m_p_parent); + + m_size = 0; + + initialize(); + + _GLIBCXX_DEBUG_ONLY(map_debug_base::clear();) + + _GLIBCXX_DEBUG_ONLY(structure_only_assert_valid();) + } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +clear_imp(node_pointer p_nd) +{ + if (p_nd == NULL) + return; + + clear_imp(p_nd->m_p_left); + + clear_imp(p_nd->m_p_right); + + p_nd->~node(); + + s_node_allocator.deallocate(p_nd, 1); +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/find_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/find_fn_imps.hpp new file mode 100644 index 000000000000..5f534d1c753c --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/find_fn_imps.hpp @@ -0,0 +1,188 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file find_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_point_iterator +PB_DS_CLASS_C_DEC:: +lower_bound(const_key_reference r_key) const +{ + node_pointer p_pot = m_p_head; + node_pointer p_nd = m_p_head->m_p_parent; + + while (p_nd != NULL) + if (Cmp_Fn::operator()( + PB_DS_V2F(p_nd->m_value), + r_key)) + p_nd = p_nd->m_p_right; + else + { + p_pot = p_nd; + + p_nd = p_nd->m_p_left; + } + + return (iterator(p_pot)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::point_iterator +PB_DS_CLASS_C_DEC:: +lower_bound(const_key_reference r_key) +{ + node_pointer p_pot = m_p_head; + node_pointer p_nd = m_p_head->m_p_parent; + + while (p_nd != NULL) + if (Cmp_Fn::operator()( + PB_DS_V2F(p_nd->m_value), + r_key)) + p_nd = p_nd->m_p_right; + else + { + p_pot = p_nd; + + p_nd = p_nd->m_p_left; + } + + return (iterator(p_pot)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_point_iterator +PB_DS_CLASS_C_DEC:: +upper_bound(const_key_reference r_key) const +{ + node_pointer p_pot = m_p_head; + node_pointer p_nd = m_p_head->m_p_parent; + + while (p_nd != NULL) + if (Cmp_Fn::operator()(r_key, + PB_DS_V2F(p_nd->m_value))) + { + p_pot = p_nd, + + p_nd = p_nd->m_p_left; + } + else + p_nd = p_nd->m_p_right; + + return (const_iterator(p_pot)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::point_iterator +PB_DS_CLASS_C_DEC:: +upper_bound(const_key_reference r_key) +{ + node_pointer p_pot = m_p_head; + node_pointer p_nd = m_p_head->m_p_parent; + + while (p_nd != NULL) + if (Cmp_Fn::operator()(r_key, + PB_DS_V2F(p_nd->m_value))) + { + p_pot = p_nd, + + p_nd = p_nd->m_p_left; + } + else + p_nd = p_nd->m_p_right; + + return (point_iterator(p_pot)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::point_iterator +PB_DS_CLASS_C_DEC:: +find(const_key_reference r_key) +{ + _GLIBCXX_DEBUG_ONLY(structure_only_assert_valid();) + + node_pointer p_pot = m_p_head; + node_pointer p_nd = m_p_head->m_p_parent; + + while (p_nd != NULL) + if (!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), r_key)) + { + p_pot = p_nd; + + p_nd = p_nd->m_p_left; + } + else + p_nd = p_nd->m_p_right; + + return point_iterator((p_pot != m_p_head&& Cmp_Fn::operator()( + r_key, + PB_DS_V2F(p_pot->m_value)))? + m_p_head : p_pot); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_point_iterator +PB_DS_CLASS_C_DEC:: +find(const_key_reference r_key) const +{ + _GLIBCXX_DEBUG_ONLY(structure_only_assert_valid();) + + node_pointer p_pot = m_p_head; + node_pointer p_nd = m_p_head->m_p_parent; + + while (p_nd != NULL) + if (!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), r_key)) + { + p_pot = p_nd; + + p_nd = p_nd->m_p_left; + } + else + p_nd = p_nd->m_p_right; + + return const_point_iterator((p_pot != m_p_head&& Cmp_Fn::operator()( + r_key, + PB_DS_V2F(p_pot->m_value)))? + m_p_head : p_pot); +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/info_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/info_fn_imps.hpp new file mode 100644 index 000000000000..4381efe3dc5d --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/info_fn_imps.hpp @@ -0,0 +1,70 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file info_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +empty() const +{ + return (m_size == 0); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +size() const +{ + return (m_size); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +max_size() const +{ + return (s_node_allocator.max_size()); +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/insert_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/insert_fn_imps.hpp new file mode 100644 index 000000000000..91fe41ab9d26 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/insert_fn_imps.hpp @@ -0,0 +1,217 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file insert_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +inline std::pair<typename PB_DS_CLASS_C_DEC::point_iterator, bool> +PB_DS_CLASS_C_DEC:: +insert_leaf(const_reference r_value) +{ + _GLIBCXX_DEBUG_ONLY(structure_only_assert_valid();) + + if (m_size == 0) + return (std::make_pair( + insert_imp_empty(r_value), + true)); + + node_pointer p_nd = m_p_head->m_p_parent; + node_pointer p_pot = m_p_head; + + while (p_nd != NULL) + if (!Cmp_Fn::operator()( + PB_DS_V2F(p_nd->m_value), + PB_DS_V2F(r_value))) + { + p_pot = p_nd; + + p_nd = p_nd->m_p_left; + } + else + p_nd = p_nd->m_p_right; + + if (p_pot == m_p_head) + return (std::make_pair( + insert_leaf_new(r_value, m_p_head->m_p_right, false), + true)); + + if (!Cmp_Fn::operator()( + PB_DS_V2F(r_value), + PB_DS_V2F(p_pot->m_value))) + { + _GLIBCXX_DEBUG_ONLY(structure_only_assert_valid();) + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists( + PB_DS_V2F(r_value))); + + return (std::make_pair(p_pot, false)); + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist( + PB_DS_V2F(r_value))); + + p_nd = p_pot->m_p_left; + if (p_nd == NULL) + return (std::make_pair( + insert_leaf_new(r_value, p_pot, true), + true)); + + while (p_nd->m_p_right != NULL) + p_nd = p_nd->m_p_right; + + return (std::make_pair( + insert_leaf_new(r_value, p_nd, false), + true)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +insert_leaf_new(const_reference r_value, node_pointer p_nd, bool left_nd) +{ + node_pointer p_new_nd = + get_new_node_for_leaf_insert( r_value, traits_base::m_no_throw_copies_indicator); + + if (left_nd) + { + _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_left == NULL); + _GLIBCXX_DEBUG_ASSERT(Cmp_Fn::operator()( + PB_DS_V2F(r_value), + PB_DS_V2F(p_nd->m_value))); + + p_nd->m_p_left = p_new_nd; + + if (m_p_head->m_p_left == p_nd) + m_p_head->m_p_left = p_new_nd; + } + else + { + _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_right == NULL); + _GLIBCXX_DEBUG_ASSERT(Cmp_Fn::operator()( + PB_DS_V2F(p_nd->m_value), + PB_DS_V2F(r_value))); + + p_nd->m_p_right = p_new_nd; + + if (m_p_head->m_p_right == p_nd) + m_p_head->m_p_right = p_new_nd; + } + + p_new_nd->m_p_parent = p_nd; + + p_new_nd->m_p_left = p_new_nd->m_p_right = NULL; + + _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_nd)); + + update_to_top(p_new_nd, (node_update* )this); + + _GLIBCXX_DEBUG_ONLY(map_debug_base::insert_new( + PB_DS_V2F(r_value))); + + return (iterator(p_new_nd)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +insert_imp_empty(const_reference r_value) +{ + node_pointer p_new_node = + get_new_node_for_leaf_insert( r_value, traits_base::m_no_throw_copies_indicator); + + m_p_head->m_p_left = m_p_head->m_p_right = + m_p_head->m_p_parent = p_new_node; + + p_new_node->m_p_parent = m_p_head; + + p_new_node->m_p_left = p_new_node->m_p_right = NULL; + + _GLIBCXX_DEBUG_ONLY(map_debug_base::insert_new( + PB_DS_V2F(r_value))); + + update_to_top(m_p_head->m_p_parent, (node_update* )this); + + return (iterator(p_new_node)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +get_new_node_for_leaf_insert(const_reference r_val, false_type) +{ + node_pointer p_new_nd = s_node_allocator.allocate(1); + + cond_dealtor_t cond(p_new_nd); + + new (const_cast<void* >( + static_cast<const void* >(&p_new_nd->m_value))) + typename node::value_type(r_val); + + cond.set_no_action(); + + p_new_nd->m_p_left = p_new_nd->m_p_right = NULL; + + ++m_size; + + return (p_new_nd); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +get_new_node_for_leaf_insert(const_reference r_val, true_type) +{ + node_pointer p_new_nd = s_node_allocator.allocate(1); + + new (const_cast<void* >( + static_cast<const void* >(&p_new_nd->m_value))) + typename node::value_type(r_val); + + p_new_nd->m_p_left = p_new_nd->m_p_right = NULL; + + ++m_size; + + return (p_new_nd); +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/iterators_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/iterators_fn_imps.hpp new file mode 100644 index 000000000000..3132a4237214 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/iterators_fn_imps.hpp @@ -0,0 +1,142 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file iterators_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +begin() +{ + return (iterator(m_p_head->m_p_left)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +begin() const +{ + return (const_iterator(m_p_head->m_p_left)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +end() +{ + return (iterator(m_p_head)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +end() const +{ + return (const_iterator(m_p_head)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_reverse_iterator +PB_DS_CLASS_C_DEC:: +rbegin() const +{ + return (const_reverse_iterator(m_p_head->m_p_right)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::reverse_iterator +PB_DS_CLASS_C_DEC:: +rbegin() +{ + return (reverse_iterator(m_p_head->m_p_right)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::reverse_iterator +PB_DS_CLASS_C_DEC:: +rend() +{ + return (reverse_iterator(m_p_head)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_reverse_iterator +PB_DS_CLASS_C_DEC:: +rend() const +{ + return (const_reverse_iterator(m_p_head)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_node_iterator +PB_DS_CLASS_C_DEC:: +node_begin() const +{ + return (const_node_iterator(m_p_head->m_p_parent)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_iterator +PB_DS_CLASS_C_DEC:: +node_begin() +{ + return (node_iterator(m_p_head->m_p_parent)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_node_iterator +PB_DS_CLASS_C_DEC:: +node_end() const +{ + return (const_node_iterator(NULL)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_iterator +PB_DS_CLASS_C_DEC:: +node_end() +{ + return (node_iterator(NULL)); +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/node_iterators.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/node_iterators.hpp new file mode 100644 index 000000000000..ce1cd22b0116 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/node_iterators.hpp @@ -0,0 +1,243 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file node_iterators.hpp + * Contains an implementation class for bin_search_tree_. + */ + +#ifndef PB_DS_BIN_SEARCH_TREE_NODE_ITERATORS_HPP +#define PB_DS_BIN_SEARCH_TREE_NODE_ITERATORS_HPP + +#include <ext/pb_ds/tag_and_trait.hpp> + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC \ + bin_search_tree_const_node_it_< \ + Node, \ + Const_Iterator, \ + Iterator, \ + Allocator> + + // Const node iterator. + template<typename Node, + class Const_Iterator, + class Iterator, + class Allocator> + class bin_search_tree_const_node_it_ + { + private: + + private: + typedef + typename Allocator::template rebind< + Node>::other::pointer + node_pointer; + + public: + + // Category. + typedef trivial_iterator_tag iterator_category; + + // Difference type. + typedef trivial_iterator_difference_type difference_type; + + // __Iterator's value type. + typedef Const_Iterator value_type; + + // __Iterator's reference type. + typedef Const_Iterator reference; + + // __Iterator's __const reference type. + typedef Const_Iterator const_reference; + + // Metadata type. + typedef typename Node::metadata_type metadata_type; + + // Const metadata reference type. + typedef + typename Allocator::template rebind< + metadata_type>::other::const_reference + const_metadata_reference; + + public: + + // Default constructor. + /* + inline + bin_search_tree_const_node_it_() + */ + + inline + bin_search_tree_const_node_it_(const node_pointer p_nd = NULL) : m_p_nd(const_cast<node_pointer>(p_nd)) + { } + + // Access. + inline const_reference + operator*() const + { + return (Const_Iterator(m_p_nd)); + } + + // Metadata access. + inline const_metadata_reference + get_metadata() const + { + return (m_p_nd->get_metadata()); + } + + // Returns the __const node iterator associated with the left node. + inline PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC + get_l_child() const + { + return (PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC(m_p_nd->m_p_left)); + } + + // Returns the __const node iterator associated with the right node. + inline PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC + get_r_child() const + { + return (PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC(m_p_nd->m_p_right)); + } + + // Compares to a different iterator object. + inline bool + operator==(const PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC& other) const + { + return (m_p_nd == other.m_p_nd); + } + + // Compares (negatively) to a different iterator object. + inline bool + operator!=(const PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC& other) const + { + return (m_p_nd != other.m_p_nd); + } + + public: + node_pointer m_p_nd; + }; + +#define PB_DS_TREE_NODE_ITERATOR_CLASS_C_DEC \ + bin_search_tree_node_it_< \ + Node, \ + Const_Iterator, \ + Iterator, \ + Allocator> + + // Node iterator. + template<typename Node, + class Const_Iterator, + class Iterator, + class Allocator> + class bin_search_tree_node_it_ : + public PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC + + { + + private: + typedef + typename Allocator::template rebind< + Node>::other::pointer + node_pointer; + + public: + + // __Iterator's value type. + typedef Iterator value_type; + + // __Iterator's reference type. + typedef Iterator reference; + + // __Iterator's __const reference type. + typedef Iterator const_reference; + + public: + + // Default constructor. + /* + inline + bin_search_tree_node_it_(); + */ + + inline + bin_search_tree_node_it_(const node_pointer p_nd = NULL) : PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC( + const_cast<node_pointer>(p_nd)) + { } + + // Access. + inline Iterator + operator*() const + { + return (Iterator(PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC::m_p_nd)); + } + + // Returns the node iterator associated with the left node. + inline PB_DS_TREE_NODE_ITERATOR_CLASS_C_DEC + get_l_child() const + { + return (PB_DS_TREE_NODE_ITERATOR_CLASS_C_DEC( + PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC::m_p_nd->m_p_left)); + } + + // Returns the node iterator associated with the right node. + inline PB_DS_TREE_NODE_ITERATOR_CLASS_C_DEC + get_r_child() const + { + return (PB_DS_TREE_NODE_ITERATOR_CLASS_C_DEC( + PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC::m_p_nd->m_p_right)); + } + + }; + +#undef PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC + +#undef PB_DS_TREE_NODE_ITERATOR_CLASS_C_DEC + + } // namespace detail +} // namespace pb_ds + +#endif // #ifndef PB_DS_BIN_SEARCH_TREE_NODE_ITERATORS_HPP + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/point_iterators.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/point_iterators.hpp new file mode 100644 index 000000000000..275177e10e09 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/point_iterators.hpp @@ -0,0 +1,387 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file point_iterators.hpp + * Contains an implementation class for bin_search_tree_. + */ + +#ifndef PB_DS_BIN_SEARCH_TREE_FIND_ITERATORS_HPP +#define PB_DS_BIN_SEARCH_TREE_FIND_ITERATORS_HPP + +#include <ext/pb_ds/tag_and_trait.hpp> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_TREE_CONST_IT_C_DEC \ + bin_search_tree_const_it_< \ + Node_Pointer, \ + Value_Type, \ + Pointer, \ + Const_Pointer, \ + Reference, \ + Const_Reference, \ + Is_Forward_Iterator, \ + Allocator> + +#define PB_DS_TREE_CONST_ODIR_IT_C_DEC \ + bin_search_tree_const_it_< \ + Node_Pointer, \ + Value_Type, \ + Pointer, \ + Const_Pointer, \ + Reference, \ + Const_Reference, \ + !Is_Forward_Iterator, \ + Allocator> + +#define PB_DS_TREE_IT_C_DEC \ + bin_search_tree_it_< \ + Node_Pointer, \ + Value_Type, \ + Pointer, \ + Const_Pointer, \ + Reference, \ + Const_Reference, \ + Is_Forward_Iterator, \ + Allocator> + +#define PB_DS_TREE_ODIR_IT_C_DEC \ + bin_search_tree_it_< \ + Node_Pointer, \ + Value_Type, \ + Pointer, \ + Const_Pointer, \ + Reference, \ + Const_Reference, \ + !Is_Forward_Iterator, \ + Allocator> + + // Const iterator. + template<typename Node_Pointer, + typename Value_Type, + typename Pointer, + typename Const_Pointer, + typename Reference, + typename Const_Reference, + bool Is_Forward_Iterator, + class Allocator> + class bin_search_tree_const_it_ + { + + public: + + typedef std::bidirectional_iterator_tag iterator_category; + + typedef typename Allocator::difference_type difference_type; + + typedef Value_Type value_type; + + typedef Pointer pointer; + + typedef Const_Pointer const_pointer; + + typedef Reference reference; + + typedef Const_Reference const_reference; + + public: + + inline + bin_search_tree_const_it_(const Node_Pointer p_nd = NULL) + : m_p_nd(const_cast<Node_Pointer>(p_nd)) + { } + + inline + bin_search_tree_const_it_(const PB_DS_TREE_CONST_ODIR_IT_C_DEC& other) + : m_p_nd(other.m_p_nd) + { } + + inline + PB_DS_TREE_CONST_IT_C_DEC& + operator=(const PB_DS_TREE_CONST_IT_C_DEC& other) + { + m_p_nd = other.m_p_nd; + return *this; + } + + inline + PB_DS_TREE_CONST_IT_C_DEC& + operator=(const PB_DS_TREE_CONST_ODIR_IT_C_DEC& other) + { + m_p_nd = other.m_p_nd; + return *this; + } + + inline const_pointer + operator->() const + { + _GLIBCXX_DEBUG_ASSERT(m_p_nd != NULL); + return &m_p_nd->m_value; + } + + inline const_reference + operator*() const + { + _GLIBCXX_DEBUG_ASSERT(m_p_nd != NULL); + return m_p_nd->m_value; + } + + inline bool + operator==(const PB_DS_TREE_CONST_IT_C_DEC & other) const + { return m_p_nd == other.m_p_nd; } + + inline bool + operator==(const PB_DS_TREE_CONST_ODIR_IT_C_DEC & other) const + { return m_p_nd == other.m_p_nd; } + + inline bool + operator!=(const PB_DS_TREE_CONST_IT_C_DEC& other) const + { return m_p_nd != other.m_p_nd; } + + inline bool + operator!=(const PB_DS_TREE_CONST_ODIR_IT_C_DEC& other) const + { return m_p_nd != other.m_p_nd; } + + inline PB_DS_TREE_CONST_IT_C_DEC& + operator++() + { + _GLIBCXX_DEBUG_ASSERT(m_p_nd != NULL); + inc(integral_constant<int,Is_Forward_Iterator>()); + return *this; + } + + inline PB_DS_TREE_CONST_IT_C_DEC + operator++(int) + { + PB_DS_TREE_CONST_IT_C_DEC ret_it(m_p_nd); + operator++(); + return ret_it; + } + + inline PB_DS_TREE_CONST_IT_C_DEC& + operator--() + { + dec(integral_constant<int,Is_Forward_Iterator>()); + return *this; + } + + inline PB_DS_TREE_CONST_IT_C_DEC + operator--(int) + { + PB_DS_TREE_CONST_IT_C_DEC ret_it(m_p_nd); + operator--(); + return ret_it; + } + + protected: + inline void + inc(false_type) + { dec(true_type()); } + + void + inc(true_type) + { + if (m_p_nd->special()&& + m_p_nd->m_p_parent->m_p_parent == m_p_nd) + { + m_p_nd = m_p_nd->m_p_left; + return; + } + + if (m_p_nd->m_p_right != NULL) + { + m_p_nd = m_p_nd->m_p_right; + while (m_p_nd->m_p_left != NULL) + m_p_nd = m_p_nd->m_p_left; + return; + } + + Node_Pointer p_y = m_p_nd->m_p_parent; + while (m_p_nd == p_y->m_p_right) + { + m_p_nd = p_y; + p_y = p_y->m_p_parent; + } + + if (m_p_nd->m_p_right != p_y) + m_p_nd = p_y; + } + + inline void + dec(false_type) + { inc(true_type()); } + + void + dec(true_type) + { + if (m_p_nd->special() && m_p_nd->m_p_parent->m_p_parent == m_p_nd) + { + m_p_nd = m_p_nd->m_p_right; + return; + } + + if (m_p_nd->m_p_left != NULL) + { + Node_Pointer p_y = m_p_nd->m_p_left; + while (p_y->m_p_right != NULL) + p_y = p_y->m_p_right; + m_p_nd = p_y; + return; + } + + Node_Pointer p_y = m_p_nd->m_p_parent; + while (m_p_nd == p_y->m_p_left) + { + m_p_nd = p_y; + p_y = p_y->m_p_parent; + } + if (m_p_nd->m_p_left != p_y) + m_p_nd = p_y; + } + + public: + Node_Pointer m_p_nd; + }; + + // Iterator. + template<typename Node_Pointer, + typename Value_Type, + typename Pointer, + typename Const_Pointer, + typename Reference, + typename Const_Reference, + bool Is_Forward_Iterator, + class Allocator> + class bin_search_tree_it_ : + public PB_DS_TREE_CONST_IT_C_DEC + + { + + public: + + inline + bin_search_tree_it_(const Node_Pointer p_nd = NULL) + : PB_DS_TREE_CONST_IT_C_DEC((Node_Pointer)p_nd) + { } + + inline + bin_search_tree_it_(const PB_DS_TREE_ODIR_IT_C_DEC& other) + : PB_DS_TREE_CONST_IT_C_DEC(other.m_p_nd) + { } + + inline + PB_DS_TREE_IT_C_DEC& + operator=(const PB_DS_TREE_IT_C_DEC& other) + { + base_it_type::m_p_nd = other.m_p_nd; + return *this; + } + + inline + PB_DS_TREE_IT_C_DEC& + operator=(const PB_DS_TREE_ODIR_IT_C_DEC& other) + { + base_it_type::m_p_nd = other.m_p_nd; + return *this; + } + + inline typename PB_DS_TREE_CONST_IT_C_DEC::pointer + operator->() const + { + _GLIBCXX_DEBUG_ASSERT(base_it_type::m_p_nd != NULL); + return &base_it_type::m_p_nd->m_value; + } + + inline typename PB_DS_TREE_CONST_IT_C_DEC::reference + operator*() const + { + _GLIBCXX_DEBUG_ASSERT(base_it_type::m_p_nd != NULL); + return base_it_type::m_p_nd->m_value; + } + + inline PB_DS_TREE_IT_C_DEC& + operator++() + { + PB_DS_TREE_CONST_IT_C_DEC:: operator++(); + return *this; + } + + inline PB_DS_TREE_IT_C_DEC + operator++(int) + { + PB_DS_TREE_IT_C_DEC ret_it(base_it_type::m_p_nd); + operator++(); + return ret_it; + } + + inline PB_DS_TREE_IT_C_DEC& + operator--() + { + PB_DS_TREE_CONST_IT_C_DEC:: operator--(); + return *this; + } + + inline PB_DS_TREE_IT_C_DEC + operator--(int) + { + PB_DS_TREE_IT_C_DEC ret_it(base_it_type::m_p_nd); + operator--(); + return ret_it; + } + + protected: + typedef PB_DS_TREE_CONST_IT_C_DEC base_it_type; + }; + +#undef PB_DS_TREE_CONST_IT_C_DEC +#undef PB_DS_TREE_CONST_ODIR_IT_C_DEC +#undef PB_DS_TREE_IT_C_DEC +#undef PB_DS_TREE_ODIR_IT_C_DEC + + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/policy_access_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/policy_access_fn_imps.hpp new file mode 100644 index 000000000000..eadb47824777 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/policy_access_fn_imps.hpp @@ -0,0 +1,62 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file policy_access_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +Cmp_Fn& +PB_DS_CLASS_C_DEC:: +get_cmp_fn() +{ + return (*this); +} + +PB_DS_CLASS_T_DEC +const Cmp_Fn& +PB_DS_CLASS_C_DEC:: +get_cmp_fn() const +{ + return (*this); +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/r_erase_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/r_erase_fn_imps.hpp new file mode 100644 index 000000000000..2bad9795b2bd --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/r_erase_fn_imps.hpp @@ -0,0 +1,126 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file r_erase_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +actual_erase_node(node_pointer p_z) +{ + _GLIBCXX_DEBUG_ASSERT(m_size > 0); + --m_size; + + _GLIBCXX_DEBUG_ONLY(erase_existing(PB_DS_V2F(p_z->m_value))); + + p_z->~node(); + + s_node_allocator.deallocate(p_z, 1); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +update_min_max_for_erased_node(node_pointer p_z) +{ + if (m_size == 1) + { + m_p_head->m_p_left = m_p_head->m_p_right = m_p_head; + + return; + } + + if (m_p_head->m_p_left == p_z) + { + iterator it(p_z); + + ++it; + + m_p_head->m_p_left = it.m_p_nd; + } + else if (m_p_head->m_p_right == p_z) + { + iterator it(p_z); + + --it; + + m_p_head->m_p_right = it.m_p_nd; + } +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +clear() +{ + _GLIBCXX_DEBUG_ONLY(structure_only_assert_valid();) + + clear_imp(m_p_head->m_p_parent); + + m_size = 0; + + initialize(); + + _GLIBCXX_DEBUG_ONLY(map_debug_base::clear();) + + _GLIBCXX_DEBUG_ONLY(structure_only_assert_valid();) + } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +clear_imp(node_pointer p_nd) +{ + if (p_nd == NULL) + return; + + clear_imp(p_nd->m_p_left); + + clear_imp(p_nd->m_p_right); + + p_nd->~Node(); + + s_node_allocator.deallocate(p_nd, 1); +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/rotate_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/rotate_fn_imps.hpp new file mode 100644 index 000000000000..4e32aae637f3 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/rotate_fn_imps.hpp @@ -0,0 +1,162 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file rotate_fn_imps.hpp + * Contains imps for rotating nodes. + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +rotate_left(node_pointer p_x) +{ + node_pointer p_y = p_x->m_p_right; + + p_x->m_p_right = p_y->m_p_left; + + if (p_y->m_p_left != NULL) + p_y->m_p_left->m_p_parent = p_x; + + p_y->m_p_parent = p_x->m_p_parent; + + if (p_x == m_p_head->m_p_parent) + m_p_head->m_p_parent = p_y; + else if (p_x == p_x->m_p_parent->m_p_left) + p_x->m_p_parent->m_p_left = p_y; + else + p_x->m_p_parent->m_p_right = p_y; + + p_y->m_p_left = p_x; + p_x->m_p_parent = p_y; + + _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_x);) + _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_y);) + + apply_update(p_x, (node_update* )this); + apply_update(p_x->m_p_parent, (node_update* )this); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +rotate_right(node_pointer p_x) +{ + node_pointer p_y = p_x->m_p_left; + + p_x->m_p_left = p_y->m_p_right; + + if (p_y->m_p_right != NULL) + p_y->m_p_right->m_p_parent = p_x; + + p_y->m_p_parent = p_x->m_p_parent; + + if (p_x == m_p_head->m_p_parent) + m_p_head->m_p_parent = p_y; + else if (p_x == p_x->m_p_parent->m_p_right) + p_x->m_p_parent->m_p_right = p_y; + else + p_x->m_p_parent->m_p_left = p_y; + + p_y->m_p_right = p_x; + p_x->m_p_parent = p_y; + + _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_x);) + _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_y);) + + apply_update(p_x, (node_update* )this); + apply_update(p_x->m_p_parent, (node_update* )this); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +rotate_parent(node_pointer p_nd) +{ + node_pointer p_parent = p_nd->m_p_parent; + + if (p_nd == p_parent->m_p_left) + rotate_right(p_parent); + else + rotate_left(p_parent); + + _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_parent = p_nd); + _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_left == p_parent || + p_nd->m_p_right == p_parent); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +apply_update(node_pointer /*p_nd*/, null_node_update_pointer /*p_update*/) +{ } + +PB_DS_CLASS_T_DEC +template<typename Node_Update_> +inline void +PB_DS_CLASS_C_DEC:: +apply_update(node_pointer p_nd, Node_Update_* /*p_update*/) +{ + node_update::operator()( + node_iterator(p_nd), + const_node_iterator(static_cast<node_pointer>(NULL))); +} + +PB_DS_CLASS_T_DEC +template<typename Node_Update_> +inline void +PB_DS_CLASS_C_DEC:: +update_to_top(node_pointer p_nd, Node_Update_* p_update) +{ + while (p_nd != m_p_head) + { + apply_update(p_nd, p_update); + + p_nd = p_nd->m_p_parent; + } +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +update_to_top(node_pointer /*p_nd*/, null_node_update_pointer /*p_update*/) +{ } + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/split_join_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/split_join_fn_imps.hpp new file mode 100644 index 000000000000..2c8e77dedf52 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/split_join_fn_imps.hpp @@ -0,0 +1,152 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file split_join_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +bool +PB_DS_CLASS_C_DEC:: +join_prep(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + if (other.m_size == 0) + return false; + + if (m_size == 0) + { + value_swap(other); + return false; + } + + const bool greater = Cmp_Fn::operator()(PB_DS_V2F(m_p_head->m_p_right->m_value), PB_DS_V2F(other.m_p_head->m_p_left->m_value)); + + const bool lesser = Cmp_Fn::operator()(PB_DS_V2F(other.m_p_head->m_p_right->m_value), PB_DS_V2F(m_p_head->m_p_left->m_value)); + + if (!greater && !lesser) + __throw_join_error(); + + if (lesser) + value_swap(other); + + m_size += other.m_size; + _GLIBCXX_DEBUG_ONLY(map_debug_base::join(other);) + return true; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +join_finish(PB_DS_CLASS_C_DEC& other) +{ + initialize_min_max(); + other.initialize(); +} + +PB_DS_CLASS_T_DEC +bool +PB_DS_CLASS_C_DEC:: +split_prep(const_key_reference r_key, PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + other.clear(); + + if (m_size == 0) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + return false; + } + + if (Cmp_Fn::operator()(r_key, PB_DS_V2F(m_p_head->m_p_left->m_value))) + { + value_swap(other); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + return false; + } + + if (!Cmp_Fn::operator()(r_key, PB_DS_V2F(m_p_head->m_p_right->m_value))) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + return false; + } + + if (m_size == 1) + { + value_swap(other); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + return false; + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::split(r_key,(Cmp_Fn& )(*this), other);) + return true; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +split_finish(PB_DS_CLASS_C_DEC& other) +{ + other.initialize_min_max(); + other.m_size = std::distance(other.begin(), other.end()); + m_size -= other.m_size; + initialize_min_max(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +recursive_count(node_pointer p) const +{ + if (p == NULL) + return 0; + return 1 + recursive_count(p->m_p_left) + recursive_count(p->m_p_right); +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/traits.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/traits.hpp new file mode 100644 index 000000000000..4c57608cc56f --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/bin_search_tree_/traits.hpp @@ -0,0 +1,256 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file traits.hpp + * Contains an implementation for bin_search_tree_. + */ + +#ifndef PB_DS_BIN_SEARCH_TREE_NODE_AND_IT_TRAITS_HPP +#define PB_DS_BIN_SEARCH_TREE_NODE_AND_IT_TRAITS_HPP + +#include <ext/pb_ds/detail/bin_search_tree_/point_iterators.hpp> +#include <ext/pb_ds/detail/bin_search_tree_/node_iterators.hpp> + +namespace pb_ds +{ + namespace detail + { + + template<typename Key, + typename Mapped, + class Cmp_Fn, + template<typename Const_Node_Iterator, + class Node_Iterator, + class Cmp_Fn, + class Allocator> + class Node_Update, + class Node, + class Allocator> + struct bin_search_tree_traits + { + private: + typedef + types_traits< + Key, + Mapped, + Allocator, + false> + type_traits; + + public: + typedef Node node; + + typedef + bin_search_tree_const_it_< + typename Allocator::template rebind< + node>::other::pointer, + typename type_traits::value_type, + typename type_traits::pointer, + typename type_traits::const_pointer, + typename type_traits::reference, + typename type_traits::const_reference, + true, + Allocator> + const_point_iterator; + + typedef + bin_search_tree_it_< + typename Allocator::template rebind< + node>::other::pointer, + typename type_traits::value_type, + typename type_traits::pointer, + typename type_traits::const_pointer, + typename type_traits::reference, + typename type_traits::const_reference, + true, + Allocator> + point_iterator; + + typedef + bin_search_tree_const_it_< + typename Allocator::template rebind< + node>::other::pointer, + typename type_traits::value_type, + typename type_traits::pointer, + typename type_traits::const_pointer, + typename type_traits::reference, + typename type_traits::const_reference, + false, + Allocator> + const_reverse_iterator; + + typedef + bin_search_tree_it_< + typename Allocator::template rebind< + node>::other::pointer, + typename type_traits::value_type, + typename type_traits::pointer, + typename type_traits::const_pointer, + typename type_traits::reference, + typename type_traits::const_reference, + false, + Allocator> + reverse_iterator; + + typedef + bin_search_tree_const_node_it_< + Node, + const_point_iterator, + point_iterator, + Allocator> + const_node_iterator; + + typedef + bin_search_tree_node_it_< + Node, + const_point_iterator, + point_iterator, + Allocator> + node_iterator; + + typedef + Node_Update< + const_node_iterator, + node_iterator, + Cmp_Fn, + Allocator> + node_update; + + typedef + pb_ds::null_tree_node_update< + const_node_iterator, + node_iterator, + Cmp_Fn, + Allocator>* + null_node_update_pointer; + }; + + template<typename Key, + class Cmp_Fn, + template<typename Const_Node_Iterator, + class Node_Iterator, + class Cmp_Fn, + class Allocator> + class Node_Update, + class Node, + class Allocator> + struct bin_search_tree_traits< + Key, + null_mapped_type, + Cmp_Fn, + Node_Update, + Node, + Allocator> + { + private: + typedef + types_traits< + Key, + null_mapped_type, + Allocator, + false> + type_traits; + + public: + typedef Node node; + + typedef + bin_search_tree_const_it_< + typename Allocator::template rebind< + node>::other::pointer, + typename type_traits::value_type, + typename type_traits::pointer, + typename type_traits::const_pointer, + typename type_traits::reference, + typename type_traits::const_reference, + true, + Allocator> + const_point_iterator; + + typedef const_point_iterator point_iterator; + + typedef + bin_search_tree_const_it_< + typename Allocator::template rebind< + node>::other::pointer, + typename type_traits::value_type, + typename type_traits::pointer, + typename type_traits::const_pointer, + typename type_traits::reference, + typename type_traits::const_reference, + false, + Allocator> + const_reverse_iterator; + + typedef const_reverse_iterator reverse_iterator; + + typedef + bin_search_tree_const_node_it_< + Node, + const_point_iterator, + point_iterator, + Allocator> + const_node_iterator; + + typedef const_node_iterator node_iterator; + + typedef + Node_Update< + const_node_iterator, + node_iterator, + Cmp_Fn, + Allocator> + node_update; + + typedef + pb_ds::null_tree_node_update< + const_node_iterator, + node_iterator, + Cmp_Fn, + Allocator>* + null_node_update_pointer; + }; + + } // namespace detail +} // namespace pb_ds + +#endif // #ifndef PB_DS_BIN_SEARCH_TREE_NODE_AND_IT_TRAITS_HPP diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/binary_heap_.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/binary_heap_.hpp new file mode 100644 index 000000000000..659b7732866f --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/binary_heap_.hpp @@ -0,0 +1,363 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file binary_heap_.hpp + * Contains an implementation class for a binary heap. + */ + +#ifndef PB_DS_BINARY_HEAP_HPP +#define PB_DS_BINARY_HEAP_HPP + +/* + * Based on CLRS. + */ + +#include <queue> +#include <algorithm> +#include <ext/pb_ds/detail/cond_dealtor.hpp> +#include <ext/pb_ds/detail/cond_dealtor.hpp> +#include <ext/pb_ds/detail/type_utils.hpp> +#include <ext/pb_ds/detail/binary_heap_/entry_cmp.hpp> +#include <ext/pb_ds/detail/binary_heap_/entry_pred.hpp> +#include <ext/pb_ds/detail/binary_heap_/resize_policy.hpp> +#include <ext/pb_ds/detail/binary_heap_/const_point_iterator.hpp> +#include <ext/pb_ds/detail/binary_heap_/const_iterator.hpp> +#ifdef PB_DS_BINARY_HEAP_TRACE_ +#include <iostream> +#endif +#include <ext/pb_ds/detail/type_utils.hpp> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { +#define PB_DS_CLASS_T_DEC \ + template<typename Value_Type, class Cmp_Fn, class Allocator> + +#define PB_DS_CLASS_C_DEC \ + binary_heap_<Value_Type, Cmp_Fn, Allocator> + +#define PB_DS_ENTRY_CMP_DEC \ + entry_cmp<Value_Type, Cmp_Fn, is_simple<Value_Type>::value, Allocator>::type + +#define PB_DS_RESIZE_POLICY_DEC \ + resize_policy<typename Allocator::size_type> + + /** + * class description = "Base class for some types of h3ap$"> + **/ + template<typename Value_Type, class Cmp_Fn, class Allocator> + class binary_heap_ : public PB_DS_ENTRY_CMP_DEC, + public PB_DS_RESIZE_POLICY_DEC + { + + private: + enum + { + simple_value = is_simple<Value_Type>::value + }; + + typedef integral_constant<int, simple_value> no_throw_copies_t; + + typedef + typename Allocator::template rebind< + Value_Type>::other + value_allocator; + + typedef + typename __conditional_type< + simple_value, + Value_Type, + typename value_allocator::pointer>::__type + entry; + + typedef + typename Allocator::template rebind< + entry>::other + entry_allocator; + + typedef typename entry_allocator::pointer entry_pointer; + + typedef typename PB_DS_ENTRY_CMP_DEC entry_cmp; + + typedef PB_DS_RESIZE_POLICY_DEC resize_policy; + + typedef + cond_dealtor< + Value_Type, + Allocator> + cond_dealtor_t; + + public: + + typedef typename Allocator::size_type size_type; + + typedef typename Allocator::difference_type difference_type; + + typedef Value_Type value_type; + + typedef + typename Allocator::template rebind< + value_type>::other::pointer + pointer; + + typedef + typename Allocator::template rebind< + value_type>::other::const_pointer + const_pointer; + + typedef + typename Allocator::template rebind< + value_type>::other::reference + reference; + + typedef + typename Allocator::template rebind< + value_type>::other::const_reference + const_reference; + + typedef + binary_heap_const_point_iterator_< + value_type, + entry, + simple_value, + Allocator> + const_point_iterator; + + typedef const_point_iterator point_iterator; + + typedef + binary_heap_const_iterator_< + value_type, + entry, + simple_value, + Allocator> + const_iterator; + + typedef const_iterator iterator; + + typedef Cmp_Fn cmp_fn; + + typedef Allocator allocator; + + public: + + binary_heap_(); + + binary_heap_(const Cmp_Fn& r_cmp_fn); + + binary_heap_(const PB_DS_CLASS_C_DEC& other); + + void + swap(PB_DS_CLASS_C_DEC& other); + + ~binary_heap_(); + + inline bool + empty() const; + + inline size_type + size() const; + + inline size_type + max_size() const; + + Cmp_Fn& + get_cmp_fn(); + + const Cmp_Fn& + get_cmp_fn() const; + + inline point_iterator + push(const_reference r_val); + + void + modify(point_iterator it, const_reference r_new_val); + + inline const_reference + top() const; + + inline void + pop(); + + inline void + erase(point_iterator it); + + template<typename Pred> + typename PB_DS_CLASS_C_DEC::size_type + erase_if(Pred pred); + + inline static void + erase_at(entry_pointer a_entries, size_type size, false_type); + + inline static void + erase_at(entry_pointer a_entries, size_type size, true_type); + + inline iterator + begin(); + + inline const_iterator + begin() const; + + inline iterator + end(); + + inline const_iterator + end() const; + + void + clear(); + + template<typename Pred> + void + split(Pred pred, PB_DS_CLASS_C_DEC& other); + + void + join(PB_DS_CLASS_C_DEC& other); + +#ifdef PB_DS_BINARY_HEAP_TRACE_ + void + trace() const; +#endif + + protected: + + template<typename It> + void + copy_from_range(It first_it, It last_it); + + private: + + void + value_swap(PB_DS_CLASS_C_DEC& other); + + inline void + insert_value(const_reference r_val, false_type); + + inline void + insert_value(value_type val, true_type); + + inline void + insert_entry(entry e); + + inline void + resize_for_insert_if_needed(); + + inline void + swap_value_imp(entry_pointer p_e, value_type new_val, true_type); + + inline void + swap_value_imp(entry_pointer p_e, const_reference r_new_val, false_type); + + void + fix(entry_pointer p_e); + + inline const_reference + top_imp(true_type) const; + + inline const_reference + top_imp(false_type) const; + + inline static size_type + left_child(size_type i); + + inline static size_type + right_child(size_type i); + + inline static size_type + parent(size_type i); + + inline void + resize_for_erase_if_needed(); + + template<typename Pred> + size_type + partition(Pred pred); + +#ifdef _GLIBCXX_DEBUG + void + assert_valid() const; +#endif + +#ifdef PB_DS_BINARY_HEAP_TRACE_ + void + trace_entry(const entry& r_e, false_type) const; + + void + trace_entry(const entry& r_e, true_type) const; +#endif + + private: + static entry_allocator s_entry_allocator; + + static value_allocator s_value_allocator; + + static no_throw_copies_t s_no_throw_copies_ind; + + size_type m_size; + + size_type m_actual_size; + + entry_pointer m_a_entries; + }; + +#include <ext/pb_ds/detail/binary_heap_/insert_fn_imps.hpp> +#include <ext/pb_ds/detail/binary_heap_/constructors_destructor_fn_imps.hpp> +#include <ext/pb_ds/detail/binary_heap_/iterators_fn_imps.hpp> +#include <ext/pb_ds/detail/binary_heap_/debug_fn_imps.hpp> +#include <ext/pb_ds/detail/binary_heap_/trace_fn_imps.hpp> +#include <ext/pb_ds/detail/binary_heap_/erase_fn_imps.hpp> +#include <ext/pb_ds/detail/binary_heap_/info_fn_imps.hpp> +#include <ext/pb_ds/detail/binary_heap_/find_fn_imps.hpp> +#include <ext/pb_ds/detail/binary_heap_/split_join_fn_imps.hpp> +#include <ext/pb_ds/detail/binary_heap_/policy_access_fn_imps.hpp> + +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_ENTRY_CMP_DEC +#undef PB_DS_RESIZE_POLICY_DEC + + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/const_iterator.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/const_iterator.hpp new file mode 100644 index 000000000000..12b96e766ba0 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/const_iterator.hpp @@ -0,0 +1,158 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file const_iterator.hpp + * Contains an iterator class returned by the table's const find and insert + * methods. + */ + +#ifndef PB_DS_BINARY_HEAP_CONST_ITERATOR_HPP +#define PB_DS_BINARY_HEAP_CONST_ITERATOR_HPP + +#include <ext/pb_ds/detail/binary_heap_/const_point_iterator.hpp> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_CLASS_C_DEC \ + binary_heap_const_iterator_<Value_Type, Entry, Simple, Allocator> + +#define PB_DS_BASE_C_DEC \ + binary_heap_const_point_iterator_<Value_Type, Entry, Simple, Allocator> + + // Const point-type iterator. + template<typename Value_Type, + typename Entry, + bool Simple, + class Allocator> + class binary_heap_const_iterator_ : public PB_DS_BASE_C_DEC + { + + private: + typedef typename PB_DS_BASE_C_DEC::entry_pointer entry_pointer; + + typedef PB_DS_BASE_C_DEC base_type; + + public: + + // Category. + typedef std::forward_iterator_tag iterator_category; + + // Difference type. + typedef typename Allocator::difference_type difference_type; + + // Iterator's value type. + typedef typename base_type::value_type value_type; + + // Iterator's pointer type. + typedef typename base_type::pointer pointer; + + // Iterator's const pointer type. + typedef typename base_type::const_pointer const_pointer; + + // Iterator's reference type. + typedef typename base_type::reference reference; + + // Iterator's const reference type. + typedef typename base_type::const_reference const_reference; + + public: + + inline + binary_heap_const_iterator_(entry_pointer p_e) : base_type(p_e) + { } + + // Default constructor. + inline + binary_heap_const_iterator_() + { } + + // Copy constructor. + inline + binary_heap_const_iterator_(const PB_DS_CLASS_C_DEC& other) : base_type(other) + { } + + // Compares content to a different iterator object. + inline bool + operator==(const PB_DS_CLASS_C_DEC& other) const + { + return base_type::m_p_e == other.m_p_e; + } + + // Compares content (negatively) to a different iterator object. + inline bool + operator!=(const PB_DS_CLASS_C_DEC& other) const + { + return base_type::m_p_e != other.m_p_e; + } + + inline PB_DS_CLASS_C_DEC& + operator++() + { + _GLIBCXX_DEBUG_ASSERT(base_type::m_p_e != NULL); + inc(); + return *this; + } + + inline PB_DS_CLASS_C_DEC + operator++(int) + { + PB_DS_CLASS_C_DEC ret_it(base_type::m_p_e); + operator++(); + return ret_it; + } + + private: + void + inc() + { ++base_type::m_p_e; } + }; + +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_BASE_C_DEC + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/const_point_iterator.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/const_point_iterator.hpp new file mode 100644 index 000000000000..3a50cd6c4b1e --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/const_point_iterator.hpp @@ -0,0 +1,150 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file const_point_iterator.hpp + * Contains an iterator class returned by the table's const find and insert + * methods. + */ + +#ifndef PB_DS_BINARY_HEAP_CONST_FIND_ITERATOR_HPP +#define PB_DS_BINARY_HEAP_CONST_FIND_ITERATOR_HPP + +#include <ext/pb_ds/tag_and_trait.hpp> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { + // Const point-type iterator. + template<typename Value_Type, typename Entry, bool Simple, + typename Allocator> + class binary_heap_const_point_iterator_ + { + protected: + typedef typename Allocator::template rebind<Entry>::other::pointer entry_pointer; + + public: + // Category. + typedef trivial_iterator_tag iterator_category; + + // Difference type. + typedef trivial_iterator_difference_type difference_type; + + // Iterator's value type. + typedef Value_Type value_type; + + // Iterator's pointer type. + typedef typename Allocator::template rebind<value_type>::other::pointer + pointer; + + // Iterator's const pointer type. + typedef + typename Allocator::template rebind<value_type>::other::const_pointer + const_pointer; + + // Iterator's reference type. + typedef + typename Allocator::template rebind<value_type>::other::reference + reference; + + // Iterator's const reference type. + typedef + typename Allocator::template rebind<value_type>::other::const_reference + const_reference; + + inline + binary_heap_const_point_iterator_(entry_pointer p_e) : m_p_e(p_e) + { } + + // Default constructor. + inline + binary_heap_const_point_iterator_() : m_p_e(NULL) { } + + // Copy constructor. + inline + binary_heap_const_point_iterator_(const binary_heap_const_point_iterator_& other) + : m_p_e(other.m_p_e) + { } + + // Access. + inline const_pointer + operator->() const + { + _GLIBCXX_DEBUG_ASSERT(m_p_e != NULL); + return to_ptr(integral_constant<int, Simple>()); + } + + // Access. + inline const_reference + operator*() const + { + _GLIBCXX_DEBUG_ASSERT(m_p_e != NULL); + return *to_ptr(integral_constant<int, Simple>()); + } + + // Compares content to a different iterator object. + inline bool + operator==(const binary_heap_const_point_iterator_& other) const + { return m_p_e == other.m_p_e; } + + // Compares content (negatively) to a different iterator object. + inline bool + operator!=(const binary_heap_const_point_iterator_& other) const + { return m_p_e != other.m_p_e; } + + private: + inline const_pointer + to_ptr(true_type) const + { return m_p_e; } + + inline const_pointer + to_ptr(false_type) const + { return *m_p_e; } + + public: + entry_pointer m_p_e; + }; + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/constructors_destructor_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/constructors_destructor_fn_imps.hpp new file mode 100644 index 000000000000..b43529beeb3d --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/constructors_destructor_fn_imps.hpp @@ -0,0 +1,165 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructors_destructor_fn_imps.hpp + * Contains an implementation class for binary_heap_. + */ + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::entry_allocator +PB_DS_CLASS_C_DEC::s_entry_allocator; + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::value_allocator +PB_DS_CLASS_C_DEC::s_value_allocator; + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::no_throw_copies_t +PB_DS_CLASS_C_DEC::s_no_throw_copies_ind; + +PB_DS_CLASS_T_DEC +template<typename It> +void +PB_DS_CLASS_C_DEC:: +copy_from_range(It first_it, It last_it) +{ + while (first_it != last_it) + { + insert_value(*first_it, s_no_throw_copies_ind); + ++first_it; + } + + std::make_heap(m_a_entries, m_a_entries + m_size, static_cast<entry_cmp& >(*this)); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +binary_heap_() : + m_size(0), + m_actual_size(resize_policy::min_size), + m_a_entries(s_entry_allocator.allocate(m_actual_size)) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +binary_heap_(const Cmp_Fn& r_cmp_fn) : + entry_cmp(r_cmp_fn), + m_size(0), + m_actual_size(resize_policy::min_size), + m_a_entries(s_entry_allocator.allocate(m_actual_size)) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +binary_heap_(const PB_DS_CLASS_C_DEC& other) : + entry_cmp(other), + resize_policy(other), + m_size(0), + m_actual_size(other.m_actual_size), + m_a_entries(s_entry_allocator.allocate(m_actual_size)) +{ + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + _GLIBCXX_DEBUG_ASSERT(m_a_entries != other.m_a_entries); + + const_iterator first_it = other.begin(); + const_iterator last_it = other.end(); + + try + { + while (first_it != last_it) + { + insert_value(*first_it, s_no_throw_copies_ind); + ++first_it; + } + } + catch(...) + { + for (size_type i = 0; i < m_size; ++i) + erase_at(m_a_entries, i, s_no_throw_copies_ind); + + s_entry_allocator.deallocate(m_a_entries, m_actual_size); + __throw_exception_again; + } + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + _GLIBCXX_DEBUG_ASSERT(m_a_entries != other.m_a_entries); + + value_swap(other); + std::swap((entry_cmp& )(*this), (entry_cmp& )other); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +value_swap(PB_DS_CLASS_C_DEC& other) +{ + std::swap(m_a_entries, other.m_a_entries); + std::swap(m_size, other.m_size); + std::swap(m_actual_size, other.m_actual_size); + static_cast<resize_policy*>(this)->swap(other); +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +~binary_heap_() +{ + for (size_type i = 0; i < m_size; ++i) + erase_at(m_a_entries, i, s_no_throw_copies_ind); + s_entry_allocator.deallocate(m_a_entries, m_actual_size); +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/debug_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/debug_fn_imps.hpp new file mode 100644 index 000000000000..198d6608e37a --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/debug_fn_imps.hpp @@ -0,0 +1,78 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_fn_imps.hpp + * Contains an implementation class for a binary_heap. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_valid() const +{ +#ifdef PB_DS_REGRESSION + s_entry_allocator.check_allocated(m_a_entries, m_actual_size); +#endif + + resize_policy::assert_valid(); + _GLIBCXX_DEBUG_ASSERT(m_size <= m_actual_size); + for (size_type i = 0; i < m_size; ++i) + { +#ifdef PB_DS_REGRESSION + s_value_allocator.check_allocated(m_a_entries[i], 1); +#endif + + if (left_child(i) < m_size) + _GLIBCXX_DEBUG_ASSERT(!entry_cmp::operator()(m_a_entries[i], m_a_entries[left_child(i)])); + + _GLIBCXX_DEBUG_ASSERT(parent(left_child(i)) == i); + + if (right_child(i) < m_size) + _GLIBCXX_DEBUG_ASSERT(!entry_cmp::operator()(m_a_entries[i], m_a_entries[right_child(i)])); + + _GLIBCXX_DEBUG_ASSERT(parent(right_child(i)) == i); + } +} + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/entry_cmp.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/entry_cmp.hpp new file mode 100644 index 000000000000..c98dae75cab2 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/entry_cmp.hpp @@ -0,0 +1,99 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file entry_cmp.hpp + * Contains an implementation class for a binary_heap. + */ + +#ifndef PB_DS_BINARY_HEAP_ENTRY_CMP_HPP +#define PB_DS_BINARY_HEAP_ENTRY_CMP_HPP + +namespace pb_ds +{ + namespace detail + { + + template<typename Value_Type, + class Cmp_Fn, + bool No_Throw, + class Allocator> + struct entry_cmp + { + typedef Cmp_Fn type; + }; + + template<typename Value_Type, class Cmp_Fn, class Allocator> + struct entry_cmp< + Value_Type, + Cmp_Fn, + false, + Allocator> + { + public: + typedef + typename Allocator::template rebind< + Value_Type>::other::const_pointer + entry; + + struct type : public Cmp_Fn + { + public: + inline + type() + { } + + inline + type(const Cmp_Fn& other) : Cmp_Fn(other) + { } + + inline bool + operator()(entry p_lhs, entry p_rhs) const + { + return Cmp_Fn::operator()(*p_lhs, * p_rhs); + } + }; + }; + + } // namespace detail +} // namespace pb_ds + +#endif // #ifndef PB_DS_BINARY_HEAP_ENTRY_CMP_HPP diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/entry_pred.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/entry_pred.hpp new file mode 100644 index 000000000000..25102f2c1ad6 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/entry_pred.hpp @@ -0,0 +1,99 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file entry_pred.hpp + * Contains an implementation class for a binary_heap. + */ + +#ifndef PB_DS_BINARY_HEAP_ENTRY_PRED_HPP +#define PB_DS_BINARY_HEAP_ENTRY_PRED_HPP + +namespace pb_ds +{ + namespace detail + { + + template<typename Value_Type, + class Pred, + bool No_Throw, + class Allocator> + struct entry_pred + { + typedef Pred type; + }; + + template<typename Value_Type, class Pred, class Allocator> + struct entry_pred< + Value_Type, + Pred, + false, + Allocator> + { + public: + typedef + typename Allocator::template rebind< + Value_Type>::other::const_pointer + entry; + + struct type : public Pred + { + public: + inline + type() + { } + + inline + type(const Pred& other) : Pred(other) + { } + + inline bool + operator()(entry p_v) const + { + return Pred::operator()(*p_v); + } + }; + }; + + } // namespace detail +} // namespace pb_ds + +#endif // #ifndef PB_DS_BINARY_HEAP_ENTRY_PRED_HPP diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/erase_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/erase_fn_imps.hpp new file mode 100644 index 000000000000..72686d129743 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/erase_fn_imps.hpp @@ -0,0 +1,252 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file erase_fn_imps.hpp + * Contains an implementation class for a binary_heap. + */ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +clear() +{ + for (size_type i = 0; i < m_size; ++i) + erase_at(m_a_entries, i, s_no_throw_copies_ind); + + try + { + const size_type actual_size = resize_policy::get_new_size_for_arbitrary(0); + + entry_pointer a_entries = s_entry_allocator.allocate(actual_size); + + resize_policy::notify_arbitrary(actual_size); + + s_entry_allocator.deallocate(m_a_entries, m_actual_size); + + m_actual_size = actual_size; + + m_a_entries = a_entries; + } + catch(...) + { } + + m_size = 0; + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +erase_at(entry_pointer a_entries, size_type i, false_type) +{ + a_entries[i]->~value_type(); + + s_value_allocator.deallocate(a_entries[i], 1); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +erase_at(entry_pointer, size_type, true_type) +{ } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +pop() +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ASSERT(!empty()); + + erase_at(m_a_entries, 0, s_no_throw_copies_ind); + + std::pop_heap(m_a_entries, m_a_entries + m_size, static_cast<entry_cmp& >(*this)); + + resize_for_erase_if_needed(); + + _GLIBCXX_DEBUG_ASSERT(m_size > 0); + --m_size; + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + +PB_DS_CLASS_T_DEC +template<typename Pred> +typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +erase_if(Pred pred) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + typedef + typename entry_pred< + value_type, + Pred, + simple_value, + Allocator>::type + pred_t; + + const size_type left = partition(pred_t(pred)); + + _GLIBCXX_DEBUG_ASSERT(m_size >= left); + + const size_type ersd = m_size - left; + + for (size_type i = left; i < m_size; ++i) + erase_at(m_a_entries, i, s_no_throw_copies_ind); + + try + { + const size_type actual_size = + resize_policy::get_new_size_for_arbitrary(left); + + entry_pointer a_entries = s_entry_allocator.allocate(actual_size); + + std::copy(m_a_entries, m_a_entries + left, a_entries); + + s_entry_allocator.deallocate(m_a_entries, m_actual_size); + + m_actual_size = actual_size; + + resize_policy::notify_arbitrary(m_actual_size); + } + catch(...) + { }; + + m_size = left; + + std::make_heap(m_a_entries, m_a_entries + m_size, static_cast<entry_cmp& >(*this)); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + return ersd; +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +erase(point_iterator it) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ASSERT(!empty()); + + const size_type fix_pos = it.m_p_e - m_a_entries; + + std::swap(*it.m_p_e, m_a_entries[m_size - 1]); + + erase_at(m_a_entries, m_size - 1, s_no_throw_copies_ind); + + resize_for_erase_if_needed(); + + _GLIBCXX_DEBUG_ASSERT(m_size > 0); + --m_size; + + _GLIBCXX_DEBUG_ASSERT(fix_pos <= m_size); + + if (fix_pos != m_size) + fix(m_a_entries + fix_pos); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +resize_for_erase_if_needed() +{ + if (!resize_policy::resize_needed_for_shrink(m_size)) + return; + + try + { + const size_type new_actual_size = + resize_policy::get_new_size_for_shrink(); + + entry_pointer a_new_entries = s_entry_allocator.allocate(new_actual_size); + + resize_policy::notify_shrink_resize(); + + _GLIBCXX_DEBUG_ASSERT(m_size > 0); + std::copy(m_a_entries, m_a_entries + m_size - 1, a_new_entries); + + s_entry_allocator.deallocate(m_a_entries, m_actual_size); + + m_actual_size = new_actual_size; + + m_a_entries = a_new_entries; + } + catch(...) + { } +} + +PB_DS_CLASS_T_DEC +template<typename Pred> +typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +partition(Pred pred) +{ + size_type left = 0; + size_type right = m_size - 1; + + while (right + 1 != left) + { + _GLIBCXX_DEBUG_ASSERT(left <= m_size); + + if (!pred(m_a_entries[left])) + ++left; + else if (pred(m_a_entries[right])) + --right; + else + { + _GLIBCXX_DEBUG_ASSERT(left < right); + + std::swap(m_a_entries[left], m_a_entries[right]); + + ++left; + --right; + } + } + + return left; +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/find_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/find_fn_imps.hpp new file mode 100644 index 000000000000..b7606b673d8e --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/find_fn_imps.hpp @@ -0,0 +1,97 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file find_fn_imps.hpp + * Contains an implementation class for a binary_heap. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_reference +PB_DS_CLASS_C_DEC:: +top() const +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ASSERT(!empty()); + + return top_imp(s_no_throw_copies_ind); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_reference +PB_DS_CLASS_C_DEC:: +top_imp(true_type) const +{ + return* m_a_entries; +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_reference +PB_DS_CLASS_C_DEC:: +top_imp(false_type) const +{ + return** m_a_entries; +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +left_child(size_type i) +{ + return i* 2 + 1; +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +right_child(size_type i) +{ + return i* 2 + 2; +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +parent(size_type i) +{ + return (i - 1) / 2; +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/info_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/info_fn_imps.hpp new file mode 100644 index 000000000000..eb227d3beace --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/info_fn_imps.hpp @@ -0,0 +1,70 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file info_fn_imps.hpp + * Contains an implementation class for a binary_heap. + */ + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +empty() const +{ + return (m_size == 0); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +size() const +{ + return (m_size); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +max_size() const +{ + return (s_entry_allocator.max_size()); +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/insert_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/insert_fn_imps.hpp new file mode 100644 index 000000000000..489ccc124653 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/insert_fn_imps.hpp @@ -0,0 +1,220 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file insert_fn_imps.hpp + * Contains an implementation class for a binary_heap. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::point_iterator +PB_DS_CLASS_C_DEC:: +push(const_reference r_val) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + insert_value(r_val, s_no_throw_copies_ind); + + std::push_heap(m_a_entries, m_a_entries + m_size, static_cast<entry_cmp& >(*this)); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + return point_iterator(m_a_entries); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +insert_value(value_type val, true_type) +{ + resize_for_insert_if_needed(); + + m_a_entries[m_size++] = val; +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +insert_value(const_reference r_val, false_type) +{ + resize_for_insert_if_needed(); + + pointer p_new = s_value_allocator.allocate(1); + + cond_dealtor_t cond(p_new); + + new (p_new) value_type(r_val); + + cond.set_no_action(); + + m_a_entries[m_size++] = p_new; +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +insert_entry(entry e) +{ + resize_for_insert_if_needed(); + + m_a_entries[m_size++] = e; +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +resize_for_insert_if_needed() +{ + if (!resize_policy::resize_needed_for_grow(m_size)) + { + _GLIBCXX_DEBUG_ASSERT(m_size < m_actual_size); + + return; + } + + const size_type new_actual_size = + resize_policy::get_new_size_for_grow(); + + entry_pointer a_new_entries = s_entry_allocator.allocate(new_actual_size); + + resize_policy::notify_grow_resize(); + + std::copy(m_a_entries, m_a_entries + m_size, a_new_entries); + + s_entry_allocator.deallocate(m_a_entries, m_actual_size); + + m_actual_size = new_actual_size; + + m_a_entries = a_new_entries; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +modify(point_iterator it, const_reference r_new_val) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + swap_value_imp(it.m_p_e, r_new_val, s_no_throw_copies_ind); + + fix(it.m_p_e); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +fix(entry_pointer p_e) +{ + size_type i = p_e - m_a_entries; + + if (i > 0&& entry_cmp::operator()(m_a_entries[parent(i)], m_a_entries[i])) + { + size_type parent_i = parent(i); + + while (i > 0&& entry_cmp::operator()(m_a_entries[parent_i], m_a_entries[i])) + { + std::swap(m_a_entries[i], m_a_entries[parent_i]); + + i = parent_i; + + parent_i = parent(i); + } + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + return; + } + + while (i < m_size) + { + const size_type left_child_i = left_child(i); + const size_type right_child_i = right_child(i); + + _GLIBCXX_DEBUG_ASSERT(right_child_i > left_child_i); + + const bool smaller_than_left_child = + left_child_i < m_size&& + entry_cmp::operator()(m_a_entries[i], m_a_entries[left_child_i]); + + const bool smaller_than_right_child = + right_child_i < m_size&& + entry_cmp::operator()(m_a_entries[i], m_a_entries[right_child_i]); + + const bool swap_with_r_child = smaller_than_right_child&& (!smaller_than_left_child || + entry_cmp::operator()(m_a_entries[left_child_i], m_a_entries[right_child_i])); + + const bool swap_with_l_child = !swap_with_r_child&& smaller_than_left_child; + + if (swap_with_l_child) + { + std::swap(m_a_entries[i], m_a_entries[left_child_i]); + + i = left_child_i; + } + else if (swap_with_r_child) + { + std::swap(m_a_entries[i], m_a_entries[right_child_i]); + + i = right_child_i; + } + else + i = m_size; + } +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +swap_value_imp(entry_pointer p_e, value_type new_val, true_type) +{ + * p_e = new_val; +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +swap_value_imp(entry_pointer p_e, const_reference r_new_val, false_type) +{ + value_type tmp(r_new_val); + (*p_e)->swap(tmp); +} diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/iterators_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/iterators_fn_imps.hpp new file mode 100644 index 000000000000..7a647c33556e --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/iterators_fn_imps.hpp @@ -0,0 +1,78 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file iterators_fn_imps.hpp + * Contains an implementation class for a binary_heap. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +begin() +{ + return (iterator(m_a_entries)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +begin() const +{ + return (const_iterator(m_a_entries)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +end() +{ + return (iterator(m_a_entries + m_size)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +end() const +{ + return (const_iterator(m_a_entries + m_size)); +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/policy_access_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/policy_access_fn_imps.hpp new file mode 100644 index 000000000000..6c019c085822 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/policy_access_fn_imps.hpp @@ -0,0 +1,62 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file policy_access_fn_imps.hpp + * Contains an implementation class for a binary_heap. + */ + +PB_DS_CLASS_T_DEC +Cmp_Fn& +PB_DS_CLASS_C_DEC:: +get_cmp_fn() +{ + return (*this); +} + +PB_DS_CLASS_T_DEC +const Cmp_Fn& +PB_DS_CLASS_C_DEC:: +get_cmp_fn() const +{ + return (*this); +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/resize_policy.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/resize_policy.hpp new file mode 100644 index 000000000000..c6021a998041 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/resize_policy.hpp @@ -0,0 +1,259 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file resize_policy.hpp + * Contains an implementation class for a binary_heap. + */ + +#ifndef PB_DS_BINARY_HEAP_RESIZE_POLICY_HPP +#define PB_DS_BINARY_HEAP_RESIZE_POLICY_HPP + +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_CLASS_T_DEC template<typename Size_Type> + +#define PB_DS_CLASS_C_DEC resize_policy<Size_Type> + + template<typename Size_Type> + class resize_policy + { + public: + typedef Size_Type size_type; + + enum + { + min_size = 16 + }; + + public: + inline + resize_policy(); + + inline void + swap(PB_DS_CLASS_C_DEC& other); + + inline bool + resize_needed_for_grow(size_type size) const; + + inline bool + resize_needed_for_shrink(size_type size) const; + + inline bool + grow_needed(size_type size) const; + + inline bool + shrink_needed(size_type size) const; + + inline size_type + get_new_size_for_grow() const; + + inline size_type + get_new_size_for_shrink() const; + + size_type + get_new_size_for_arbitrary(size_type size) const; + + inline void + notify_grow_resize(); + + inline void + notify_shrink_resize(); + + void + notify_arbitrary(size_type actual_size); + +#ifdef _GLIBCXX_DEBUG + void + assert_valid() const; +#endif + +#ifdef PB_DS_BINARY_HEAP_TRACE_ + void + trace() const; +#endif + + private: + enum + { + ratio = 8, + factor = 2 + }; + + private: + size_type m_next_shrink_size; + size_type m_next_grow_size; + }; + + PB_DS_CLASS_T_DEC + inline + PB_DS_CLASS_C_DEC:: + resize_policy() : + m_next_shrink_size(0), + m_next_grow_size(min_size) + { _GLIBCXX_DEBUG_ONLY(assert_valid();) } + + PB_DS_CLASS_T_DEC + inline void + PB_DS_CLASS_C_DEC:: + swap(PB_DS_CLASS_C_DEC& other) + { + std::swap(m_next_shrink_size, other.m_next_shrink_size); + std::swap(m_next_grow_size, other.m_next_grow_size); + } + + PB_DS_CLASS_T_DEC + inline bool + PB_DS_CLASS_C_DEC:: + resize_needed_for_grow(size_type size) const + { + _GLIBCXX_DEBUG_ASSERT(size <= m_next_grow_size); + return size == m_next_grow_size; + } + + PB_DS_CLASS_T_DEC + inline bool + PB_DS_CLASS_C_DEC:: + resize_needed_for_shrink(size_type size) const + { + _GLIBCXX_DEBUG_ASSERT(size <= m_next_grow_size); + return size == m_next_shrink_size; + } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::size_type + PB_DS_CLASS_C_DEC:: + get_new_size_for_grow() const + { return m_next_grow_size* factor; } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::size_type + PB_DS_CLASS_C_DEC:: + get_new_size_for_shrink() const + { + const size_type half_size = m_next_grow_size / factor; + return std::max(static_cast<size_type>(min_size), half_size); + } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::size_type + PB_DS_CLASS_C_DEC:: + get_new_size_for_arbitrary(size_type size) const + { + size_type ret = min_size; + while (ret < size) + ret *= factor; + return ret; + } + + PB_DS_CLASS_T_DEC + inline void + PB_DS_CLASS_C_DEC:: + notify_grow_resize() + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ASSERT(m_next_grow_size >= min_size); + m_next_grow_size *= factor; + m_next_shrink_size = m_next_grow_size / ratio; + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + + PB_DS_CLASS_T_DEC + inline void + PB_DS_CLASS_C_DEC:: + notify_shrink_resize() + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + m_next_shrink_size /= factor; + if (m_next_shrink_size == 1) + m_next_shrink_size = 0; + + m_next_grow_size = + std::max(m_next_grow_size / factor, static_cast<size_type>(min_size)); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + + PB_DS_CLASS_T_DEC + inline void + PB_DS_CLASS_C_DEC:: + notify_arbitrary(size_type actual_size) + { + m_next_grow_size = actual_size; + m_next_shrink_size = m_next_grow_size / ratio; + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + +#ifdef _GLIBCXX_DEBUG + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + assert_valid() const + { + _GLIBCXX_DEBUG_ASSERT(m_next_shrink_size == 0 || + m_next_shrink_size* ratio == m_next_grow_size); + + _GLIBCXX_DEBUG_ASSERT(m_next_grow_size >= min_size); + } +#endif + +#ifdef PB_DS_BINARY_HEAP_TRACE_ + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + trace() const + { + std::cerr << "shrink = " << m_next_shrink_size << + " grow = " << m_next_grow_size << std::endl; + } +#endif + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +} // namespace detail +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/split_join_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/split_join_fn_imps.hpp new file mode 100644 index 000000000000..679efa5c4752 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/split_join_fn_imps.hpp @@ -0,0 +1,178 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file split_join_fn_imps.hpp + * Contains an implementation class for a binary_heap. + */ + +PB_DS_CLASS_T_DEC +template<typename Pred> +void +PB_DS_CLASS_C_DEC:: +split(Pred pred, PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + typedef + typename entry_pred< + value_type, + Pred, + simple_value, + Allocator>::type + pred_t; + + const size_type left = partition(pred_t(pred)); + + _GLIBCXX_DEBUG_ASSERT(m_size >= left); + + const size_type ersd = m_size - left; + + _GLIBCXX_DEBUG_ASSERT(m_size >= ersd); + + const size_type actual_size = + resize_policy::get_new_size_for_arbitrary(left); + + const size_type other_actual_size = + other.get_new_size_for_arbitrary(ersd); + + entry_pointer a_entries = NULL; + entry_pointer a_other_entries = NULL; + + try + { + a_entries = s_entry_allocator.allocate(actual_size); + + a_other_entries = s_entry_allocator.allocate(other_actual_size); + } + catch(...) + { + if (a_entries != NULL) + s_entry_allocator.deallocate(a_entries, actual_size); + + if (a_other_entries != NULL) + s_entry_allocator.deallocate(a_other_entries, other_actual_size); + + __throw_exception_again; + }; + + for (size_type i = 0; i < other.m_size; ++i) + erase_at(other.m_a_entries, i, s_no_throw_copies_ind); + + _GLIBCXX_DEBUG_ASSERT(actual_size >= left); + std::copy(m_a_entries, m_a_entries + left, a_entries); + std::copy(m_a_entries + left, m_a_entries + m_size, a_other_entries); + + s_entry_allocator.deallocate(m_a_entries, m_actual_size); + s_entry_allocator.deallocate(other.m_a_entries, other.m_actual_size); + + m_actual_size = actual_size; + other.m_actual_size = other_actual_size; + + m_size = left; + other.m_size = ersd; + + m_a_entries = a_entries; + other.m_a_entries = a_other_entries; + + std::make_heap(m_a_entries, m_a_entries + m_size, static_cast<entry_cmp& >(*this)); + std::make_heap(other.m_a_entries, other.m_a_entries + other.m_size, static_cast<entry_cmp& >(other)); + + resize_policy::notify_arbitrary(m_actual_size); + other.notify_arbitrary(other.m_actual_size); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +join(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + + const size_type len = m_size + other.m_size; + const size_type actual_size = resize_policy::get_new_size_for_arbitrary(len); + + entry_pointer a_entries = NULL; + entry_pointer a_other_entries = NULL; + + try + { + a_entries = s_entry_allocator.allocate(actual_size); + a_other_entries = s_entry_allocator.allocate(resize_policy::min_size); + } + catch(...) + { + if (a_entries != NULL) + s_entry_allocator.deallocate(a_entries, actual_size); + + if (a_other_entries != NULL) + s_entry_allocator.deallocate(a_other_entries, resize_policy::min_size); + + __throw_exception_again; + } + + std::copy(m_a_entries, m_a_entries + m_size, a_entries); + std::copy(other.m_a_entries, other.m_a_entries + other.m_size, a_entries + m_size); + + s_entry_allocator.deallocate(m_a_entries, m_actual_size); + m_a_entries = a_entries; + m_size = len; + m_actual_size = actual_size; + + resize_policy::notify_arbitrary(actual_size); + + std::make_heap(m_a_entries, m_a_entries + m_size, static_cast<entry_cmp& >(*this)); + + s_entry_allocator.deallocate(other.m_a_entries, other.m_actual_size); + other.m_a_entries = a_other_entries; + other.m_size = 0; + other.m_actual_size = resize_policy::min_size; + + other.notify_arbitrary(resize_policy::min_size); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/trace_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/trace_fn_imps.hpp new file mode 100644 index 000000000000..bcc10656abba --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/binary_heap_/trace_fn_imps.hpp @@ -0,0 +1,84 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file trace_fn_imps.hpp + * Contains an implementation class for a binary_heap. + */ + +#ifdef PB_DS_BINARY_HEAP_TRACE_ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +trace() const +{ + std::cerr << this << std::endl; + + std::cerr << m_a_entries << std::endl; + + for (size_type i = 0; i < m_size; ++i) + trace_entry(m_a_entries[i], s_no_throw_copies_ind); + + std::cerr << std::endl; + + std::cerr << "size = " << m_size << " " << "actual_size = " << m_actual_size << std::endl; + + resize_policy::trace(); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +trace_entry(const entry& r_e, false_type) const +{ + std::cout << r_e << " " <<* r_e << std::endl; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +trace_entry(const entry& r_e, true_type) const +{ + std::cout << r_e << std::endl; +} + +#endif // #ifdef PB_DS_BINARY_HEAP_TRACE_ diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/binomial_heap_/binomial_heap_.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/binomial_heap_/binomial_heap_.hpp new file mode 100644 index 000000000000..c6f361d936c8 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/binomial_heap_/binomial_heap_.hpp @@ -0,0 +1,122 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file binomial_heap_.hpp + * Contains an implementation class for a binomial heap. + */ + +/* + * Binomial heap. + * Vuillemin J is the mastah. + * Modified from CLRS. + */ + +#include <debug/debug.h> +#include <ext/pb_ds/detail/cond_dealtor.hpp> +#include <ext/pb_ds/detail/type_utils.hpp> +#include <ext/pb_ds/detail/binomial_heap_base_/binomial_heap_base_.hpp> + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_CLASS_T_DEC \ + template<typename Value_Type, class Cmp_Fn, class Allocator> + +#define PB_DS_CLASS_C_DEC \ + binomial_heap_<Value_Type, Cmp_Fn, Allocator> + +#define PB_DS_BASE_C_DEC \ + binomial_heap_base_<Value_Type, Cmp_Fn, Allocator> + + /** + * class description = "8y|\|0|\/|i41 h34p 74813"> + **/ + template<typename Value_Type, class Cmp_Fn, class Allocator> + class binomial_heap_ : public PB_DS_BASE_C_DEC + { + private: + typedef PB_DS_BASE_C_DEC base_type; + typedef typename base_type::node_pointer node_pointer; + typedef typename base_type::const_node_pointer const_node_pointer; + + public: + typedef Value_Type value_type; + typedef typename Allocator::size_type size_type; + typedef typename Allocator::difference_type difference_type; + typedef typename base_type::pointer pointer; + typedef typename base_type::const_pointer const_pointer; + typedef typename base_type::reference reference; + typedef typename base_type::const_reference const_reference; + typedef typename base_type::const_point_iterator const_point_iterator; + typedef typename base_type::point_iterator point_iterator; + typedef typename base_type::const_iterator const_iterator; + typedef typename base_type::iterator iterator; + typedef typename base_type::cmp_fn cmp_fn; + typedef typename base_type::allocator allocator; + + binomial_heap_(); + + binomial_heap_(const Cmp_Fn& r_cmp_fn); + + binomial_heap_(const PB_DS_CLASS_C_DEC& other); + + ~binomial_heap_(); + + protected: +#ifdef _GLIBCXX_DEBUG + void + assert_valid() const; +#endif + }; + +#include <ext/pb_ds/detail/binomial_heap_/constructors_destructor_fn_imps.hpp> +#include <ext/pb_ds/detail/binomial_heap_/debug_fn_imps.hpp> + +#undef PB_DS_CLASS_C_DEC + +#undef PB_DS_CLASS_T_DEC + +#undef PB_DS_BASE_C_DEC + } // namespace detail +} // namespace pb_ds diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/binomial_heap_/constructors_destructor_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/binomial_heap_/constructors_destructor_fn_imps.hpp new file mode 100644 index 000000000000..2e63cf8e923a --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/binomial_heap_/constructors_destructor_fn_imps.hpp @@ -0,0 +1,67 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructors_destructor_fn_imps.hpp + * Contains an implementation for binomial_heap_. + */ + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +binomial_heap_() +{ _GLIBCXX_DEBUG_ONLY(assert_valid();) } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +binomial_heap_(const Cmp_Fn& r_cmp_fn) : + PB_DS_BASE_C_DEC(r_cmp_fn) +{ _GLIBCXX_DEBUG_ONLY(assert_valid();) } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +binomial_heap_(const PB_DS_CLASS_C_DEC& other) : + PB_DS_BASE_C_DEC(other) +{ _GLIBCXX_DEBUG_ONLY(assert_valid();) } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +~binomial_heap_() { } + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/binomial_heap_/debug_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/binomial_heap_/debug_fn_imps.hpp new file mode 100644 index 000000000000..540bd7cd8467 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/binomial_heap_/debug_fn_imps.hpp @@ -0,0 +1,55 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_fn_imps.hpp + * Contains an implementation for binomial_heap_. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_valid() const +{ base_type::assert_valid(true); } + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/binomial_heap_base_.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/binomial_heap_base_.hpp new file mode 100644 index 000000000000..09af8cfffd71 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/binomial_heap_base_.hpp @@ -0,0 +1,240 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file binomial_heap_base_.hpp + * Contains an implementation class for a base of binomial heaps. + */ + +#ifndef PB_DS_BINOMIAL_HEAP_BASE_HPP +#define PB_DS_BINOMIAL_HEAP_BASE_HPP + +/* + * Binomial heap base. + * Vuillemin J is the mastah. + * Modified from CLRS. + */ + +#include <debug/debug.h> +#include <ext/pb_ds/detail/cond_dealtor.hpp> +#include <ext/pb_ds/detail/type_utils.hpp> +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/left_child_next_sibling_heap_.hpp> +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/null_metadata.hpp> + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_CLASS_T_DEC \ + template<typename Value_Type, class Cmp_Fn, class Allocator> + +#define PB_DS_CLASS_C_DEC \ + binomial_heap_base_<Value_Type, Cmp_Fn, Allocator> + +#ifdef _GLIBCXX_DEBUG +#define PB_DS_BASE_C_DEC \ + left_child_next_sibling_heap_<Value_Type, Cmp_Fn, \ + typename Allocator::size_type, \ + Allocator, false> +#else +#define PB_DS_BASE_C_DEC \ + left_child_next_sibling_heap_<Value_Type, Cmp_Fn, \ + typename Allocator::size_type, Allocator> +#endif + + /** + * class description = "8y|\|0|\/|i41 h34p 74813"> + **/ + template<typename Value_Type, class Cmp_Fn, class Allocator> + class binomial_heap_base_ : public PB_DS_BASE_C_DEC + { + + private: + typedef PB_DS_BASE_C_DEC base_type; + + protected: + typedef typename base_type::node node; + + typedef typename base_type::node_pointer node_pointer; + + typedef typename base_type::const_node_pointer const_node_pointer; + + public: + + typedef typename Allocator::size_type size_type; + + typedef typename Allocator::difference_type difference_type; + + typedef Value_Type value_type; + + typedef + typename Allocator::template rebind< + value_type>::other::pointer + pointer; + + typedef + typename Allocator::template rebind< + value_type>::other::const_pointer + const_pointer; + + typedef + typename Allocator::template rebind< + value_type>::other::reference + reference; + + typedef + typename Allocator::template rebind< + value_type>::other::const_reference + const_reference; + + typedef + typename PB_DS_BASE_C_DEC::const_point_iterator + const_point_iterator; + + typedef typename PB_DS_BASE_C_DEC::point_iterator point_iterator; + + typedef typename PB_DS_BASE_C_DEC::const_iterator const_iterator; + + typedef typename PB_DS_BASE_C_DEC::iterator iterator; + + typedef Cmp_Fn cmp_fn; + + typedef Allocator allocator; + + public: + + inline point_iterator + push(const_reference r_val); + + void + modify(point_iterator it, const_reference r_new_val); + + inline const_reference + top() const; + + void + pop(); + + void + erase(point_iterator it); + + inline void + clear(); + + template<typename Pred> + size_type + erase_if(Pred pred); + + template<typename Pred> + void + split(Pred pred, PB_DS_CLASS_C_DEC& other); + + void + join(PB_DS_CLASS_C_DEC& other); + + protected: + + binomial_heap_base_(); + + binomial_heap_base_(const Cmp_Fn& r_cmp_fn); + + binomial_heap_base_(const PB_DS_CLASS_C_DEC& other); + + void + swap(PB_DS_CLASS_C_DEC& other); + + ~binomial_heap_base_(); + + template<typename It> + void + copy_from_range(It first_it, It last_it); + + inline void + find_max(); + +#ifdef _GLIBCXX_DEBUG + void + assert_valid(bool strictly_binomial) const; + + void + assert_max() const; +#endif + + private: + + inline node_pointer + fix(node_pointer p_nd) const; + + inline void + insert_node(node_pointer p_nd); + + inline void + remove_parentless_node(node_pointer p_nd); + + inline node_pointer + join(node_pointer p_lhs, node_pointer p_rhs) const; + +#ifdef _GLIBCXX_DEBUG + void + assert_node_consistent(const_node_pointer, bool, bool) const; +#endif + + protected: + node_pointer m_p_max; + }; + +#include <ext/pb_ds/detail/binomial_heap_base_/constructors_destructor_fn_imps.hpp> +#include <ext/pb_ds/detail/binomial_heap_base_/debug_fn_imps.hpp> +#include <ext/pb_ds/detail/binomial_heap_base_/find_fn_imps.hpp> +#include <ext/pb_ds/detail/binomial_heap_base_/insert_fn_imps.hpp> +#include <ext/pb_ds/detail/binomial_heap_base_/erase_fn_imps.hpp> +#include <ext/pb_ds/detail/binomial_heap_base_/split_join_fn_imps.hpp> + +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_BASE_C_DEC + + + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/constructors_destructor_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/constructors_destructor_fn_imps.hpp new file mode 100644 index 000000000000..24ea2955917f --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/constructors_destructor_fn_imps.hpp @@ -0,0 +1,103 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructors_destructor_fn_imps.hpp + * Contains an implementation class for a base of binomial heaps. + */ + +PB_DS_CLASS_T_DEC +template<typename It> +void +PB_DS_CLASS_C_DEC:: +copy_from_range(It first_it, It last_it) +{ + while (first_it != last_it) + push(*(first_it++)); + + _GLIBCXX_DEBUG_ONLY(assert_valid(false);) + } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +binomial_heap_base_() : + m_p_max(NULL) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid(false);) + } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +binomial_heap_base_(const Cmp_Fn& r_cmp_fn) : + PB_DS_BASE_C_DEC(r_cmp_fn), + m_p_max(NULL) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid(false);) + } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +binomial_heap_base_(const PB_DS_CLASS_C_DEC& other) : + PB_DS_BASE_C_DEC(other), + m_p_max(NULL) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid(false);) + } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid(false);) + + base_type::swap(other); + + std::swap(m_p_max, other.m_p_max); + + _GLIBCXX_DEBUG_ONLY(assert_valid(false);) + } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +~binomial_heap_base_() +{ } + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/debug_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/debug_fn_imps.hpp new file mode 100644 index 000000000000..200249d8d988 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/debug_fn_imps.hpp @@ -0,0 +1,97 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_fn_imps.hpp + * Contains an implementation class for a base of binomial heaps. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_valid(bool strictly_binomial) const +{ + base_type::assert_valid(); + assert_node_consistent(base_type::m_p_root, strictly_binomial, true); + assert_max(); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_max() const +{ + if (m_p_max == NULL) + return; + _GLIBCXX_DEBUG_ASSERT(base_type::parent(m_p_max) == NULL); + for (const_iterator it = base_type::begin(); it != base_type::end(); ++it) + _GLIBCXX_DEBUG_ASSERT(!Cmp_Fn::operator()(m_p_max->m_value, it.m_p_nd->m_value)); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_node_consistent(const_node_pointer p_nd, bool strictly_binomial, bool increasing) const +{ + _GLIBCXX_DEBUG_ASSERT(increasing || strictly_binomial); + base_type::assert_node_consistent(p_nd, false); + if (p_nd == NULL) + return; + _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata == base_type::degree(p_nd)); + _GLIBCXX_DEBUG_ASSERT(base_type::size_under_node(p_nd) == + static_cast<size_type>(1 << p_nd->m_metadata)); + assert_node_consistent(p_nd->m_p_next_sibling, strictly_binomial, increasing); + assert_node_consistent(p_nd->m_p_l_child, true, false); + if (p_nd->m_p_next_sibling != NULL) + if (increasing) + { + if (strictly_binomial) + _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata < p_nd->m_p_next_sibling->m_metadata); + else + _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata <= p_nd->m_p_next_sibling->m_metadata); + } + else + _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata > p_nd->m_p_next_sibling->m_metadata); +} + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/erase_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/erase_fn_imps.hpp new file mode 100644 index 000000000000..8109b53ec01b --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/erase_fn_imps.hpp @@ -0,0 +1,198 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file erase_fn_imps.hpp + * Contains an implementation class for a base of binomial heaps. + */ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +pop() +{ + _GLIBCXX_DEBUG_ONLY(assert_valid(true);) + _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); + + if (m_p_max == NULL) + find_max(); + + _GLIBCXX_DEBUG_ASSERT(m_p_max != NULL); + + node_pointer p_nd = m_p_max; + + remove_parentless_node(m_p_max); + + base_type::actual_erase_node(p_nd); + + m_p_max = NULL; + + _GLIBCXX_DEBUG_ONLY(assert_valid(true);) + } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +remove_parentless_node(node_pointer p_nd) +{ + _GLIBCXX_DEBUG_ASSERT(p_nd != NULL); + _GLIBCXX_DEBUG_ASSERT(base_type::parent(p_nd) == NULL); + + node_pointer p_cur_root = p_nd == base_type::m_p_root? + p_nd->m_p_next_sibling : + base_type::m_p_root; + + if (p_cur_root != NULL) + p_cur_root->m_p_prev_or_parent = NULL; + + if (p_nd->m_p_prev_or_parent != NULL) + p_nd->m_p_prev_or_parent->m_p_next_sibling = p_nd->m_p_next_sibling; + + if (p_nd->m_p_next_sibling != NULL) + p_nd->m_p_next_sibling->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; + + node_pointer p_child = p_nd->m_p_l_child; + + if (p_child != NULL) + { + p_child->m_p_prev_or_parent = NULL; + + while (p_child->m_p_next_sibling != NULL) + p_child = p_child->m_p_next_sibling; + } + + m_p_max = NULL; + + base_type::m_p_root = join(p_cur_root, p_child); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +clear() +{ + base_type::clear(); + + m_p_max = NULL; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +erase(point_iterator it) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid(true);) + _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); + + base_type::bubble_to_top(it.m_p_nd); + + remove_parentless_node(it.m_p_nd); + + base_type::actual_erase_node(it.m_p_nd); + + m_p_max = NULL; + + _GLIBCXX_DEBUG_ONLY(assert_valid(true);) + } + +PB_DS_CLASS_T_DEC +template<typename Pred> +typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +erase_if(Pred pred) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid(true);) + + if (base_type::empty()) + { + _GLIBCXX_DEBUG_ONLY(assert_valid(true);) + + return 0; + } + + base_type::to_linked_list(); + + node_pointer p_out = base_type::prune(pred); + + size_type ersd = 0; + + while (p_out != NULL) + { + ++ersd; + + node_pointer p_next = p_out->m_p_next_sibling; + + base_type::actual_erase_node(p_out); + + p_out = p_next; + } + + node_pointer p_cur = base_type::m_p_root; + + base_type::m_p_root = NULL; + + while (p_cur != NULL) + { + node_pointer p_next = p_cur->m_p_next_sibling; + + p_cur->m_p_l_child = p_cur->m_p_prev_or_parent = NULL; + + p_cur->m_metadata = 0; + + p_cur->m_p_next_sibling = base_type::m_p_root; + + if (base_type::m_p_root != NULL) + base_type::m_p_root->m_p_prev_or_parent = p_cur; + + base_type::m_p_root = p_cur; + + base_type::m_p_root = fix(base_type::m_p_root); + + p_cur = p_next; + } + + m_p_max = NULL; + + _GLIBCXX_DEBUG_ONLY(assert_valid(true);) + + return ersd; +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/find_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/find_fn_imps.hpp new file mode 100644 index 000000000000..6014c0725267 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/find_fn_imps.hpp @@ -0,0 +1,79 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file find_fn_imps.hpp + * Contains an implementation class for a base of binomial heaps. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_reference +PB_DS_CLASS_C_DEC:: +top() const +{ + _GLIBCXX_DEBUG_ONLY(assert_valid(false);) + _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); + + if (m_p_max == NULL) + const_cast<PB_DS_CLASS_C_DEC* >(this)->find_max(); + + _GLIBCXX_DEBUG_ASSERT(m_p_max != NULL); + return m_p_max->m_value; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +find_max() +{ + node_pointer p_cur = base_type::m_p_root; + + m_p_max = p_cur; + + while (p_cur != NULL) + { + if (Cmp_Fn::operator()(m_p_max->m_value, p_cur->m_value)) + m_p_max = p_cur; + + p_cur = p_cur->m_p_next_sibling; + } +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/insert_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/insert_fn_imps.hpp new file mode 100644 index 000000000000..91b04e165fdd --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/insert_fn_imps.hpp @@ -0,0 +1,222 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file insert_fn_imps.hpp + * Contains an implementation class for a base of binomial heaps. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::point_iterator +PB_DS_CLASS_C_DEC:: +push(const_reference r_val) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid(true);) + + node_pointer p_nd = base_type::get_new_node_for_insert(r_val); + + insert_node(p_nd); + + m_p_max = NULL; + + _GLIBCXX_DEBUG_ONLY(assert_valid(true);) + + return point_iterator(p_nd); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +insert_node(node_pointer p_nd) +{ + if (base_type::m_p_root == NULL) + { + p_nd->m_p_next_sibling = p_nd->m_p_prev_or_parent = + p_nd->m_p_l_child = NULL; + + p_nd->m_metadata = 0; + + base_type::m_p_root = p_nd; + + return; + } + + if (base_type::m_p_root->m_metadata > 0) + { + p_nd->m_p_prev_or_parent = p_nd->m_p_l_child = NULL; + + p_nd->m_p_next_sibling = base_type::m_p_root; + + base_type::m_p_root->m_p_prev_or_parent = p_nd; + + base_type::m_p_root = p_nd; + + p_nd->m_metadata = 0; + + return; + } + + if (Cmp_Fn::operator()(base_type::m_p_root->m_value, p_nd->m_value)) + { + p_nd->m_p_next_sibling = base_type::m_p_root->m_p_next_sibling; + + p_nd->m_p_prev_or_parent = NULL; + + p_nd->m_metadata = 1; + + p_nd->m_p_l_child = base_type::m_p_root; + + base_type::m_p_root->m_p_prev_or_parent = p_nd; + + base_type::m_p_root->m_p_next_sibling = NULL; + + base_type::m_p_root = p_nd; + } + else + { + p_nd->m_p_next_sibling = NULL; + + p_nd->m_p_l_child = NULL; + + p_nd->m_p_prev_or_parent = base_type::m_p_root; + + p_nd->m_metadata = 0; + + _GLIBCXX_DEBUG_ASSERT(base_type::m_p_root->m_p_l_child == 0); + base_type::m_p_root->m_p_l_child = p_nd; + + base_type::m_p_root->m_metadata = 1; + } + + base_type::m_p_root = fix(base_type::m_p_root); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +fix(node_pointer p_nd) const +{ + while (p_nd->m_p_next_sibling != NULL&& + p_nd->m_metadata == p_nd->m_p_next_sibling->m_metadata) + { + node_pointer p_next = p_nd->m_p_next_sibling; + + if (Cmp_Fn::operator()(p_nd->m_value, p_next->m_value)) + { + p_next->m_p_prev_or_parent = + p_nd->m_p_prev_or_parent; + + if (p_nd->m_p_prev_or_parent != NULL) + p_nd->m_p_prev_or_parent->m_p_next_sibling = p_next; + + base_type::make_child_of(p_nd, p_next); + + ++p_next->m_metadata; + + p_nd = p_next; + } + else + { + p_nd->m_p_next_sibling = p_next->m_p_next_sibling; + + if (p_nd->m_p_next_sibling != NULL) + p_next->m_p_next_sibling = NULL; + + base_type::make_child_of(p_next, p_nd); + + ++p_nd->m_metadata; + } + } + + if (p_nd->m_p_next_sibling != NULL) + p_nd->m_p_next_sibling->m_p_prev_or_parent = p_nd; + + return p_nd; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +modify(point_iterator it, const_reference r_new_val) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid(true);) + node_pointer p_nd = it.m_p_nd; + + _GLIBCXX_DEBUG_ASSERT(p_nd != NULL); + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_nd, false);) + + const bool bubble_up = Cmp_Fn::operator()(p_nd->m_value, r_new_val); + + p_nd->m_value = r_new_val; + + if (bubble_up) + { + node_pointer p_parent = base_type::parent(p_nd); + + while (p_parent != NULL&& + Cmp_Fn::operator()(p_parent->m_value, p_nd->m_value)) + { + base_type::swap_with_parent(p_nd, p_parent); + + p_parent = base_type::parent(p_nd); + } + + if (p_nd->m_p_prev_or_parent == NULL) + base_type::m_p_root = p_nd; + + m_p_max = NULL; + + _GLIBCXX_DEBUG_ONLY(assert_valid(true);) + + return; + } + + base_type::bubble_to_top(p_nd); + + remove_parentless_node(p_nd); + + insert_node(p_nd); + + m_p_max = NULL; + + _GLIBCXX_DEBUG_ONLY(assert_valid(true);) + } + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/split_join_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/split_join_fn_imps.hpp new file mode 100644 index 000000000000..05f9f1278bcd --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/binomial_heap_base_/split_join_fn_imps.hpp @@ -0,0 +1,238 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file split_join_fn_imps.hpp + * Contains an implementation class for a base of binomial heaps. + */ + +PB_DS_CLASS_T_DEC +template<typename Pred> +void +PB_DS_CLASS_C_DEC:: +split(Pred pred, PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid(true);) + _GLIBCXX_DEBUG_ONLY(other.assert_valid(true);) + + other.clear(); + + if (base_type::empty()) + { + _GLIBCXX_DEBUG_ONLY(assert_valid(true);) + _GLIBCXX_DEBUG_ONLY(other.assert_valid(true);) + + return; + } + + base_type::to_linked_list(); + + node_pointer p_out = base_type::prune(pred); + + while (p_out != NULL) + { + _GLIBCXX_DEBUG_ASSERT(base_type::m_size > 0); + --base_type::m_size; + + ++other.m_size; + + node_pointer p_next = p_out->m_p_next_sibling; + + p_out->m_p_l_child = p_out->m_p_prev_or_parent = NULL; + + p_out->m_metadata = 0; + + p_out->m_p_next_sibling = other.m_p_root; + + if (other.m_p_root != NULL) + other.m_p_root->m_p_prev_or_parent = p_out; + + other.m_p_root = p_out; + + other.m_p_root = other.fix(other.m_p_root); + + p_out = p_next; + } + + _GLIBCXX_DEBUG_ONLY(other.assert_valid(true);) + + node_pointer p_cur = base_type::m_p_root; + + base_type::m_p_root = NULL; + + while (p_cur != NULL) + { + node_pointer p_next = p_cur->m_p_next_sibling; + + p_cur->m_p_l_child = p_cur->m_p_prev_or_parent = NULL; + + p_cur->m_metadata = 0; + + p_cur->m_p_next_sibling = base_type::m_p_root; + + if (base_type::m_p_root != NULL) + base_type::m_p_root->m_p_prev_or_parent = p_cur; + + base_type::m_p_root = p_cur; + + base_type::m_p_root = fix(base_type::m_p_root); + + p_cur = p_next; + } + + m_p_max = NULL; + + _GLIBCXX_DEBUG_ONLY(assert_valid(true);) + _GLIBCXX_DEBUG_ONLY(other.assert_valid(true);) + } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +join(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid(true);) + _GLIBCXX_DEBUG_ONLY(other.assert_valid(true);) + + node_pointer p_other = other.m_p_root; + + if (p_other != NULL) + do + { + node_pointer p_next = p_other->m_p_next_sibling; + + std::swap(p_other->m_p_next_sibling, p_other->m_p_prev_or_parent); + + p_other = p_next; + } + while (p_other != NULL); + + base_type::m_p_root = join(base_type::m_p_root, other.m_p_root); + base_type::m_size += other.m_size; + m_p_max = NULL; + + other.m_p_root = NULL; + other.m_size = 0; + other.m_p_max = NULL; + + _GLIBCXX_DEBUG_ONLY(assert_valid(true);) + _GLIBCXX_DEBUG_ONLY(other.assert_valid(true);) + } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +join(node_pointer p_lhs, node_pointer p_rhs) const +{ + node_pointer p_ret = NULL; + + node_pointer p_cur = NULL; + + while (p_lhs != NULL || p_rhs != NULL) + { + if (p_rhs == NULL) + { + if (p_cur == NULL) + p_ret = p_cur = p_lhs; + else + { + p_cur->m_p_next_sibling = p_lhs; + + p_lhs->m_p_prev_or_parent = p_cur; + } + + p_cur = p_lhs = NULL; + } + else if (p_lhs == NULL || p_rhs->m_metadata < p_lhs->m_metadata) + { + if (p_cur == NULL) + { + p_ret = p_cur = p_rhs; + + p_rhs = p_rhs->m_p_prev_or_parent; + } + else + { + p_cur->m_p_next_sibling = p_rhs; + + p_rhs = p_rhs->m_p_prev_or_parent; + + p_cur->m_p_next_sibling->m_p_prev_or_parent = p_cur; + + p_cur = p_cur->m_p_next_sibling; + } + } + else if (p_lhs->m_metadata < p_rhs->m_metadata) + { + if (p_cur == NULL) + p_ret = p_cur = p_lhs; + else + { + p_cur->m_p_next_sibling = p_lhs; + + p_lhs->m_p_prev_or_parent = p_cur; + + p_cur = p_cur->m_p_next_sibling; + } + + p_lhs = p_cur->m_p_next_sibling; + } + else + { + node_pointer p_next_rhs = p_rhs->m_p_prev_or_parent; + + p_rhs->m_p_next_sibling = p_lhs; + + p_lhs = fix(p_rhs); + + p_rhs = p_next_rhs; + } + } + + if (p_cur != NULL) + p_cur->m_p_next_sibling = NULL; + + if (p_ret != NULL) + p_ret->m_p_prev_or_parent = NULL; + + return p_ret; +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/cc_ht_map_.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/cc_ht_map_.hpp new file mode 100644 index 000000000000..c2b95e84ca7e --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/cc_ht_map_.hpp @@ -0,0 +1,647 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file cc_ht_map_.hpp + * Contains an implementation class for cc_ht_map_. + */ + +#include <utility> +#include <iterator> +#include <ext/pb_ds/detail/cond_dealtor.hpp> +#include <ext/pb_ds/tag_and_trait.hpp> +#include <ext/pb_ds/detail/hash_fn/ranged_hash_fn.hpp> +#include <ext/pb_ds/detail/types_traits.hpp> +#include <ext/pb_ds/exception.hpp> +#include <ext/pb_ds/detail/eq_fn/hash_eq_fn.hpp> +#ifdef _GLIBCXX_DEBUG +#include <ext/pb_ds/detail/map_debug_base.hpp> +#endif +#ifdef PB_DS_HT_MAP_TRACE_ +#include <iostream> +#endif +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_CLASS_T_DEC \ + template<typename Key, typename Mapped, typename Hash_Fn, \ + typename Eq_Fn, typename Allocator, bool Store_Hash, \ + typename Comb_Hash_Fn, typename Resize_Policy> + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_CLASS_NAME cc_ht_map_data_ +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#define PB_DS_CLASS_NAME cc_ht_map_no_data_ +#endif + +#define PB_DS_CLASS_C_DEC \ + PB_DS_CLASS_NAME<Key, Mapped, Hash_Fn, Eq_Fn, Allocator, \ + Store_Hash, Comb_Hash_Fn, Resize_Policy> + +#define PB_DS_HASH_EQ_FN_C_DEC \ + hash_eq_fn<Key, Eq_Fn, Allocator, Store_Hash> + +#define PB_DS_RANGED_HASH_FN_C_DEC \ + ranged_hash_fn<Key, Hash_Fn, Allocator, Comb_Hash_Fn, Store_Hash> + +#define PB_DS_TYPES_TRAITS_C_DEC \ + types_traits<Key, Mapped, Allocator, Store_Hash> + +#ifdef _GLIBCXX_DEBUG +#define PB_DS_MAP_DEBUG_BASE_C_DEC \ + map_debug_base<Key, Eq_Fn, typename Allocator::template rebind<Key>::other::const_reference> +#endif + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_V2F(X) (X).first +#define PB_DS_V2S(X) (X).second +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#define PB_DS_V2F(X) (X) +#define PB_DS_V2S(X) Mapped_Data() +#endif + +#define PB_DS_STATIC_ASSERT(UNIQUE, E) \ + typedef static_assert_dumclass<sizeof(static_assert<(bool)(E)>)> \ + UNIQUE##static_assert_type + + // <011i$i0|\|-<|-|4i|\|i|\|g |-|4$|-| 74813. + template<typename Key, + typename Mapped, + typename Hash_Fn, + typename Eq_Fn, + typename Allocator, + bool Store_Hash, + typename Comb_Hash_Fn, + typename Resize_Policy > + class PB_DS_CLASS_NAME: +#ifdef _GLIBCXX_DEBUG + protected PB_DS_MAP_DEBUG_BASE_C_DEC, +#endif + public PB_DS_HASH_EQ_FN_C_DEC, + public Resize_Policy, + public PB_DS_RANGED_HASH_FN_C_DEC, + public PB_DS_TYPES_TRAITS_C_DEC + { + private: + typedef PB_DS_TYPES_TRAITS_C_DEC traits_base; + typedef typename traits_base::comp_hash comp_hash; + typedef typename traits_base::value_type value_type_; + typedef typename traits_base::pointer pointer_; + typedef typename traits_base::const_pointer const_pointer_; + typedef typename traits_base::reference reference_; + typedef typename traits_base::const_reference const_reference_; + + struct entry : public traits_base::stored_value_type + { + typename Allocator::template rebind<entry>::other::pointer m_p_next; + }; + + typedef cond_dealtor<entry, Allocator> cond_dealtor_t; + + typedef typename Allocator::template rebind<entry>::other entry_allocator; + typedef typename entry_allocator::pointer entry_pointer; + typedef typename entry_allocator::const_pointer const_entry_pointer; + typedef typename entry_allocator::reference entry_reference; + typedef typename entry_allocator::const_reference const_entry_reference; + + typedef typename Allocator::template rebind<entry_pointer>::other entry_pointer_allocator; + typedef typename entry_pointer_allocator::pointer entry_pointer_array; + + typedef PB_DS_RANGED_HASH_FN_C_DEC ranged_hash_fn_base; + typedef PB_DS_HASH_EQ_FN_C_DEC hash_eq_fn_base; + typedef Resize_Policy resize_base; + +#ifdef _GLIBCXX_DEBUG + typedef PB_DS_MAP_DEBUG_BASE_C_DEC map_debug_base; +#endif + +#define PB_DS_GEN_POS std::pair<entry_pointer, typename Allocator::size_type> + +#include <ext/pb_ds/detail/unordered_iterator/const_point_iterator.hpp> +#include <ext/pb_ds/detail/unordered_iterator/point_iterator.hpp> +#include <ext/pb_ds/detail/unordered_iterator/const_iterator.hpp> +#include <ext/pb_ds/detail/unordered_iterator/iterator.hpp> + +#undef PB_DS_GEN_POS + + public: + typedef Allocator allocator; + typedef typename Allocator::size_type size_type; + typedef typename Allocator::difference_type difference_type; + typedef Hash_Fn hash_fn; + typedef Eq_Fn eq_fn; + typedef Comb_Hash_Fn comb_hash_fn; + typedef Resize_Policy resize_policy; + + enum + { + store_hash = Store_Hash + }; + + typedef typename traits_base::key_type key_type; + typedef typename traits_base::key_pointer key_pointer; + typedef typename traits_base::const_key_pointer const_key_pointer; + typedef typename traits_base::key_reference key_reference; + typedef typename traits_base::const_key_reference const_key_reference; + typedef typename traits_base::mapped_type mapped_type; + typedef typename traits_base::mapped_pointer mapped_pointer; + typedef typename traits_base::const_mapped_pointer const_mapped_pointer; + typedef typename traits_base::mapped_reference mapped_reference; + typedef typename traits_base::const_mapped_reference const_mapped_reference; + typedef typename traits_base::value_type value_type; + typedef typename traits_base::pointer pointer; + typedef typename traits_base::const_pointer const_pointer; + typedef typename traits_base::reference reference; + typedef typename traits_base::const_reference const_reference; + +#ifdef PB_DS_DATA_TRUE_INDICATOR + typedef point_iterator_ point_iterator; +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR + typedef const_point_iterator_ point_iterator; +#endif + + typedef const_point_iterator_ const_point_iterator; + +#ifdef PB_DS_DATA_TRUE_INDICATOR + typedef iterator_ iterator; +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR + typedef const_iterator_ iterator; +#endif + + typedef const_iterator_ const_iterator; + + PB_DS_CLASS_NAME(); + + PB_DS_CLASS_NAME(const Hash_Fn&); + + PB_DS_CLASS_NAME(const Hash_Fn&, const Eq_Fn&); + + PB_DS_CLASS_NAME(const Hash_Fn&, const Eq_Fn&, const Comb_Hash_Fn&); + + PB_DS_CLASS_NAME(const Hash_Fn&, const Eq_Fn&, const Comb_Hash_Fn&, + const Resize_Policy&); + + PB_DS_CLASS_NAME(const PB_DS_CLASS_C_DEC&); + + virtual + ~PB_DS_CLASS_NAME(); + + void + swap(PB_DS_CLASS_C_DEC&); + + template<typename It> + void + copy_from_range(It, It); + + void + initialize(); + + inline size_type + size() const; + + inline size_type + max_size() const; + + inline bool + empty() const; + + Hash_Fn& + get_hash_fn(); + + const Hash_Fn& + get_hash_fn() const; + + Eq_Fn& + get_eq_fn(); + + const Eq_Fn& + get_eq_fn() const; + + Comb_Hash_Fn& + get_comb_hash_fn(); + + const Comb_Hash_Fn& + get_comb_hash_fn() const; + + Resize_Policy& + get_resize_policy(); + + const Resize_Policy& + get_resize_policy() const; + + inline std::pair<point_iterator, bool> + insert(const_reference r_val) + { return insert_imp(r_val, traits_base::m_store_extra_indicator); } + + inline mapped_reference + operator[](const_key_reference r_key) + { +#ifdef PB_DS_DATA_TRUE_INDICATOR + return (subscript_imp(r_key, traits_base::m_store_extra_indicator)); +#else + insert(r_key); + return traits_base::s_null_mapped; +#endif + } + + inline point_iterator + find(const_key_reference); + + inline const_point_iterator + find(const_key_reference) const; + + inline point_iterator + find_end(); + + inline const_point_iterator + find_end() const; + + inline bool + erase(const_key_reference); + + template<typename Pred> + inline size_type + erase_if(Pred); + + void + clear(); + + inline iterator + begin(); + + inline const_iterator + begin() const; + + inline iterator + end(); + + inline const_iterator + end() const; + +#ifdef _GLIBCXX_DEBUG + void + assert_valid() const; +#endif + +#ifdef PB_DS_HT_MAP_TRACE_ + void + trace() const; +#endif + + private: + void + deallocate_all(); + + inline bool + do_resize_if_needed(); + + inline void + do_resize_if_needed_no_throw(); + + void + resize_imp(size_type new_size); + + void + do_resize(size_type new_size); + + void + resize_imp_no_exceptions(size_type, entry_pointer_array, size_type); + + inline entry_pointer + resize_imp_no_exceptions_reassign_pointer(entry_pointer, entry_pointer_array, false_type); + + inline entry_pointer + resize_imp_no_exceptions_reassign_pointer(entry_pointer, entry_pointer_array, true_type); + + void + deallocate_links_in_list(entry_pointer); + + inline entry_pointer + get_entry(const_reference, false_type); + + inline entry_pointer + get_entry(const_reference, true_type); + + inline void + rels_entry(entry_pointer); + +#ifdef PB_DS_DATA_TRUE_INDICATOR + inline mapped_reference + subscript_imp(const_key_reference r_key, false_type) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + const size_type pos = ranged_hash_fn_base::operator()(r_key); + entry_pointer p_e = m_entries[pos]; + resize_base::notify_insert_search_start(); + + while (p_e != NULL + && !hash_eq_fn_base::operator()(p_e->m_value.first, r_key)) + { + resize_base::notify_insert_search_collision(); + p_e = p_e->m_p_next; + } + + resize_base::notify_insert_search_end(); + if (p_e != NULL) + { + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(r_key);) + return (p_e->m_value.second); + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key);) + return insert_new_imp(value_type(r_key, mapped_type()), pos)->second; + } + + inline mapped_reference + subscript_imp(const_key_reference r_key, true_type) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + comp_hash pos_hash_pair = ranged_hash_fn_base::operator()(r_key); + entry_pointer p_e = m_entries[pos_hash_pair.first]; + resize_base::notify_insert_search_start(); + while (p_e != NULL && + !hash_eq_fn_base::operator()(p_e->m_value.first, p_e->m_hash, r_key, pos_hash_pair.second)) + { + resize_base::notify_insert_search_collision(); + p_e = p_e->m_p_next; + } + + resize_base::notify_insert_search_end(); + if (p_e != NULL) + { + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(r_key);) + return p_e->m_value.second; + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key);) + return insert_new_imp(value_type(r_key, mapped_type()), + pos_hash_pair)->second; + } +#endif + + inline std::pair<point_iterator, bool> + insert_imp(const_reference, false_type); + + inline std::pair<point_iterator, bool> + insert_imp(const_reference, true_type); + + inline pointer + insert_new_imp(const_reference r_val, size_type pos) + { + if (do_resize_if_needed()) + pos = ranged_hash_fn_base::operator()(PB_DS_V2F(r_val)); + + // Following lines might throw an exception. + entry_pointer p_e = get_entry(r_val, traits_base::m_no_throw_copies_indicator); + + // At this point no exceptions can be thrown. + p_e->m_p_next = m_entries[pos]; + m_entries[pos] = p_e; + resize_base::notify_inserted(++m_num_used_e); + + _GLIBCXX_DEBUG_ONLY(map_debug_base::insert_new(PB_DS_V2F(r_val));) + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return &p_e->m_value; + } + + inline pointer + insert_new_imp(const_reference r_val, comp_hash& r_pos_hash_pair) + { + // Following lines might throw an exception. + if (do_resize_if_needed()) + r_pos_hash_pair = ranged_hash_fn_base::operator()(PB_DS_V2F(r_val)); + + entry_pointer p_e = get_entry(r_val, traits_base::m_no_throw_copies_indicator); + + // At this point no exceptions can be thrown. + p_e->m_hash = r_pos_hash_pair.second; + p_e->m_p_next = m_entries[r_pos_hash_pair.first]; + m_entries[r_pos_hash_pair.first] = p_e; + resize_base::notify_inserted(++m_num_used_e); + _GLIBCXX_DEBUG_ONLY(map_debug_base::insert_new(PB_DS_V2F(r_val));) + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return &p_e->m_value; + } + + inline pointer + find_key_pointer(const_key_reference r_key, false_type) + { + entry_pointer p_e = m_entries[ranged_hash_fn_base::operator()(r_key)]; + resize_base::notify_find_search_start(); + while (p_e != NULL && + !hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), r_key)) + { + resize_base::notify_find_search_collision(); + p_e = p_e->m_p_next; + } + + resize_base::notify_find_search_end(); + +#ifdef _GLIBCXX_DEBUG + if (p_e == NULL) + map_debug_base::check_key_does_not_exist(r_key); + else + map_debug_base::check_key_exists(r_key); +#endif + return &p_e->m_value; + } + + inline pointer + find_key_pointer(const_key_reference r_key, true_type) + { + comp_hash pos_hash_pair = ranged_hash_fn_base::operator()(r_key); + entry_pointer p_e = m_entries[pos_hash_pair.first]; + resize_base::notify_find_search_start(); + while (p_e != NULL && + !hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), + p_e->m_hash, + r_key, pos_hash_pair.second)) + { + resize_base::notify_find_search_collision(); + p_e = p_e->m_p_next; + } + + resize_base::notify_find_search_end(); + +#ifdef _GLIBCXX_DEBUG + if (p_e == NULL) + map_debug_base::check_key_does_not_exist(r_key); + else + map_debug_base::check_key_exists(r_key); +#endif + return &p_e->m_value; + } + + inline bool + erase_in_pos_imp(const_key_reference, size_type); + + inline bool + erase_in_pos_imp(const_key_reference, const comp_hash&); + + inline void + erase_entry_pointer(entry_pointer&); + +#ifdef PB_DS_DATA_TRUE_INDICATOR + void + inc_it_state(pointer& r_p_value, + std::pair<entry_pointer, size_type>& r_pos) const + { + inc_it_state((const_mapped_pointer& )r_p_value, r_pos); + } +#endif + + void + inc_it_state(const_pointer& r_p_value, + std::pair<entry_pointer, size_type>& r_pos) const + { + _GLIBCXX_DEBUG_ASSERT(r_p_value != NULL); + r_pos.first = r_pos.first->m_p_next; + if (r_pos.first != NULL) + { + r_p_value = &r_pos.first->m_value; + return; + } + + for (++r_pos.second; r_pos.second < m_num_e; ++r_pos.second) + if (m_entries[r_pos.second] != NULL) + { + r_pos.first = m_entries[r_pos.second]; + r_p_value = &r_pos.first->m_value; + return; + } + r_p_value = NULL; + } + + void + get_start_it_state(pointer& r_p_value, + std::pair<entry_pointer, size_type>& r_pos) const + { + for (r_pos.second = 0; r_pos.second < m_num_e; ++r_pos.second) + if (m_entries[r_pos.second] != NULL) + { + r_pos.first = m_entries[r_pos.second]; + r_p_value = &r_pos.first->m_value; + return; + } + r_p_value = NULL; + } + +#ifdef _GLIBCXX_DEBUG + void + assert_entry_pointer_array_valid(const entry_pointer_array) const; + + void + assert_entry_pointer_valid(const entry_pointer, true_type) const; + + void + assert_entry_pointer_valid(const entry_pointer, false_type) const; +#endif + +#ifdef PB_DS_HT_MAP_TRACE_ + void + trace_list(const_entry_pointer) const; +#endif + + private: +#ifdef PB_DS_DATA_TRUE_INDICATOR + friend class iterator_; +#endif + + friend class const_iterator_; + + static entry_allocator s_entry_allocator; + static entry_pointer_allocator s_entry_pointer_allocator; + static iterator s_end_it; + static const_iterator s_const_end_it; + static point_iterator s_find_end_it; + static const_point_iterator s_const_find_end_it; + + size_type m_num_e; + size_type m_num_used_e; + entry_pointer_array m_entries; + + enum + { + store_hash_ok = !Store_Hash + || !is_same<Hash_Fn, pb_ds::null_hash_fn>::value + }; + + PB_DS_STATIC_ASSERT(sth, store_hash_ok); + }; + +#include <ext/pb_ds/detail/cc_hash_table_map_/constructor_destructor_fn_imps.hpp> +#include <ext/pb_ds/detail/cc_hash_table_map_/entry_list_fn_imps.hpp> +#include <ext/pb_ds/detail/cc_hash_table_map_/find_fn_imps.hpp> +#include <ext/pb_ds/detail/cc_hash_table_map_/resize_fn_imps.hpp> +#include <ext/pb_ds/detail/cc_hash_table_map_/debug_fn_imps.hpp> +#include <ext/pb_ds/detail/cc_hash_table_map_/size_fn_imps.hpp> +#include <ext/pb_ds/detail/cc_hash_table_map_/policy_access_fn_imps.hpp> +#include <ext/pb_ds/detail/cc_hash_table_map_/erase_fn_imps.hpp> +#include <ext/pb_ds/detail/cc_hash_table_map_/iterators_fn_imps.hpp> +#include <ext/pb_ds/detail/cc_hash_table_map_/insert_fn_imps.hpp> +#include <ext/pb_ds/detail/cc_hash_table_map_/trace_fn_imps.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_HASH_EQ_FN_C_DEC +#undef PB_DS_RANGED_HASH_FN_C_DEC +#undef PB_DS_TYPES_TRAITS_C_DEC +#undef PB_DS_MAP_DEBUG_BASE_C_DEC +#undef PB_DS_CLASS_NAME +#undef PB_DS_V2F +#undef PB_DS_V2S +#undef PB_DS_STATIC_ASSERT + + } // namespace detail +} // namespace pb_ds + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/cmp_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/cmp_fn_imps.hpp new file mode 100644 index 000000000000..9223da5d6f93 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/cmp_fn_imps.hpp @@ -0,0 +1,89 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file cmp_fn_imps.hpp + * Contains implementations of cc_ht_map_'s entire container comparison related + * functions. + */ + +PB_DS_CLASS_T_DEC +template<typename Other_HT_Map_Type> +bool +PB_DS_CLASS_C_DEC:: +operator==(const Other_HT_Map_Type& other) const +{ return cmp_with_other(other); } + +PB_DS_CLASS_T_DEC +template<typename Other_Map_Type> +bool +PB_DS_CLASS_C_DEC:: +cmp_with_other(const Other_Map_Type& other) const +{ + if (size() != other.size()) + return false; + + for (typename Other_Map_Type::const_iterator it = other.begin(); + it != other.end(); ++it) + { + const_key_reference r_key = const_key_reference(PB_DS_V2F(*it)); + + const_mapped_pointer p_mapped_value = + const_cast<PB_DS_CLASS_C_DEC& >(*this). + find_key_pointer(r_key, traits_base::m_store_hash_indicator); + + if (p_mapped_value == NULL) + return false; + +#ifdef PB_DS_DATA_TRUE_INDICATOR + if (p_mapped_value->second != it->second) + return false; +#endif + } + return true; +} + +PB_DS_CLASS_T_DEC +template<typename Other_HT_Map_Type> +bool +PB_DS_CLASS_C_DEC:: +operator!=(const Other_HT_Map_Type& other) const +{ return !operator==(other); } diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/cond_key_dtor_entry_dealtor.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/cond_key_dtor_entry_dealtor.hpp new file mode 100644 index 000000000000..bf5e0bd47106 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/cond_key_dtor_entry_dealtor.hpp @@ -0,0 +1,123 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file cond_key_dtor_entry_dealtor.hpp + * Contains a conditional key destructor, used for exception handling. + */ + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_CLASS_T_DEC template<typename HT_Map> +#define PB_DS_CLASS_C_DEC PB_DS_CKDED_CLASS_NAME<HT_Map> + + /** + * A conditional key destructor, used for exception handling. + **/ + template<typename HT_Map> + class PB_DS_CKDED_CLASS_NAME + { + public: + typedef typename HT_Map::entry entry; + typedef typename HT_Map::entry_allocator entry_allocator; + typedef typename HT_Map::key_type key_type; + + inline + PB_DS_CKDED_CLASS_NAME(entry_allocator* p_a, entry* p_e); + + inline + ~PB_DS_CKDED_CLASS_NAME(); + + inline void + set_key_destruct(); + + inline void + set_no_action_destructor(); + + protected: + entry_allocator* const m_p_a; + entry* const m_p_e; + + bool m_key_destruct; + bool m_no_action_destructor; + }; + + PB_DS_CLASS_T_DEC + inline + PB_DS_CLASS_C_DEC:: + PB_DS_CKDED_CLASS_NAME(entry_allocator* p_a, entry* p_e) + : m_p_a(p_a), m_p_e(p_e), m_key_destruct(false), + m_no_action_destructor(false) + { } + + PB_DS_CLASS_T_DEC + inline void + PB_DS_CLASS_C_DEC:: + set_key_destruct() + { m_key_destruct = true; } + + PB_DS_CLASS_T_DEC + inline void + PB_DS_CLASS_C_DEC:: + set_no_action_destructor() + { m_no_action_destructor = true; } + + PB_DS_CLASS_T_DEC + inline + PB_DS_CLASS_C_DEC:: + ~PB_DS_CKDED_CLASS_NAME() + { + if (m_no_action_destructor) + return; + if (m_key_destruct) + m_p_e->m_value.first.~key_type(); + m_p_a->deallocate(m_p_e, 1); + } + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + + } // namespace detail +} // namespace pb_ds + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/constructor_destructor_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/constructor_destructor_fn_imps.hpp new file mode 100644 index 000000000000..7da4d8a1e791 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/constructor_destructor_fn_imps.hpp @@ -0,0 +1,197 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructor_destructor_fn_imps.hpp + * Contains implementations of cc_ht_map_'s constructors, destructor, + * and related functions. + */ + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::entry_allocator +PB_DS_CLASS_C_DEC::s_entry_allocator; + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::entry_pointer_allocator +PB_DS_CLASS_C_DEC::s_entry_pointer_allocator; + +PB_DS_CLASS_T_DEC +template<typename It> +void +PB_DS_CLASS_C_DEC:: +copy_from_range(It first_it, It last_it) +{ + while (first_it != last_it) + insert(*(first_it++)); +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME() : + ranged_hash_fn_base(resize_base::get_nearest_larger_size(1)), + m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), + m_entries(s_entry_pointer_allocator.allocate(m_num_e)) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const Hash_Fn& r_hash_fn) : + ranged_hash_fn_base(resize_base::get_nearest_larger_size(1), r_hash_fn), + m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), + m_entries(s_entry_pointer_allocator.allocate(m_num_e)) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn) : + PB_DS_HASH_EQ_FN_C_DEC(r_eq_fn), + ranged_hash_fn_base(resize_base::get_nearest_larger_size(1), r_hash_fn), + m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), + m_entries(s_entry_pointer_allocator.allocate(m_num_e)) +{ + std::fill(m_entries, m_entries + m_num_e, (entry_pointer)NULL); + Resize_Policy::notify_cleared(); + ranged_hash_fn_base::notify_resized(m_num_e); + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn, const Comb_Hash_Fn& r_comb_hash_fn) : + PB_DS_HASH_EQ_FN_C_DEC(r_eq_fn), + ranged_hash_fn_base(resize_base::get_nearest_larger_size(1), + r_hash_fn, r_comb_hash_fn), + m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), + m_entries(s_entry_pointer_allocator.allocate(m_num_e)) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn, const Comb_Hash_Fn& r_comb_hash_fn, const Resize_Policy& r_resize_policy) : + PB_DS_HASH_EQ_FN_C_DEC(r_eq_fn), + Resize_Policy(r_resize_policy), + ranged_hash_fn_base(resize_base::get_nearest_larger_size(1), + r_hash_fn, r_comb_hash_fn), + m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), + m_entries(s_entry_pointer_allocator.allocate(m_num_e)) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const PB_DS_CLASS_C_DEC& other) : +#ifdef _GLIBCXX_DEBUG + map_debug_base(other), +#endif + PB_DS_HASH_EQ_FN_C_DEC(other), + resize_base(other), ranged_hash_fn_base(other), + m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), + m_entries(m_entries = s_entry_pointer_allocator.allocate(m_num_e)) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) + try + { + copy_from_range(other.begin(), other.end()); + } + catch(...) + { + deallocate_all(); + __throw_exception_again; + } + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +~PB_DS_CLASS_NAME() +{ deallocate_all(); } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid()); + _GLIBCXX_DEBUG_ONLY(other.assert_valid()); + + std::swap(m_entries, other.m_entries); + std::swap(m_num_e, other.m_num_e); + std::swap(m_num_used_e, other.m_num_used_e); + ranged_hash_fn_base::swap(other); + hash_eq_fn_base::swap(other); + resize_base::swap(other); + + _GLIBCXX_DEBUG_ONLY(map_debug_base::swap(other)); + _GLIBCXX_DEBUG_ONLY(assert_valid()); + _GLIBCXX_DEBUG_ONLY(other.assert_valid()); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +deallocate_all() +{ + clear(); + s_entry_pointer_allocator.deallocate(m_entries, m_num_e); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +initialize() +{ + std::fill(m_entries, m_entries + m_num_e, entry_pointer(NULL)); + Resize_Policy::notify_resized(m_num_e); + Resize_Policy::notify_cleared(); + ranged_hash_fn_base::notify_resized(m_num_e); +} diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/constructor_destructor_no_store_hash_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/constructor_destructor_no_store_hash_fn_imps.hpp new file mode 100644 index 000000000000..f2b41b37bca6 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/constructor_destructor_no_store_hash_fn_imps.hpp @@ -0,0 +1,61 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructor_destructor_no_store_hash_fn_imps.hpp + * Contains implementations of cc_ht_map_'s constructors, destructor, + * and related functions. + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +constructor_insert_new_imp(const_mapped_reference r_val, size_type pos, + false_type) +{ + // Following lines might throw an exception. + entry_pointer p = get_entry(r_val, traits_base::s_no_throw_copies_indicator); + + // At this point no exceptions can be thrown. + p->m_p_next = m_entries[pos]; + m_entries[pos] = p; + _GLIBCXX_DEBUG_ONLY(map_debug_base::insert_new(r_key);) +} diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/constructor_destructor_store_hash_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/constructor_destructor_store_hash_fn_imps.hpp new file mode 100644 index 000000000000..08a0b7b3fce1 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/constructor_destructor_store_hash_fn_imps.hpp @@ -0,0 +1,62 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructor_destructor_store_hash_fn_imps.hpp + * Contains implementations of cc_ht_map_'s constructors, destructor, + * and related functions. + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +constructor_insert_new_imp(const_reference r_val, size_type pos, true_type) +{ + // Following lines might throw an exception. + entry_pointer p = get_entry(r_val, traits_base::s_no_throw_copies_indicator); + + // At this point no exceptions can be thrown. + p->m_p_next = m_entries[pos]; + p->m_hash = ranged_hash_fn_base::operator()((const_key_reference)(PB_DS_V2F(p->m_value))).second; + + m_entries[pos] = p; + _GLIBCXX_DEBUG_ONLY(map_debug_base::insert_new(r_key);) +} diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/debug_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/debug_fn_imps.hpp new file mode 100644 index 000000000000..61cbfa90d2e1 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/debug_fn_imps.hpp @@ -0,0 +1,80 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_fn_imps.hpp + * Contains implementations of cc_ht_map_'s debug-mode functions. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_valid() const +{ + map_debug_base::check_size(m_num_used_e); + assert_entry_pointer_array_valid(m_entries); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_entry_pointer_array_valid(const entry_pointer_array a_p_entries) const +{ + size_type iterated_num_used_e = 0; + for (size_type pos = 0; pos < m_num_e; ++pos) + { + entry_pointer p_e = a_p_entries[pos]; + while (p_e != NULL) + { + ++iterated_num_used_e; + assert_entry_pointer_valid(p_e, traits_base::m_store_hash_indicator); + p_e = p_e->m_p_next; + } + } + _GLIBCXX_DEBUG_ASSERT(iterated_num_used_e == m_num_used_e); +} + +#include <ext/pb_ds/detail/cc_hash_table_map_/debug_store_hash_fn_imps.hpp> +#include <ext/pb_ds/detail/cc_hash_table_map_/debug_no_store_hash_fn_imps.hpp> + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/debug_no_store_hash_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/debug_no_store_hash_fn_imps.hpp new file mode 100644 index 000000000000..d179a3dc941a --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/debug_no_store_hash_fn_imps.hpp @@ -0,0 +1,55 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_no_store_hash_fn_imps.hpp + * Contains implementations of cc_ht_map_'s debug-mode functions. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_entry_pointer_valid(const entry_pointer p, false_type) const +{ map_debug_base::check_key_exists(PB_DS_V2F(p->m_value)); } + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/debug_store_hash_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/debug_store_hash_fn_imps.hpp new file mode 100644 index 000000000000..48dc555abea2 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/debug_store_hash_fn_imps.hpp @@ -0,0 +1,59 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_store_hash_fn_imps.hpp + * Contains implementations of cc_ht_map_'s debug-mode functions. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_entry_pointer_valid(const entry_pointer p_e, true_type) const +{ + map_debug_base::check_key_exists(PB_DS_V2F(p_e->m_value)); + comp_hash pos_hash_pair = ranged_hash_fn_base::operator()(PB_DS_V2F(p_e->m_value)); + _GLIBCXX_DEBUG_ASSERT(p_e->m_hash == pos_hash_pair.second); +} + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/entry_list_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/entry_list_fn_imps.hpp new file mode 100644 index 000000000000..b8871630854e --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/entry_list_fn_imps.hpp @@ -0,0 +1,97 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file entry_list_fn_imps.hpp + * Contains implementations of cc_ht_map_'s entry-list related functions. + */ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +deallocate_links_in_list(entry_pointer p_e) +{ + while (p_e != NULL) + { + entry_pointer p_dealloc_e = p_e; + p_e = p_e->m_p_next; + s_entry_allocator.deallocate(p_dealloc_e, 1); + } +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::entry_pointer +PB_DS_CLASS_C_DEC:: +get_entry(const_reference r_val, true_type) +{ + // Following line might throw an exception. + entry_pointer p_e = s_entry_allocator.allocate(1); + + // Following lines* cannot* throw an exception. + new (&p_e->m_value) value_type(r_val); + return p_e; +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::entry_pointer +PB_DS_CLASS_C_DEC:: +get_entry(const_reference r_val, false_type) +{ + // Following line might throw an exception. + entry_pointer p_e = s_entry_allocator.allocate(1); + cond_dealtor_t cond(p_e); + + // Following lines might throw an exception. + new (&p_e->m_value) value_type(r_val); + cond.set_no_action(); + return p_e; +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +rels_entry(entry_pointer p_e) +{ + // The following lines cannot throw exceptions (unless if key-data dtors do). + p_e->m_value.~value_type(); + s_entry_allocator.deallocate(p_e, 1); +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/erase_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/erase_fn_imps.hpp new file mode 100644 index 000000000000..265a7052780f --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/erase_fn_imps.hpp @@ -0,0 +1,109 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file erase_fn_imps.hpp + * Contains implementations of cc_ht_map_'s erase related functions. + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +erase_entry_pointer(entry_pointer& r_p_e) +{ + _GLIBCXX_DEBUG_ONLY(map_debug_base::erase_existing(PB_DS_V2F(r_p_e->m_value))); + + entry_pointer p_e = r_p_e; + r_p_e = r_p_e->m_p_next; + rels_entry(p_e); + _GLIBCXX_DEBUG_ASSERT(m_num_used_e > 0); + resize_base::notify_erased(--m_num_used_e); +} + +PB_DS_CLASS_T_DEC +template<typename Pred> +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +erase_if(Pred pred) +{ + size_type num_ersd = 0; + for (size_type pos = 0; pos < m_num_e; ++pos) + { + while (m_entries[pos] != NULL && pred(m_entries[pos]->m_value)) + { + ++num_ersd; + entry_pointer p_next_e = m_entries[pos]->m_p_next; + erase_entry_pointer(m_entries[pos]); + m_entries[pos] = p_next_e; + } + + entry_pointer p_e = m_entries[pos]; + while (p_e != NULL && p_e->m_p_next != NULL) + { + if (pred(p_e->m_p_next->m_value)) + { + ++num_ersd; + erase_entry_pointer(p_e->m_p_next); + } + else + p_e = p_e->m_p_next; + } + } + + do_resize_if_needed_no_throw(); + return num_ersd; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +clear() +{ + for (size_type pos = 0; pos < m_num_e; ++pos) + while (m_entries[pos] != NULL) + erase_entry_pointer(m_entries[pos]); + do_resize_if_needed_no_throw(); + resize_base::notify_cleared(); +} + +#include <ext/pb_ds/detail/cc_hash_table_map_/erase_no_store_hash_fn_imps.hpp> +#include <ext/pb_ds/detail/cc_hash_table_map_/erase_store_hash_fn_imps.hpp> + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/erase_no_store_hash_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/erase_no_store_hash_fn_imps.hpp new file mode 100644 index 000000000000..13a3a6d4d34a --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/erase_no_store_hash_fn_imps.hpp @@ -0,0 +1,107 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file erase_no_store_hash_fn_imps.hpp + * Contains implementations of cc_ht_map_'s erase related functions, + * when the hash value is not stored. + */ + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +erase(const_key_reference r_key) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return erase_in_pos_imp(r_key, ranged_hash_fn_base::operator()(r_key)); +} + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +erase_in_pos_imp(const_key_reference r_key, size_type pos) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + entry_pointer p_e = m_entries[pos]; + resize_base::notify_erase_search_start(); + if (p_e == NULL) + { + resize_base::notify_erase_search_end(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key);) + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return false; + } + + if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), r_key)) + { + resize_base::notify_erase_search_end(); + _GLIBCXX_DEBUG_ONLY(map_debug_base:: check_key_exists(r_key);) + erase_entry_pointer(m_entries[pos]); + do_resize_if_needed_no_throw(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return true; + } + + while (true) + { + entry_pointer p_next_e = p_e->m_p_next; + if (p_next_e == NULL) + { + resize_base::notify_erase_search_end(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key);) + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return false; + } + + if (hash_eq_fn_base::operator()(PB_DS_V2F(p_next_e->m_value), r_key)) + { + resize_base::notify_erase_search_end(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(r_key);) + erase_entry_pointer(p_e->m_p_next); + do_resize_if_needed_no_throw(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return true; + } + resize_base::notify_erase_search_collision(); + p_e = p_next_e; + } +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/erase_store_hash_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/erase_store_hash_fn_imps.hpp new file mode 100644 index 000000000000..7eb821e0fe68 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/erase_store_hash_fn_imps.hpp @@ -0,0 +1,101 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file erase_store_hash_fn_imps.hpp + * Contains implementations of cc_ht_map_'s erase related functions, + * when the hash value is stored. + */ + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +erase_in_pos_imp(const_key_reference r_key, const comp_hash& r_pos_hash_pair) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + entry_pointer p_e = m_entries[r_pos_hash_pair.first]; + resize_base::notify_erase_search_start(); + if (p_e == NULL) + { + resize_base::notify_erase_search_end(); + _GLIBCXX_DEBUG_ONLY(map_debug_base:: check_key_does_not_exist(r_key);) + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return false; + } + + if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), p_e->m_hash, + r_key, r_pos_hash_pair.second)) + { + resize_base::notify_erase_search_end(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(r_key);) + erase_entry_pointer(m_entries[r_pos_hash_pair.first]); + do_resize_if_needed_no_throw(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return true; + } + + while (true) + { + entry_pointer p_next_e = p_e->m_p_next; + if (p_next_e == NULL) + { + resize_base::notify_erase_search_end(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key);) + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return false; + } + + if (hash_eq_fn_base::operator()(PB_DS_V2F(p_next_e->m_value), + p_next_e->m_hash, r_key, + r_pos_hash_pair.second)) + { + resize_base::notify_erase_search_end(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(r_key);) + erase_entry_pointer(p_e->m_p_next); + do_resize_if_needed_no_throw(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return true; + } + resize_base::notify_erase_search_collision(); + p_e = p_next_e; + } +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/find_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/find_fn_imps.hpp new file mode 100644 index 000000000000..1a726643d0ce --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/find_fn_imps.hpp @@ -0,0 +1,77 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file find_fn_imps.hpp + * Contains implementations of cc_ht_map_'s find related functions. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::point_iterator +PB_DS_CLASS_C_DEC:: +find(const_key_reference r_key) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return find_key_pointer(r_key, traits_base::m_store_extra_indicator); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_point_iterator +PB_DS_CLASS_C_DEC:: +find(const_key_reference r_key) const +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return const_cast<PB_DS_CLASS_C_DEC& >(*this).find_key_pointer(r_key, + traits_base::m_store_extra_indicator); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::point_iterator +PB_DS_CLASS_C_DEC:: +find_end() +{ return NULL; } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_point_iterator +PB_DS_CLASS_C_DEC:: +find_end() const +{ return NULL; } + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/find_store_hash_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/find_store_hash_fn_imps.hpp new file mode 100644 index 000000000000..423a59a9f48e --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/find_store_hash_fn_imps.hpp @@ -0,0 +1,47 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file find_store_hash_fn_imps.hpp + * Contains implementations of cc_ht_map_'s find related functions, + * when the hash value is stored. + */ + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/info_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/info_fn_imps.hpp new file mode 100644 index 000000000000..519072a2e9e6 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/info_fn_imps.hpp @@ -0,0 +1,106 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file info_fn_imps.hpp + * Contains implementations of cc_ht_map_'s entire container info related + * functions. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +size() const +{ return m_num_used_e; } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +max_size() const +{ return m_entry_allocator.max_size(); } + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +empty() const +{ return (size() == 0); } + +PB_DS_CLASS_T_DEC +template<typename Other_HT_Map_Type> +bool +PB_DS_CLASS_C_DEC:: +operator==(const Other_HT_Map_Type& other) const +{ return cmp_with_other(other); } + +PB_DS_CLASS_T_DEC +template<typename Other_Map_Type> +bool +PB_DS_CLASS_C_DEC:: +cmp_with_other(const Other_Map_Type& other) const +{ + if (size() != other.size()) + return false; + + for (typename Other_Map_Type::const_iterator it = other.begin(); + it != other.end(); ++it) + { + const_key_reference r_key =(const_key_reference)PB_DS_V2F(*it); + const_mapped_pointer p_mapped_value = + const_cast<PB_DS_CLASS_C_DEC& >(*this). + find_key_pointer(r_key, traits_base::m_store_hash_indicator); + + if (p_mapped_value == NULL) + return false; + +#ifdef PB_DS_DATA_TRUE_INDICATOR + if (p_mapped_value->second != it->second) + return false; +#endif + } + return true; +} + +PB_DS_CLASS_T_DEC +template<typename Other_HT_Map_Type> +bool +PB_DS_CLASS_C_DEC:: +operator!=(const Other_HT_Map_Type& other) const +{ return !operator==(other); } diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/insert_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/insert_fn_imps.hpp new file mode 100644 index 000000000000..27260735c634 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/insert_fn_imps.hpp @@ -0,0 +1,49 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file insert_fn_imps.hpp + * Contains implementations of cc_ht_map_'s insert related functions. + */ + +#include <ext/pb_ds/detail/cc_hash_table_map_/insert_no_store_hash_fn_imps.hpp> +#include <ext/pb_ds/detail/cc_hash_table_map_/insert_store_hash_fn_imps.hpp> + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/insert_no_store_hash_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/insert_no_store_hash_fn_imps.hpp new file mode 100644 index 000000000000..fd158f921ad3 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/insert_no_store_hash_fn_imps.hpp @@ -0,0 +1,76 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file insert_no_store_hash_fn_imps.hpp + * Contains implementations of cc_ht_map_'s insert related functions, + * when the hash value is not stored. + */ + +PB_DS_CLASS_T_DEC +inline std::pair<typename PB_DS_CLASS_C_DEC::point_iterator, bool> +PB_DS_CLASS_C_DEC:: +insert_imp(const_reference r_val, false_type) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + const_key_reference r_key = PB_DS_V2F(r_val); + const size_type pos = ranged_hash_fn_base::operator()(r_key); + entry_pointer p_e = m_entries[pos]; + resize_base::notify_insert_search_start(); + + while (p_e != NULL && !hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), + r_key)) + { + resize_base::notify_insert_search_collision(); + p_e = p_e->m_p_next; + } + + resize_base::notify_insert_search_end(); + if (p_e != NULL) + { + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(r_key);) + return std::make_pair(&p_e->m_value, false); + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key);) + return std::make_pair(insert_new_imp(r_val, pos), true); +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/insert_store_hash_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/insert_store_hash_fn_imps.hpp new file mode 100644 index 000000000000..128e11fdc0fc --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/insert_store_hash_fn_imps.hpp @@ -0,0 +1,77 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file insert_store_hash_fn_imps.hpp + * Contains implementations of cc_ht_map_'s insert related functions, + * when the hash value is stored. + */ + +PB_DS_CLASS_T_DEC +inline std::pair<typename PB_DS_CLASS_C_DEC::point_iterator, bool> +PB_DS_CLASS_C_DEC:: +insert_imp(const_reference r_val, true_type) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + const_key_reference key = PB_DS_V2F(r_val); + comp_hash pos_hash_pair = ranged_hash_fn_base::operator()(key); + entry_pointer p_e = m_entries[pos_hash_pair.first]; + resize_base::notify_insert_search_start(); + + while (p_e != NULL && !hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), + p_e->m_hash, + key, pos_hash_pair.second)) + { + resize_base::notify_insert_search_collision(); + p_e = p_e->m_p_next; + } + + resize_base::notify_insert_search_end(); + if (p_e != NULL) + { + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(key);) + return std::make_pair(&p_e->m_value, false); + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(key);) + return std::make_pair(insert_new_imp(r_val, pos_hash_pair), true); +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/iterators_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/iterators_fn_imps.hpp new file mode 100644 index 000000000000..2c4f6ae2f69a --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/iterators_fn_imps.hpp @@ -0,0 +1,89 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file iterators_fn_imps.hpp + * Contains implementations of cc_ht_map_'s iterators related functions, e.g., + * begin(). + */ + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC::s_end_it; + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC::s_const_end_it; + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +begin() +{ + pointer p_value; + std::pair<entry_pointer, size_type> pos; + get_start_it_state(p_value, pos); + return iterator(p_value, pos, this); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +end() +{ return s_end_it; } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +begin() const +{ + pointer p_value; + std::pair<entry_pointer, size_type> pos; + get_start_it_state(p_value, pos); + return const_iterator(p_value, pos, this); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +end() const +{ return s_const_end_it; } + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/policy_access_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/policy_access_fn_imps.hpp new file mode 100644 index 000000000000..6c03d45ad12a --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/policy_access_fn_imps.hpp @@ -0,0 +1,94 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file policy_access_fn_imps.hpp + * Contains implementations of cc_ht_map_'s policy access + * functions. + */ + +PB_DS_CLASS_T_DEC +Hash_Fn& +PB_DS_CLASS_C_DEC:: +get_hash_fn() +{ return *this; } + +PB_DS_CLASS_T_DEC +const Hash_Fn& +PB_DS_CLASS_C_DEC:: +get_hash_fn() const +{ return *this; } + +PB_DS_CLASS_T_DEC +Eq_Fn& +PB_DS_CLASS_C_DEC:: +get_eq_fn() +{ return *this; } + +PB_DS_CLASS_T_DEC +const Eq_Fn& +PB_DS_CLASS_C_DEC:: +get_eq_fn() const +{ return *this; } + +PB_DS_CLASS_T_DEC +Comb_Hash_Fn& +PB_DS_CLASS_C_DEC:: +get_comb_hash_fn() +{ return *this; } + +PB_DS_CLASS_T_DEC +const Comb_Hash_Fn& +PB_DS_CLASS_C_DEC:: +get_comb_hash_fn() const +{ return *this; } + +PB_DS_CLASS_T_DEC +Resize_Policy& +PB_DS_CLASS_C_DEC:: +get_resize_policy() +{ return *this; } + +PB_DS_CLASS_T_DEC +const Resize_Policy& +PB_DS_CLASS_C_DEC:: +get_resize_policy() const +{ return *this; } diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/resize_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/resize_fn_imps.hpp new file mode 100644 index 000000000000..eda2c48da52e --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/resize_fn_imps.hpp @@ -0,0 +1,139 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file resize_fn_imps.hpp + * Contains implementations of cc_ht_map_'s resize related functions. + */ + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +do_resize_if_needed() +{ + if (!resize_base::is_resize_needed()) + return false; + resize_imp(resize_base::get_new_size(m_num_e, m_num_used_e)); + return true; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +do_resize(size_type len) +{ resize_imp(resize_base::get_nearest_larger_size(len)); } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +do_resize_if_needed_no_throw() +{ + if (!resize_base::is_resize_needed()) + return; + + try + { + resize_imp(resize_base::get_new_size(m_num_e, m_num_used_e)); + } + catch(...) + { } + + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +resize_imp(size_type new_size) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + if (new_size == m_num_e) + return; + + const size_type old_size = m_num_e; + entry_pointer_array a_p_entries_resized; + + // Following line might throw an exception. + ranged_hash_fn_base::notify_resized(new_size); + + try + { + // Following line might throw an exception. + a_p_entries_resized = s_entry_pointer_allocator.allocate(new_size); + m_num_e = new_size; + } + catch(...) + { + ranged_hash_fn_base::notify_resized(old_size); + __throw_exception_again; + } + + // At this point no exceptions can be thrown. + resize_imp_no_exceptions(new_size, a_p_entries_resized, old_size); + Resize_Policy::notify_resized(new_size); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +resize_imp_no_exceptions(size_type new_size, entry_pointer_array a_p_entries_resized, size_type old_size) +{ + std::fill(a_p_entries_resized, a_p_entries_resized + m_num_e, + entry_pointer(NULL)); + + for (size_type pos = 0; pos < old_size; ++pos) + { + entry_pointer p_e = m_entries[pos]; + while (p_e != NULL) + p_e = resize_imp_no_exceptions_reassign_pointer(p_e, a_p_entries_resized, traits_base::m_store_extra_indicator); + } + + m_num_e = new_size; + _GLIBCXX_DEBUG_ONLY(assert_entry_pointer_array_valid(a_p_entries_resized);) + s_entry_pointer_allocator.deallocate(m_entries, old_size); + m_entries = a_p_entries_resized; + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +#include <ext/pb_ds/detail/cc_hash_table_map_/resize_no_store_hash_fn_imps.hpp> +#include <ext/pb_ds/detail/cc_hash_table_map_/resize_store_hash_fn_imps.hpp> + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/resize_no_store_hash_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/resize_no_store_hash_fn_imps.hpp new file mode 100644 index 000000000000..5fb7f9ddf0d6 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/resize_no_store_hash_fn_imps.hpp @@ -0,0 +1,60 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file resize_no_store_hash_fn_imps.hpp + * Contains implementations of cc_ht_map_'s resize related functions, when the + * hash value is not stored. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::entry_pointer +PB_DS_CLASS_C_DEC:: +resize_imp_no_exceptions_reassign_pointer(entry_pointer p_e, entry_pointer_array a_p_entries_resized, false_type) +{ + const size_type hash_pos = + ranged_hash_fn_base::operator()(PB_DS_V2F(p_e->m_value)); + + entry_pointer const p_next_e = p_e->m_p_next; + p_e->m_p_next = a_p_entries_resized[hash_pos]; + a_p_entries_resized[hash_pos] = p_e; + return p_next_e; +} diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/resize_store_hash_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/resize_store_hash_fn_imps.hpp new file mode 100644 index 000000000000..387410599e55 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/resize_store_hash_fn_imps.hpp @@ -0,0 +1,60 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file resize_store_hash_fn_imps.hpp + * Contains implementations of cc_ht_map_'s resize related functions, when the + * hash value is stored. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::entry_pointer +PB_DS_CLASS_C_DEC:: +resize_imp_no_exceptions_reassign_pointer(entry_pointer p_e, entry_pointer_array a_p_entries_resized, true_type) +{ + const comp_hash pos_hash_pair = + ranged_hash_fn_base::operator()(PB_DS_V2F(p_e->m_value), p_e->m_hash); + + entry_pointer const p_next_e = p_e->m_p_next; + p_e->m_p_next = a_p_entries_resized[pos_hash_pair.first]; + a_p_entries_resized[pos_hash_pair.first] = p_e; + return p_next_e; +} diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/size_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/size_fn_imps.hpp new file mode 100644 index 000000000000..8fee0104d7a3 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/size_fn_imps.hpp @@ -0,0 +1,65 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file size_fn_imps.hpp + * Contains implementations of cc_ht_map_'s entire container size related + * functions. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +size() const +{ return m_num_used_e; } + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +empty() const +{ return (size() == 0); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +max_size() const +{ return s_entry_allocator.max_size(); } + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/standard_policies.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/standard_policies.hpp new file mode 100644 index 000000000000..dc175b138654 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/standard_policies.hpp @@ -0,0 +1,52 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file standard_policies.hpp + * Contains standard policies for cc_ht_map types. + */ + +#ifndef PB_DS_CC_HT_MAP_STANDARD_POLICIES_HPP +#define PB_DS_CC_HT_MAP_STANDARD_POLICIES_HPP + +#include <ext/pb_ds/detail/standard_policies.hpp> + +#endif // #ifndef PB_DS_CC_HT_MAP_STANDARD_POLICIES_HPP diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/trace_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/trace_fn_imps.hpp new file mode 100644 index 000000000000..21097de07d77 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/cc_hash_table_map_/trace_fn_imps.hpp @@ -0,0 +1,78 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file trace_fn_imps.hpp + * Contains implementations of cc_ht_map_'s trace-mode functions. + */ + +#ifdef PB_DS_HT_MAP_TRACE_ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +trace() const +{ + std::cerr << static_cast<unsigned long>(m_num_e) << " " + << static_cast<unsigned long>(m_num_used_e) << std::endl; + + for (size_type i = 0; i < m_num_e; ++i) + { + std::cerr << static_cast<unsigned long>(i) << " "; + trace_list(m_entries[i]); + std::cerr << std::endl; + } +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +trace_list(const_entry_pointer p_l) const +{ + size_type iterated_num_used_e = 0; + while (p_l != NULL) + { + std::cerr << PB_DS_V2F(p_l->m_value) << " "; + p_l = p_l->m_p_next; + } +} + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/cond_dealtor.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/cond_dealtor.hpp new file mode 100644 index 000000000000..3cf9ea91fa31 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/cond_dealtor.hpp @@ -0,0 +1,131 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file cond_dealtor.hpp + * Contains a conditional deallocator. + */ + +#ifndef PB_DS_COND_DEALTOR_HPP +#define PB_DS_COND_DEALTOR_HPP + +namespace pb_ds +{ + + namespace detail + { + +#define PB_DS_COND_DEALTOR_CLASS_T_DEC \ + template<typename Entry, class Allocator> + +#define PB_DS_COND_DEALTOR_CLASS_C_DEC \ + cond_dealtor< \ + Entry, \ + Allocator> + + template<typename Entry, class Allocator> + class cond_dealtor + { + public: + typedef + typename Allocator::template rebind<Entry>::other + entry_allocator; + + typedef typename entry_allocator::pointer entry_pointer; + + public: + inline + cond_dealtor(entry_pointer p_e); + + inline + ~cond_dealtor(); + + inline void + set_no_action(); + + private: + entry_pointer m_p_e; + + bool m_no_action_destructor; + + static entry_allocator s_alloc; + }; + + PB_DS_COND_DEALTOR_CLASS_T_DEC + typename PB_DS_COND_DEALTOR_CLASS_C_DEC::entry_allocator + PB_DS_COND_DEALTOR_CLASS_C_DEC::s_alloc; + + PB_DS_COND_DEALTOR_CLASS_T_DEC + inline + PB_DS_COND_DEALTOR_CLASS_C_DEC:: + cond_dealtor(entry_pointer p_e) : + m_p_e(p_e), + m_no_action_destructor(false) + { } + + PB_DS_COND_DEALTOR_CLASS_T_DEC + inline void + PB_DS_COND_DEALTOR_CLASS_C_DEC:: + set_no_action() + { + m_no_action_destructor = true; + } + + PB_DS_COND_DEALTOR_CLASS_T_DEC + inline + PB_DS_COND_DEALTOR_CLASS_C_DEC:: + ~cond_dealtor() + { + if (m_no_action_destructor) + return; + + s_alloc.deallocate(m_p_e, 1); + } + +#undef PB_DS_COND_DEALTOR_CLASS_T_DEC +#undef PB_DS_COND_DEALTOR_CLASS_C_DEC + + } // namespace detail + +} // namespace pb_ds + +#endif // #ifndef PB_DS_COND_DEALTOR_HPP + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/constructors_destructor_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/constructors_destructor_fn_imps.hpp new file mode 100644 index 000000000000..91763669c767 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/constructors_destructor_fn_imps.hpp @@ -0,0 +1,109 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructors_destructor_fn_imps.hpp + * Contains constructors_destructor_fn_imps applicable to different containers. + */ + +inline +PB_DS_CLASS_NAME() +{ } + +inline +PB_DS_CLASS_NAME(const PB_DS_CLASS_NAME& other) +: base_type((const base_type&)other) +{ } + +template<typename T0> +inline +PB_DS_CLASS_NAME(T0 t0) : base_type(t0) +{ } + +template<typename T0, typename T1> +inline +PB_DS_CLASS_NAME(T0 t0, T1 t1) : base_type(t0, t1) +{ } + +template<typename T0, typename T1, typename T2> +inline +PB_DS_CLASS_NAME(T0 t0, T1 t1, T2 t2) : base_type(t0, t1, t2) +{ } + +template<typename T0, typename T1, typename T2, typename T3> +inline +PB_DS_CLASS_NAME(T0 t0, T1 t1, T2 t2, T3 t3) +: base_type(t0, t1, t2, t3) +{ } + +template<typename T0, typename T1, typename T2, typename T3, typename T4> +inline +PB_DS_CLASS_NAME(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4) +: base_type(t0, t1, t2, t3, t4) +{ } + +template<typename T0, typename T1, typename T2, typename T3, typename T4, + typename T5> +inline +PB_DS_CLASS_NAME(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) +: base_type(t0, t1, t2, t3, t4, t5) +{ } + +template<typename T0, typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6> +inline +PB_DS_CLASS_NAME(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) +: base_type(t0, t1, t2, t3, t4, t5, t6) +{ } + +template<typename T0, typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6, typename T7> +inline +PB_DS_CLASS_NAME(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7) +: base_type(t0, t1, t2, t3, t4, t5, t6, t7) +{ } + +template<typename T0, typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6, typename T7, typename T8> +inline +PB_DS_CLASS_NAME(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8) +: base_type(t0, t1, t2, t3, t4, t5, t6, t7, t8) +{ } diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/container_base_dispatch.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/container_base_dispatch.hpp new file mode 100644 index 000000000000..37db003fd751 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/container_base_dispatch.hpp @@ -0,0 +1,338 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file container_base_dispatch.hpp + * Contains an associative container dispatching base. + */ + +#ifndef PB_DS_ASSOC_CNTNR_BASE_DS_DISPATCHER_HPP +#define PB_DS_ASSOC_CNTNR_BASE_DS_DISPATCHER_HPP + +#include <ext/typelist.h> + +#define PB_DS_DATA_TRUE_INDICATOR +#include <ext/pb_ds/detail/list_update_map_/lu_map_.hpp> +#undef PB_DS_DATA_TRUE_INDICATOR + +#define PB_DS_DATA_FALSE_INDICATOR +#include <ext/pb_ds/detail/list_update_map_/lu_map_.hpp> +#undef PB_DS_DATA_FALSE_INDICATOR + +#define PB_DS_DATA_TRUE_INDICATOR +#include <ext/pb_ds/detail/rb_tree_map_/rb_tree_.hpp> +#undef PB_DS_DATA_TRUE_INDICATOR + +#define PB_DS_DATA_FALSE_INDICATOR +#include <ext/pb_ds/detail/rb_tree_map_/rb_tree_.hpp> +#undef PB_DS_DATA_FALSE_INDICATOR + +#define PB_DS_DATA_TRUE_INDICATOR +#include <ext/pb_ds/detail/splay_tree_/splay_tree_.hpp> +#undef PB_DS_DATA_TRUE_INDICATOR + +#define PB_DS_DATA_FALSE_INDICATOR +#include <ext/pb_ds/detail/splay_tree_/splay_tree_.hpp> +#undef PB_DS_DATA_FALSE_INDICATOR + +#define PB_DS_DATA_TRUE_INDICATOR +#include <ext/pb_ds/detail/ov_tree_map_/ov_tree_map_.hpp> +#undef PB_DS_DATA_TRUE_INDICATOR + +#define PB_DS_DATA_FALSE_INDICATOR +#include <ext/pb_ds/detail/ov_tree_map_/ov_tree_map_.hpp> +#undef PB_DS_DATA_FALSE_INDICATOR + +#define PB_DS_DATA_TRUE_INDICATOR +#include <ext/pb_ds/detail/cc_hash_table_map_/cc_ht_map_.hpp> +#undef PB_DS_DATA_TRUE_INDICATOR + +#define PB_DS_DATA_FALSE_INDICATOR +#include <ext/pb_ds/detail/cc_hash_table_map_/cc_ht_map_.hpp> +#undef PB_DS_DATA_FALSE_INDICATOR + +#define PB_DS_DATA_TRUE_INDICATOR +#include <ext/pb_ds/detail/gp_hash_table_map_/gp_ht_map_.hpp> +#undef PB_DS_DATA_TRUE_INDICATOR + +#define PB_DS_DATA_FALSE_INDICATOR +#include <ext/pb_ds/detail/gp_hash_table_map_/gp_ht_map_.hpp> +#undef PB_DS_DATA_FALSE_INDICATOR + +#define PB_DS_DATA_TRUE_INDICATOR +#include <ext/pb_ds/detail/pat_trie_/pat_trie_.hpp> +#undef PB_DS_DATA_TRUE_INDICATOR + +#define PB_DS_DATA_FALSE_INDICATOR +#include <ext/pb_ds/detail/pat_trie_/pat_trie_.hpp> +#undef PB_DS_DATA_FALSE_INDICATOR + +namespace pb_ds +{ +namespace detail +{ + // Primary template. + template<typename Key, typename Mapped, typename Data_Structure_Taq, + typename Policy_Tl, typename Alloc> + struct container_base_dispatch; + + template<typename Key, typename Mapped, typename Policy_Tl, typename Alloc> + struct container_base_dispatch<Key, Mapped, list_update_tag, + Policy_Tl, Alloc> + { + private: + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 0> at0; + typedef typename at0::type at0t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; + typedef typename at1::type at1t; + + public: + typedef lu_map_data_<Key, Mapped, at0t, Alloc, at1t> type; + }; + + template<typename Key, typename Policy_Tl, typename Alloc> + struct container_base_dispatch<Key, null_mapped_type, list_update_tag, + Policy_Tl, Alloc> + { + private: + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 0> at0; + typedef typename at0::type at0t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; + typedef typename at1::type at1t; + + public: + typedef lu_map_no_data_<Key, null_mapped_type, at0t, Alloc, at1t> type; + }; + + template<typename Key, typename Mapped, typename Policy_Tl, typename Alloc> + struct container_base_dispatch<Key, Mapped, pat_trie_tag, Policy_Tl, Alloc> + { + private: + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; + typedef typename at1::type at1t; + + public: + typedef pat_trie_data_<Key, Mapped, at1t, Alloc> type; + }; + + template<typename Key, typename Policy_Tl, typename Alloc> + struct container_base_dispatch<Key, null_mapped_type, pat_trie_tag, + Policy_Tl, Alloc> + { + private: + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; + typedef typename at1::type at1t; + + public: + typedef pat_trie_no_data_<Key, null_mapped_type, at1t, Alloc> type; + }; + + template<typename Key, typename Mapped, typename Policy_Tl, typename Alloc> + struct container_base_dispatch<Key, Mapped, rb_tree_tag, Policy_Tl, Alloc> + { + private: + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 0> at0; + typedef typename at0::type at0t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; + typedef typename at1::type at1t; + + public: + typedef rb_tree_data_<Key, Mapped, at0t, at1t, Alloc> type; + }; + + template<typename Key, typename Policy_Tl, typename Alloc> + struct container_base_dispatch<Key, null_mapped_type, rb_tree_tag, + Policy_Tl, Alloc> + { + private: + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 0> at0; + typedef typename at0::type at0t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; + typedef typename at1::type at1t; + + public: + typedef rb_tree_no_data_<Key, null_mapped_type, at0t, at1t, Alloc> type; + }; + + template<typename Key, typename Mapped, typename Policy_Tl, typename Alloc> + struct container_base_dispatch<Key, Mapped, splay_tree_tag, + Policy_Tl, Alloc> + { + private: + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 0> at0; + typedef typename at0::type at0t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; + typedef typename at1::type at1t; + + public: + typedef splay_tree_data_<Key, Mapped, at0t, at1t, Alloc> type; + }; + + template<typename Key, typename Policy_Tl, typename Alloc> + struct container_base_dispatch<Key, null_mapped_type, splay_tree_tag, + Policy_Tl, Alloc> + { + private: + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 0> at0; + typedef typename at0::type at0t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; + typedef typename at1::type at1t; + + public: + typedef splay_tree_no_data_<Key, null_mapped_type, at0t, at1t, Alloc> type; + }; + + template<typename Key, typename Mapped, typename Policy_Tl, typename Alloc> + struct container_base_dispatch<Key, Mapped, ov_tree_tag, Policy_Tl, Alloc> + { + private: + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 0> at0; + typedef typename at0::type at0t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; + typedef typename at1::type at1t; + + public: + typedef ov_tree_data_<Key, Mapped, at0t, at1t, Alloc> type; + }; + + template<typename Key, typename Policy_Tl, typename Alloc> + struct container_base_dispatch<Key, null_mapped_type, ov_tree_tag, + Policy_Tl, Alloc> + { + private: + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 0> at0; + typedef typename at0::type at0t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; + typedef typename at1::type at1t; + + public: + typedef ov_tree_no_data_<Key, null_mapped_type, at0t, at1t, Alloc> type; + }; + + template<typename Key, typename Mapped, typename Policy_Tl, typename Alloc> + struct container_base_dispatch<Key, Mapped, cc_hash_tag, Policy_Tl, Alloc> + { + private: + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 0> at0; + typedef typename at0::type at0t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; + typedef typename at1::type at1t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 2> at2; + typedef typename at2::type at2t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 3> at3; + typedef typename at3::type at3t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 4> at4; + typedef typename at4::type at4t; + + public: + typedef cc_ht_map_data_<Key, Mapped, at0t, at1t, Alloc, at3t::value, + at4t, at2t> type; + }; + + template<typename Key, typename Policy_Tl, typename Alloc> + struct container_base_dispatch<Key, null_mapped_type, cc_hash_tag, + Policy_Tl, Alloc> + { + private: + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 0> at0; + typedef typename at0::type at0t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; + typedef typename at1::type at1t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 2> at2; + typedef typename at2::type at2t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 3> at3; + typedef typename at3::type at3t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 4> at4; + typedef typename at4::type at4t; + + public: + typedef cc_ht_map_no_data_<Key, null_mapped_type, at0t, at1t, Alloc, + at3t::value, at4t, at2t> type; + }; + + template<typename Key, typename Mapped, typename Policy_Tl, typename Alloc> + struct container_base_dispatch<Key, Mapped, gp_hash_tag, Policy_Tl, Alloc> + { + private: + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 0> at0; + typedef typename at0::type at0t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; + typedef typename at1::type at1t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 2> at2; + typedef typename at2::type at2t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 3> at3; + typedef typename at3::type at3t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 4> at4; + typedef typename at4::type at4t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 5> at5; + typedef typename at5::type at5t; + + public: + typedef gp_ht_map_data_<Key, Mapped, at0t, at1t, Alloc, at3t::value, + at4t, at5t, at2t> type; + }; + + template<typename Key, typename Policy_Tl, typename Alloc> + struct container_base_dispatch<Key, null_mapped_type, gp_hash_tag, + Policy_Tl, Alloc> + { + private: + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 0> at0; + typedef typename at0::type at0t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; + typedef typename at1::type at1t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 2> at2; + typedef typename at2::type at2t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 3> at3; + typedef typename at3::type at3t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 4> at4; + typedef typename at4::type at4t; + typedef __gnu_cxx::typelist::at_index<Policy_Tl, 5> at5; + typedef typename at5::type at5t; + + public: + typedef gp_ht_map_no_data_<Key, null_mapped_type, at0t, at1t, Alloc, + at3t::value, at4t, at5t, at2t> type; + }; +} // namespace detail +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/eq_fn/eq_by_less.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/eq_fn/eq_by_less.hpp new file mode 100644 index 000000000000..6e37b544039a --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/eq_fn/eq_by_less.hpp @@ -0,0 +1,74 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file eq_by_less.hpp + * Contains an equivalence function. + */ + +#ifndef PB_DS_EQ_BY_LESS_HPP +#define PB_DS_EQ_BY_LESS_HPP + +#include <utility> +#include <functional> +#include <vector> +#include <assert.h> +#include <ext/pb_ds/detail/types_traits.hpp> + +namespace pb_ds +{ + namespace detail + { + template<typename Key, class Cmp_Fn> + struct eq_by_less : private Cmp_Fn + { + bool + operator()(const Key& r_lhs, const Key& r_rhs) const + { + const bool l = Cmp_Fn::operator()(r_lhs, r_rhs); + const bool g = Cmp_Fn::operator()(r_rhs, r_lhs); + return !(l || g); + } + }; + } // namespace detail +} // namespace pb_ds + +#endif // #ifndef PB_DS_EQ_BY_LESS_HPP diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/eq_fn/hash_eq_fn.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/eq_fn/hash_eq_fn.hpp new file mode 100644 index 000000000000..8218ea47ab5c --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/eq_fn/hash_eq_fn.hpp @@ -0,0 +1,185 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file hash_eq_fn.hpp + * Contains 2 eqivalence functions, one employing a hash value, + * and one ignoring it. + */ + +#ifndef PB_DS_HASH_EQ_FN_HPP +#define PB_DS_HASH_EQ_FN_HPP + +#include <utility> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { + template<typename Key, class Eq_Fn, class Allocator, bool Store_Hash> + struct hash_eq_fn; + +#define PB_DS_CLASS_T_DEC \ + template<typename Key, class Eq_Fn, class Allocator> + +#define PB_DS_CLASS_C_DEC \ + hash_eq_fn<Key, Eq_Fn, Allocator, false> + + /** + * Specialization 1- The client requests that hash values not be stored. + **/ + template<typename Key, class Eq_Fn, class Allocator> + struct hash_eq_fn<Key, Eq_Fn, Allocator, false> : public Eq_Fn + { + typedef Eq_Fn eq_fn_base; + + typedef typename Allocator::template rebind<Key>::other key_allocator; + + typedef typename key_allocator::const_reference const_key_reference; + + hash_eq_fn(); + + hash_eq_fn(const Eq_Fn& r_eq_fn); + + inline bool + operator()(const_key_reference r_lhs_key, const_key_reference r_rhs_key) const; + + inline void + swap(const PB_DS_CLASS_C_DEC& other); + }; + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + hash_eq_fn() + { } + + PB_DS_CLASS_T_DEC + inline void + PB_DS_CLASS_C_DEC:: + swap(const PB_DS_CLASS_C_DEC& other) + { std::swap((Eq_Fn& )(*this), (Eq_Fn& )other); } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + hash_eq_fn(const Eq_Fn& r_eq_fn) : + Eq_Fn(r_eq_fn) + { } + + PB_DS_CLASS_T_DEC + inline bool + PB_DS_CLASS_C_DEC:: + operator()(const_key_reference r_lhs_key, const_key_reference r_rhs_key) const + { return (eq_fn_base::operator()(r_lhs_key, r_rhs_key)); } + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +#define PB_DS_CLASS_T_DEC \ + template<typename Key, class Eq_Fn, class Allocator> + +#define PB_DS_CLASS_C_DEC \ + hash_eq_fn<Key, Eq_Fn, Allocator, true> + + /** + * Specialization 2- The client requests that hash values be stored. + **/ + template<typename Key, class Eq_Fn, class Allocator> + struct hash_eq_fn<Key, Eq_Fn, Allocator, true> : + public Eq_Fn + { + typedef typename Allocator::size_type size_type; + + typedef Eq_Fn eq_fn_base; + + typedef typename Allocator::template rebind<Key>::other key_allocator; + + typedef typename key_allocator::const_reference const_key_reference; + + hash_eq_fn(); + + hash_eq_fn(const Eq_Fn& r_eq_fn); + + inline bool + operator()(const_key_reference r_lhs_key, size_type lhs_hash, + const_key_reference r_rhs_key, size_type rhs_hash) const; + + inline void + swap(const PB_DS_CLASS_C_DEC& other); + }; + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + hash_eq_fn() + { } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + hash_eq_fn(const Eq_Fn& r_eq_fn) : + Eq_Fn(r_eq_fn) + { } + + PB_DS_CLASS_T_DEC + inline bool + PB_DS_CLASS_C_DEC:: + operator()(const_key_reference r_lhs_key, size_type lhs_hash, + const_key_reference r_rhs_key, size_type rhs_hash) const + { + _GLIBCXX_DEBUG_ASSERT(!eq_fn_base::operator()(r_lhs_key, r_rhs_key) + || lhs_hash == rhs_hash); + + return (lhs_hash == rhs_hash && + eq_fn_base::operator()(r_lhs_key, r_rhs_key)); + } + + PB_DS_CLASS_T_DEC + inline void + PB_DS_CLASS_C_DEC:: + swap(const PB_DS_CLASS_C_DEC& other) + { std::swap((Eq_Fn& )(*this), (Eq_Fn& )(other)); } + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/constructor_destructor_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/constructor_destructor_fn_imps.hpp new file mode 100644 index 000000000000..30b8d3e7b73a --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/constructor_destructor_fn_imps.hpp @@ -0,0 +1,229 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructor_destructor_fn_imps.hpp + * Contains implementations of gp_ht_map_'s constructors, destructor, + * and related functions. + */ + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::entry_allocator +PB_DS_CLASS_C_DEC::s_entry_allocator; + +PB_DS_CLASS_T_DEC +template<typename It> +void +PB_DS_CLASS_C_DEC:: +copy_from_range(It first_it, It last_it) +{ + while (first_it != last_it) + insert(*(first_it++)); +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME() +: ranged_probe_fn_base(resize_base::get_nearest_larger_size(1)), + m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), + m_entries(s_entry_allocator.allocate(m_num_e)) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const Hash_Fn& r_hash_fn) +: ranged_probe_fn_base(resize_base::get_nearest_larger_size(1), r_hash_fn), + m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), + m_entries(s_entry_allocator.allocate(m_num_e)) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn) +: hash_eq_fn_base(r_eq_fn), + ranged_probe_fn_base(resize_base::get_nearest_larger_size(1), r_hash_fn), + m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), + m_entries(s_entry_allocator.allocate(m_num_e)) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn, + const Comb_Probe_Fn& r_comb_hash_fn) +: hash_eq_fn_base(r_eq_fn), + ranged_probe_fn_base(resize_base::get_nearest_larger_size(1), + r_hash_fn, r_comb_hash_fn), + m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), + m_entries(s_entry_allocator.allocate(m_num_e)) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn, + const Comb_Probe_Fn& comb_hash_fn, const Probe_Fn& prober) +: hash_eq_fn_base(r_eq_fn), + ranged_probe_fn_base(resize_base::get_nearest_larger_size(1), + r_hash_fn, comb_hash_fn, prober), + m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), + m_entries(s_entry_allocator.allocate(m_num_e)) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn, + const Comb_Probe_Fn& comb_hash_fn, const Probe_Fn& prober, + const Resize_Policy& r_resize_policy) +: hash_eq_fn_base(r_eq_fn), resize_base(r_resize_policy), + ranged_probe_fn_base(resize_base::get_nearest_larger_size(1), + r_hash_fn, comb_hash_fn, prober), + m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), + m_entries(s_entry_allocator.allocate(m_num_e)) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const PB_DS_CLASS_C_DEC& other) : +#ifdef _GLIBCXX_DEBUG + map_debug_base(other), +#endif + hash_eq_fn_base(other), + resize_base(other), + ranged_probe_fn_base(other), + m_num_e(other.m_num_e), + m_num_used_e(other.m_num_used_e), + m_entries(s_entry_allocator.allocate(m_num_e)) +{ + for (size_type i = 0; i < m_num_e; ++i) + m_entries[i].m_stat = (entry_status)empty_entry_status; + + try + { + for (size_type i = 0; i < m_num_e; ++i) + { + m_entries[i].m_stat = other.m_entries[i].m_stat; + if (m_entries[i].m_stat == valid_entry_status) + new (m_entries + i) entry(other.m_entries[i]); + } + } + catch(...) + { + deallocate_all(); + __throw_exception_again; + } + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +~PB_DS_CLASS_NAME() +{ deallocate_all(); } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid()); + _GLIBCXX_DEBUG_ONLY(other.assert_valid()); + std::swap(m_num_e, other.m_num_e); + std::swap(m_num_used_e, other.m_num_used_e); + std::swap(m_entries, other.m_entries); + ranged_probe_fn_base::swap(other); + hash_eq_fn_base::swap(other); + resize_base::swap(other); + _GLIBCXX_DEBUG_ONLY(map_debug_base::swap(other)); + _GLIBCXX_DEBUG_ONLY(assert_valid()); + _GLIBCXX_DEBUG_ONLY(other.assert_valid()); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +deallocate_all() +{ + clear(); + erase_all_valid_entries(m_entries, m_num_e); + s_entry_allocator.deallocate(m_entries, m_num_e); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +erase_all_valid_entries(entry_array a_entries_resized, size_type len) +{ + for (size_type pos = 0; pos < len; ++pos) + { + entry_pointer p_e = &a_entries_resized[pos]; + if (p_e->m_stat == valid_entry_status) + p_e->m_value.~value_type(); + } +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +initialize() +{ + Resize_Policy::notify_resized(m_num_e); + Resize_Policy::notify_cleared(); + ranged_probe_fn_base::notify_resized(m_num_e); + for (size_type i = 0; i < m_num_e; ++i) + m_entries[i].m_stat = empty_entry_status; +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/constructor_destructor_no_store_hash_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/constructor_destructor_no_store_hash_fn_imps.hpp new file mode 100644 index 000000000000..df4af951f1a4 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/constructor_destructor_no_store_hash_fn_imps.hpp @@ -0,0 +1,59 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructor_destructor_no_store_hash_fn_imps.hpp + * Contains implementations of gp_ht_map_'s constructors, destructor, + * and related functions. + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +constructor_insert_new_imp(const_mapped_reference r_val, size_type pos, + false_type) +{ + _GLIBCXX_DEBUG_ASSERT(m_entries[pos].m_stat != valid_entry_status)k; + entry* const p_e = m_entries + pos; + new (&p_e->m_value) mapped_value_type(r_val); + p_e->m_stat = valid_entry_status; + _GLIBCXX_DEBUG_ONLY(map_debug_base::insert_new(p_e->m_value.first);) +} diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/constructor_destructor_store_hash_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/constructor_destructor_store_hash_fn_imps.hpp new file mode 100644 index 000000000000..0e17e36efc17 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/constructor_destructor_store_hash_fn_imps.hpp @@ -0,0 +1,60 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructor_destructor_store_hash_fn_imps.hpp + * Contains implementations of gp_ht_map_'s constructors, destructor, + * and related functions. + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +constructor_insert_new_imp(const_mapped_reference r_val, size_type pos, + true_type) +{ + _GLIBCXX_DEBUG_ASSERT(m_entries[pos].m_stat != valid_entry_status); + entry* const p_e = m_entries + pos; + new (&p_e->m_value) mapped_value_type(r_val); + p_e->m_hash = ranged_probe_fn_base::operator()(PB_DS_V2F(r_val)).second; + p_e->m_stat = valid_entry_status; + _GLIBCXX_DEBUG_ONLY(map_debug_base::insert_new(p_e->m_value.first);) +} diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/debug_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/debug_fn_imps.hpp new file mode 100644 index 000000000000..fd8ca9abe12a --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/debug_fn_imps.hpp @@ -0,0 +1,61 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_fn_imps.hpp + * Contains implementations of gp_ht_map_'s debug-mode functions. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_valid() const +{ + map_debug_base::check_size(m_num_used_e); + assert_entry_array_valid(m_entries, traits_base::m_store_extra_indicator); +} + +#include <ext/pb_ds/detail/gp_hash_table_map_/debug_no_store_hash_fn_imps.hpp> +#include <ext/pb_ds/detail/gp_hash_table_map_/debug_store_hash_fn_imps.hpp> + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/debug_no_store_hash_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/debug_no_store_hash_fn_imps.hpp new file mode 100644 index 000000000000..9d3d428e3afa --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/debug_no_store_hash_fn_imps.hpp @@ -0,0 +1,77 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_no_store_hash_fn_imps.hpp + * Contains implementations of gp_ht_map_'s debug-mode functions. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_entry_array_valid(const entry_array a_entries, false_type) const +{ + size_type iterated_num_used_e = 0; + for (size_type pos = 0; pos < m_num_e; ++pos) + { + const_entry_pointer p_e = &a_entries[pos]; + switch(p_e->m_stat) + { + case empty_entry_status: + case erased_entry_status: + break; + case valid_entry_status: + { + const_key_reference r_key = PB_DS_V2F(p_e->m_value); + map_debug_base::check_key_exists(r_key); + ++iterated_num_used_e; + break; + } + default: + _GLIBCXX_DEBUG_ASSERT(0); + }; + } + _GLIBCXX_DEBUG_ASSERT(iterated_num_used_e == m_num_used_e); +} + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/debug_store_hash_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/debug_store_hash_fn_imps.hpp new file mode 100644 index 000000000000..a4d8b6c651aa --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/debug_store_hash_fn_imps.hpp @@ -0,0 +1,83 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_store_hash_fn_imps.hpp + * Contains implementations of gp_ht_map_'s debug-mode functions. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_entry_array_valid(const entry_array a_entries, true_type) const +{ + size_type iterated_num_used_e = 0; + + for (size_type pos = 0; pos < m_num_e; ++pos) + { + const_entry_pointer p_e =& a_entries[pos]; + switch(p_e->m_stat) + { + case empty_entry_status: + case erased_entry_status: + break; + case valid_entry_status: + { + const_key_reference r_key = PB_DS_V2F(p_e->m_value); + map_debug_base::check_key_exists(r_key); + + const comp_hash pos_hash_pair = ranged_probe_fn_base::operator()(r_key); + + _GLIBCXX_DEBUG_ASSERT(p_e->m_hash == pos_hash_pair.second); + ++iterated_num_used_e; + break; + } + default: + _GLIBCXX_DEBUG_ASSERT(0); + }; + } + + _GLIBCXX_DEBUG_ASSERT(iterated_num_used_e == m_num_used_e); +} + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/erase_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/erase_fn_imps.hpp new file mode 100644 index 000000000000..9da850725863 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/erase_fn_imps.hpp @@ -0,0 +1,106 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file erase_fn_imps.hpp + * Contains implementations of gp_ht_map_'s erase related functions. + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +erase_entry(entry_pointer p_e) +{ + _GLIBCXX_DEBUG_ASSERT(p_e->m_stat = valid_entry_status); + _GLIBCXX_DEBUG_ONLY(map_debug_base::erase_existing(PB_DS_V2F(p_e->m_value));) + p_e->m_value.~value_type(); + p_e->m_stat = erased_entry_status; + _GLIBCXX_DEBUG_ASSERT(m_num_used_e > 0); + resize_base::notify_erased(--m_num_used_e); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +clear() +{ + for (size_type pos = 0; pos < m_num_e; ++pos) + { + entry_pointer p_e = &m_entries[pos]; + if (p_e->m_stat == valid_entry_status) + erase_entry(p_e); + } + do_resize_if_needed_no_throw(); + resize_base::notify_cleared(); +} + +PB_DS_CLASS_T_DEC +template<typename Pred> +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +erase_if(Pred pred) +{ + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) + size_type num_ersd = 0; + for (size_type pos = 0; pos < m_num_e; ++pos) + { + entry_pointer p_e = &m_entries[pos]; + if (p_e->m_stat == valid_entry_status) + if (pred(p_e->m_value)) + { + ++num_ersd; + erase_entry(p_e); + } + } + + do_resize_if_needed_no_throw(); + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) + return num_ersd; +} + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +erase(const_key_reference r_key) +{ return erase_imp(r_key, traits_base::m_store_extra_indicator); } + +#include <ext/pb_ds/detail/gp_hash_table_map_/erase_no_store_hash_fn_imps.hpp> +#include <ext/pb_ds/detail/gp_hash_table_map_/erase_store_hash_fn_imps.hpp> diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/erase_no_store_hash_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/erase_no_store_hash_fn_imps.hpp new file mode 100644 index 000000000000..51acec9d4b34 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/erase_no_store_hash_fn_imps.hpp @@ -0,0 +1,91 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file erase_no_store_hash_fn_imps.hpp + * Contains implementations of gp_ht_map_'s erase related functions, + * when the hash value is not stored. + */ + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +erase_imp(const_key_reference r_key, false_type) +{ + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) + size_type hash = ranged_probe_fn_base::operator()(r_key); + size_type i; + resize_base::notify_erase_search_start(); + + for (i = 0; i < m_num_e; ++i) + { + const size_type pos = ranged_probe_fn_base::operator()(r_key, hash, i); + entry* const p_e = m_entries + pos; + switch(p_e->m_stat) + { + case empty_entry_status: + { + resize_base::notify_erase_search_end(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist( + r_key)); + return false; + } + break; + case valid_entry_status: + if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), r_key)) + { + resize_base::notify_erase_search_end(); + erase_entry(p_e); + do_resize_if_needed_no_throw(); + return true; + } + break; + case erased_entry_status: + break; + default: + _GLIBCXX_DEBUG_ASSERT(0); + }; + resize_base::notify_erase_search_collision(); + } + resize_base::notify_erase_search_end(); + return false; +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/erase_store_hash_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/erase_store_hash_fn_imps.hpp new file mode 100644 index 000000000000..71c498b46985 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/erase_store_hash_fn_imps.hpp @@ -0,0 +1,92 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file erase_store_hash_fn_imps.hpp + * Contains implementations of gp_ht_map_'s erase related functions, + * when the hash value is stored. + */ + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +erase_imp(const_key_reference r_key, true_type) +{ + const comp_hash pos_hash_pair = ranged_probe_fn_base::operator()(r_key); + size_type i; + resize_base::notify_erase_search_start(); + for (i = 0; i < m_num_e; ++i) + { + const size_type pos = ranged_probe_fn_base::operator()(r_key, pos_hash_pair.second, i); + + entry* const p_e = m_entries + pos; + switch(p_e->m_stat) + { + case empty_entry_status: + { + resize_base::notify_erase_search_end(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist( + r_key)); + return false; + } + break; + case valid_entry_status: + if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), p_e->m_hash, + r_key, pos_hash_pair.second)) + { + resize_base::notify_erase_search_end(); + erase_entry(p_e); + do_resize_if_needed_no_throw(); + return true; + } + break; + case erased_entry_status: + break; + default: + _GLIBCXX_DEBUG_ASSERT(0); + }; + + resize_base::notify_erase_search_collision(); + } + resize_base::notify_erase_search_end(); + return false; +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/find_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/find_fn_imps.hpp new file mode 100644 index 000000000000..604dc40043f0 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/find_fn_imps.hpp @@ -0,0 +1,76 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file find_fn_imps.hpp + * Contains implementations of gp_ht_map_'s find related functions. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::point_iterator +PB_DS_CLASS_C_DEC:: +find(const_key_reference r_key) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return find_key_pointer(r_key, traits_base::m_store_extra_indicator); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_point_iterator +PB_DS_CLASS_C_DEC:: +find(const_key_reference r_key) const +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return const_cast<PB_DS_CLASS_C_DEC&>(*this).find_key_pointer(r_key, traits_base::m_store_extra_indicator); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::point_iterator +PB_DS_CLASS_C_DEC:: +find_end() +{ return NULL; } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_point_iterator +PB_DS_CLASS_C_DEC:: +find_end() const +{ return NULL; } + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/find_no_store_hash_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/find_no_store_hash_fn_imps.hpp new file mode 100644 index 000000000000..a134f33aded0 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/find_no_store_hash_fn_imps.hpp @@ -0,0 +1,52 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file find_no_store_hash_fn_imps.hpp + * Contains implementations of gp_ht_map_'s find related functions, + * when the hash value is not stored. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::pointer +PB_DS_CLASS_C_DEC:: +find_key_pointer(const_key_reference r_key, false_type) + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/find_store_hash_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/find_store_hash_fn_imps.hpp new file mode 100644 index 000000000000..e43c1299c78c --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/find_store_hash_fn_imps.hpp @@ -0,0 +1,46 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file find_store_hash_fn_imps.hpp + * Contains implementations of gp_ht_map_'s insert related functions, + * when the hash value is stored. + */ diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/gp_ht_map_.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/gp_ht_map_.hpp new file mode 100644 index 000000000000..4a2ae406bbd6 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/gp_ht_map_.hpp @@ -0,0 +1,688 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file gp_ht_map_.hpp + * Contains an implementation class for gp_ht_map_. + */ + +#include <ext/pb_ds/tag_and_trait.hpp> +#include <ext/pb_ds/detail/hash_fn/ranged_probe_fn.hpp> +#include <ext/pb_ds/detail/types_traits.hpp> +#include <ext/pb_ds/exception.hpp> +#include <ext/pb_ds/detail/eq_fn/hash_eq_fn.hpp> +#include <utility> +#ifdef PB_DS_HT_MAP_TRACE_ +#include <iostream> +#endif +#ifdef _GLIBCXX_DEBUG +#include <ext/pb_ds/detail/map_debug_base.hpp> +#endif +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { +#define PB_DS_CLASS_T_DEC \ + template<typename Key, typename Mapped, typename Hash_Fn, typename Eq_Fn, \ + typename Allocator, bool Store_Hash, typename Comb_Probe_Fn, \ + typename Probe_Fn, typename Resize_Policy> + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_CLASS_NAME gp_ht_map_data_ +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#define PB_DS_CLASS_NAME gp_ht_map_no_data_ +#endif + +#define PB_DS_CLASS_C_DEC \ + PB_DS_CLASS_NAME<Key, Mapped, Hash_Fn, Eq_Fn, Allocator, \ + Store_Hash, Comb_Probe_Fn, Probe_Fn, Resize_Policy> + +#define PB_DS_HASH_EQ_FN_C_DEC \ + hash_eq_fn<Key, Eq_Fn, Allocator, Store_Hash> + +#define PB_DS_RANGED_PROBE_FN_C_DEC \ + ranged_probe_fn<Key, Hash_Fn, Allocator, Comb_Probe_Fn, Probe_Fn, Store_Hash> + +#define PB_DS_TYPES_TRAITS_C_DEC \ + types_traits<Key, Mapped, Allocator, Store_Hash> + +#ifdef _GLIBCXX_DEBUG +#define PB_DS_MAP_DEBUG_BASE_C_DEC \ + map_debug_base<Key, Eq_Fn, typename Allocator::template rebind<Key>::other::const_reference> +#endif + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_V2F(X) (X).first +#define PB_DS_V2S(X) (X).second +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#define PB_DS_V2F(X) (X) +#define PB_DS_V2S(X) Mapped() +#endif + +#define PB_DS_STATIC_ASSERT(UNIQUE, E) \ + typedef static_assert_dumclass<sizeof(static_assert<(bool)(E)>)> \ + UNIQUE##static_assert_type + + template<typename Key, + typename Mapped, + typename Hash_Fn, + typename Eq_Fn, + typename Allocator, + bool Store_Hash, + typename Comb_Probe_Fn, + typename Probe_Fn, + typename Resize_Policy> + class PB_DS_CLASS_NAME : +#ifdef _GLIBCXX_DEBUG + protected PB_DS_MAP_DEBUG_BASE_C_DEC, +#endif + public PB_DS_HASH_EQ_FN_C_DEC, + public Resize_Policy, + public PB_DS_RANGED_PROBE_FN_C_DEC, + public PB_DS_TYPES_TRAITS_C_DEC + { + private: + typedef PB_DS_TYPES_TRAITS_C_DEC traits_base; + typedef typename traits_base::value_type value_type_; + typedef typename traits_base::pointer pointer_; + typedef typename traits_base::const_pointer const_pointer_; + typedef typename traits_base::reference reference_; + typedef typename traits_base::const_reference const_reference_; + typedef typename traits_base::comp_hash comp_hash; + + enum entry_status + { + empty_entry_status, + valid_entry_status, + erased_entry_status + } __attribute__ ((packed)); + + struct entry : public traits_base::stored_value_type + { + entry_status m_stat; + }; + + typedef typename Allocator::template rebind<entry>::other entry_allocator; + typedef typename entry_allocator::pointer entry_pointer; + typedef typename entry_allocator::const_pointer const_entry_pointer; + typedef typename entry_allocator::reference entry_reference; + typedef typename entry_allocator::const_reference const_entry_reference; + typedef typename entry_allocator::pointer entry_array; + + typedef PB_DS_RANGED_PROBE_FN_C_DEC ranged_probe_fn_base; + +#ifdef _GLIBCXX_DEBUG + typedef PB_DS_MAP_DEBUG_BASE_C_DEC map_debug_base; +#endif + + typedef PB_DS_HASH_EQ_FN_C_DEC hash_eq_fn_base; + typedef Resize_Policy resize_base; + +#define PB_DS_GEN_POS typename Allocator::size_type + +#include <ext/pb_ds/detail/unordered_iterator/const_point_iterator.hpp> +#include <ext/pb_ds/detail/unordered_iterator/point_iterator.hpp> +#include <ext/pb_ds/detail/unordered_iterator/const_iterator.hpp> +#include <ext/pb_ds/detail/unordered_iterator/iterator.hpp> + +#undef PB_DS_GEN_POS + + public: + typedef Allocator allocator; + typedef typename Allocator::size_type size_type; + typedef typename Allocator::difference_type difference_type; + typedef Hash_Fn hash_fn; + typedef Eq_Fn eq_fn; + typedef Probe_Fn probe_fn; + typedef Comb_Probe_Fn comb_probe_fn; + typedef Resize_Policy resize_policy; + + enum + { + store_hash = Store_Hash + }; + + typedef typename traits_base::key_type key_type; + typedef typename traits_base::key_pointer key_pointer; + typedef typename traits_base::const_key_pointer const_key_pointer; + typedef typename traits_base::key_reference key_reference; + typedef typename traits_base::const_key_reference const_key_reference; + typedef typename traits_base::mapped_type mapped_type; + typedef typename traits_base::mapped_pointer mapped_pointer; + typedef typename traits_base::const_mapped_pointer const_mapped_pointer; + typedef typename traits_base::mapped_reference mapped_reference; + typedef typename traits_base::const_mapped_reference const_mapped_reference; + typedef typename traits_base::value_type value_type; + typedef typename traits_base::pointer pointer; + typedef typename traits_base::const_pointer const_pointer; + typedef typename traits_base::reference reference; + typedef typename traits_base::const_reference const_reference; + +#ifdef PB_DS_DATA_TRUE_INDICATOR + typedef point_iterator_ point_iterator; +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR + typedef const_point_iterator_ point_iterator; +#endif + + typedef const_point_iterator_ const_point_iterator; + +#ifdef PB_DS_DATA_TRUE_INDICATOR + typedef iterator_ iterator; +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR + typedef const_iterator_ iterator; +#endif + + typedef const_iterator_ const_iterator; + + PB_DS_CLASS_NAME(); + + PB_DS_CLASS_NAME(const PB_DS_CLASS_C_DEC&); + + PB_DS_CLASS_NAME(const Hash_Fn&); + + PB_DS_CLASS_NAME(const Hash_Fn&, const Eq_Fn&); + + PB_DS_CLASS_NAME(const Hash_Fn&, const Eq_Fn&, const Comb_Probe_Fn&); + + PB_DS_CLASS_NAME(const Hash_Fn&, const Eq_Fn&, const Comb_Probe_Fn&, + const Probe_Fn&); + + PB_DS_CLASS_NAME(const Hash_Fn&, const Eq_Fn&, const Comb_Probe_Fn&, + const Probe_Fn&, const Resize_Policy&); + + template<typename It> + void + copy_from_range(It first_it, It last_it); + + virtual + ~PB_DS_CLASS_NAME(); + + void + swap(PB_DS_CLASS_C_DEC& other); + + inline size_type + size() const; + + inline size_type + max_size() const; + + inline bool + empty() const; + + Hash_Fn& + get_hash_fn(); + + const Hash_Fn& + get_hash_fn() const; + + Eq_Fn& + get_eq_fn(); + + const Eq_Fn& + get_eq_fn() const; + + Probe_Fn& + get_probe_fn(); + + const Probe_Fn& + get_probe_fn() const; + + Comb_Probe_Fn& + get_comb_probe_fn(); + + const Comb_Probe_Fn& + get_comb_probe_fn() const; + + Resize_Policy& + get_resize_policy(); + + const Resize_Policy& + get_resize_policy() const; + + inline std::pair<point_iterator, bool> + insert(const_reference r_val) + { + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) + return insert_imp(r_val, traits_base::m_store_extra_indicator); + } + + inline mapped_reference + operator[](const_key_reference r_key) + { +#ifdef PB_DS_DATA_TRUE_INDICATOR + return subscript_imp(r_key, traits_base::m_store_extra_indicator); +#else + insert(r_key); + return traits_base::s_null_mapped; +#endif + } + + inline point_iterator + find(const_key_reference r_key); + + inline const_point_iterator + find(const_key_reference r_key) const; + + inline point_iterator + find_end(); + + inline const_point_iterator + find_end() const; + + inline bool + erase(const_key_reference r_key); + + template<typename Pred> + inline size_type + erase_if(Pred prd); + + void + clear(); + + inline iterator + begin(); + + inline const_iterator + begin() const; + + inline iterator + end(); + + inline const_iterator + end() const; + +#ifdef _GLIBCXX_DEBUG + void + assert_valid() const; +#endif + +#ifdef PB_DS_HT_MAP_TRACE_ + void + trace() const; +#endif + + private: +#ifdef PB_DS_DATA_TRUE_INDICATOR + friend class iterator_; +#endif + + friend class const_iterator_; + + void + deallocate_all(); + + void + initialize(); + + void + erase_all_valid_entries(entry_array, size_type); + + inline bool + do_resize_if_needed(); + + inline void + do_resize_if_needed_no_throw(); + + void + resize_imp(size_type); + + virtual void + do_resize(size_type); + + void + resize_imp(entry_array, size_type); + + inline void + resize_imp_reassign(entry_pointer, entry_array, false_type); + + inline void + resize_imp_reassign(entry_pointer, entry_array, true_type); + + inline size_type + find_ins_pos(const_key_reference, false_type); + + inline comp_hash + find_ins_pos(const_key_reference, true_type); + + inline std::pair<point_iterator, bool> + insert_imp(const_reference, false_type); + + inline std::pair<point_iterator, bool> + insert_imp(const_reference, true_type); + + inline pointer + insert_new_imp(const_reference r_val, size_type pos) + { + _GLIBCXX_DEBUG_ASSERT(m_entries[pos].m_stat != valid_entry_status); + + if (do_resize_if_needed()) + pos = find_ins_pos(PB_DS_V2F(r_val), + traits_base::m_store_extra_indicator); + + _GLIBCXX_DEBUG_ASSERT(m_entries[pos].m_stat != valid_entry_status); + + entry* const p_e = m_entries + pos; + new (&p_e->m_value) value_type(r_val); + p_e->m_stat = valid_entry_status; + resize_base::notify_inserted(++m_num_used_e); + + _GLIBCXX_DEBUG_ONLY(map_debug_base::insert_new(PB_DS_V2F(p_e->m_value));) + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return &p_e->m_value; + } + + inline pointer + insert_new_imp(const_reference r_val, comp_hash& r_pos_hash_pair) + { + _GLIBCXX_DEBUG_ASSERT(m_entries[r_pos_hash_pair.first].m_stat != + valid_entry_status); + + if (do_resize_if_needed()) + r_pos_hash_pair = find_ins_pos(PB_DS_V2F(r_val), + traits_base::m_store_extra_indicator); + + _GLIBCXX_DEBUG_ASSERT(m_entries[r_pos_hash_pair.first].m_stat != + valid_entry_status); + + entry* const p_e = m_entries + r_pos_hash_pair.first; + new (&p_e->m_value) value_type(r_val); + p_e->m_hash = r_pos_hash_pair.second; + p_e->m_stat = valid_entry_status; + + resize_base::notify_inserted(++m_num_used_e); + + _GLIBCXX_DEBUG_ONLY(map_debug_base::insert_new(PB_DS_V2F(p_e->m_value));) + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return &p_e->m_value; + } + +#ifdef PB_DS_DATA_TRUE_INDICATOR + inline mapped_reference + subscript_imp(const_key_reference key, false_type) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + const size_type pos = find_ins_pos(key, + traits_base::m_store_extra_indicator); + + entry_pointer p_e = &m_entries[pos]; + if (p_e->m_stat != valid_entry_status) + return insert_new_imp(value_type(key, mapped_type()), pos)->second; + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(key);) + return p_e->m_value.second; + } + + inline mapped_reference + subscript_imp(const_key_reference key, true_type) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + comp_hash pos_hash_pair = + find_ins_pos(key, traits_base::m_store_extra_indicator); + + if (m_entries[pos_hash_pair.first].m_stat != valid_entry_status) + return insert_new_imp(value_type(key, mapped_type()), + pos_hash_pair)->second; + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(key)); + return (m_entries + pos_hash_pair.first)->m_value.second; + } +#endif + + inline pointer + find_key_pointer(const_key_reference key, false_type) + { + const size_type hash = ranged_probe_fn_base::operator()(key); + size_type i; + resize_base::notify_find_search_start(); + + // Loop until entry is found or until all possible entries accessed. + for (i = 0; i < m_num_e; ++i) + { + const size_type pos = ranged_probe_fn_base::operator()(key, hash, i); + + entry* const p_e = m_entries + pos; + switch (p_e->m_stat) + { + case empty_entry_status: + { + resize_base::notify_find_search_end(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(key);) + + return NULL; + } + break; + case valid_entry_status: + if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), key)) + { + resize_base::notify_find_search_end(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(key);) + + return pointer(&p_e->m_value); + } + break; + case erased_entry_status: + break; + default: + _GLIBCXX_DEBUG_ASSERT(0); + }; + + resize_base::notify_find_search_collision(); + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(key);) + resize_base::notify_find_search_end(); + return NULL; + } + + inline pointer + find_key_pointer(const_key_reference key, true_type) + { + comp_hash pos_hash_pair = ranged_probe_fn_base::operator()(key); + size_type i; + resize_base::notify_find_search_start(); + + // Loop until entry is found or until all possible entries accessed. + for (i = 0; i < m_num_e; ++i) + { + const size_type pos = + ranged_probe_fn_base::operator()(key, pos_hash_pair.second, i); + + entry* const p_e = m_entries + pos; + + switch(p_e->m_stat) + { + case empty_entry_status: + { + resize_base::notify_find_search_end(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(key);) + + return NULL; + } + break; + case valid_entry_status: + if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), + p_e->m_hash, + key, pos_hash_pair.second)) + { + resize_base::notify_find_search_end(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(key);) + return pointer(&p_e->m_value); + } + break; + case erased_entry_status: + break; + default: + _GLIBCXX_DEBUG_ASSERT(0); + }; + + resize_base::notify_find_search_collision(); + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(key);) + resize_base::notify_find_search_end(); + return NULL; + } + + inline bool + erase_imp(const_key_reference, true_type); + + inline bool + erase_imp(const_key_reference, false_type); + + inline void + erase_entry(entry_pointer p_e); + +#ifdef PB_DS_DATA_TRUE_INDICATOR + void + inc_it_state(pointer& r_p_value, size_type& r_pos) const + { inc_it_state((const_mapped_pointer& )r_p_value, r_pos); } +#endif + + void + inc_it_state(const_pointer& r_p_value, size_type& r_pos) const + { + _GLIBCXX_DEBUG_ASSERT(r_p_value != NULL); + for (++r_pos; r_pos < m_num_e; ++r_pos) + { + const_entry_pointer p_e =& m_entries[r_pos]; + if (p_e->m_stat == valid_entry_status) + { + r_p_value =& p_e->m_value; + return; + } + } + r_p_value = NULL; + } + + void + get_start_it_state(const_pointer& r_p_value, size_type& r_pos) const + { + for (r_pos = 0; r_pos < m_num_e; ++r_pos) + { + const_entry_pointer p_e = &m_entries[r_pos]; + if (p_e->m_stat == valid_entry_status) + { + r_p_value = &p_e->m_value; + return; + } + } + r_p_value = NULL; + } + + void + get_start_it_state(pointer& r_p_value, size_type& r_pos) + { + for (r_pos = 0; r_pos < m_num_e; ++r_pos) + { + entry_pointer p_e = &m_entries[r_pos]; + if (p_e->m_stat == valid_entry_status) + { + r_p_value = &p_e->m_value; + return; + } + } + r_p_value = NULL; + } + +#ifdef _GLIBCXX_DEBUG + void + assert_entry_array_valid(const entry_array, false_type) const; + + void + assert_entry_array_valid(const entry_array, true_type) const; +#endif + + static entry_allocator s_entry_allocator; + static iterator s_end_it; + static const_iterator s_const_end_it; + + size_type m_num_e; + size_type m_num_used_e; + entry_pointer m_entries; + + enum + { + store_hash_ok = !Store_Hash + || !is_same<Hash_Fn, pb_ds::null_hash_fn>::value + }; + + PB_DS_STATIC_ASSERT(sth, store_hash_ok); + }; + +#include <ext/pb_ds/detail/gp_hash_table_map_/constructor_destructor_fn_imps.hpp> +#include <ext/pb_ds/detail/gp_hash_table_map_/find_fn_imps.hpp> +#include <ext/pb_ds/detail/gp_hash_table_map_/resize_fn_imps.hpp> +#include <ext/pb_ds/detail/gp_hash_table_map_/debug_fn_imps.hpp> +#include <ext/pb_ds/detail/gp_hash_table_map_/info_fn_imps.hpp> +#include <ext/pb_ds/detail/gp_hash_table_map_/policy_access_fn_imps.hpp> +#include <ext/pb_ds/detail/gp_hash_table_map_/erase_fn_imps.hpp> +#include <ext/pb_ds/detail/gp_hash_table_map_/iterator_fn_imps.hpp> +#include <ext/pb_ds/detail/gp_hash_table_map_/insert_fn_imps.hpp> +#include <ext/pb_ds/detail/gp_hash_table_map_/trace_fn_imps.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_HASH_EQ_FN_C_DEC +#undef PB_DS_RANGED_PROBE_FN_C_DEC +#undef PB_DS_TYPES_TRAITS_C_DEC +#undef PB_DS_MAP_DEBUG_BASE_C_DEC +#undef PB_DS_CLASS_NAME +#undef PB_DS_V2F +#undef PB_DS_V2S +#undef PB_DS_STATIC_ASSERT + + } // namespace detail +} // namespace pb_ds + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/info_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/info_fn_imps.hpp new file mode 100644 index 000000000000..f24fa8e40407 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/info_fn_imps.hpp @@ -0,0 +1,64 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file info_fn_imps.hpp + * Contains implementations of gp_ht_map_'s entire container info related + * functions. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +size() const +{ return m_num_used_e; } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +max_size() const +{ return s_entry_allocator.max_size(); } + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +empty() const +{ return (size() == 0); } diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/insert_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/insert_fn_imps.hpp new file mode 100644 index 000000000000..de6e3c21f729 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/insert_fn_imps.hpp @@ -0,0 +1,49 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file insert_fn_imps.hpp + * Contains implementations of gp_ht_map_'s insert related functions. + */ + +#include <ext/pb_ds/detail/gp_hash_table_map_/insert_no_store_hash_fn_imps.hpp> +#include <ext/pb_ds/detail/gp_hash_table_map_/insert_store_hash_fn_imps.hpp> + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/insert_no_store_hash_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/insert_no_store_hash_fn_imps.hpp new file mode 100644 index 000000000000..98d597051bdc --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/insert_no_store_hash_fn_imps.hpp @@ -0,0 +1,117 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file insert_no_store_hash_fn_imps.hpp + * Contains implementations of gp_ht_map_'s insert related functions, + * when the hash value is not stored. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +find_ins_pos(const_key_reference r_key, false_type) +{ + size_type hash = ranged_probe_fn_base::operator()(r_key); + size_type i; + + /* The insertion position is initted to a non-legal value to indicate + * that it has not been initted yet. + */ + size_type ins_pos = m_num_e; + resize_base::notify_insert_search_start(); + for (i = 0; i < m_num_e; ++i) + { + const size_type pos = ranged_probe_fn_base::operator()(r_key, hash, i); + _GLIBCXX_DEBUG_ASSERT(pos < m_num_e); + entry* const p_e = m_entries + pos; + switch(p_e->m_stat) + { + case empty_entry_status: + { + resize_base::notify_insert_search_end(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key);) + return (ins_pos == m_num_e) ? pos : ins_pos; + } + break; + case erased_entry_status: + if (ins_pos == m_num_e) + ins_pos = pos; + break; + case valid_entry_status: + if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), r_key)) + { + resize_base::notify_insert_search_end(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(r_key);) + return pos; + } + break; + default: + _GLIBCXX_DEBUG_ASSERT(0); + }; + + resize_base::notify_insert_search_collision(); + } + resize_base::notify_insert_search_end(); + if (ins_pos == m_num_e) + __throw_insert_error(); + return ins_pos; +} + +PB_DS_CLASS_T_DEC +inline std::pair<typename PB_DS_CLASS_C_DEC::point_iterator, bool> +PB_DS_CLASS_C_DEC:: +insert_imp(const_reference r_val, false_type) +{ + const_key_reference r_key = PB_DS_V2F(r_val); + const size_type pos = find_ins_pos(r_key, + traits_base::m_store_extra_indicator); + + if (m_entries[pos].m_stat == valid_entry_status) + { + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(r_key);) + return std::make_pair(&(m_entries + pos)->m_value, false); + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key)); + return std::make_pair(insert_new_imp(r_val, pos), true); +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/insert_store_hash_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/insert_store_hash_fn_imps.hpp new file mode 100644 index 000000000000..b6445fae2e61 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/insert_store_hash_fn_imps.hpp @@ -0,0 +1,124 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file insert_store_hash_fn_imps.hpp + * Contains implementations of gp_ht_map_'s find related functions, + * when the hash value is stored. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::comp_hash +PB_DS_CLASS_C_DEC:: +find_ins_pos(const_key_reference r_key, true_type) +{ + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) + comp_hash pos_hash_pair = ranged_probe_fn_base::operator()(r_key); + + size_type i; + + /* The insertion position is initted to a non-legal value to indicate + * that it has not been initted yet. + */ + size_type ins_pos = m_num_e; + resize_base::notify_insert_search_start(); + for (i = 0; i < m_num_e; ++i) + { + const size_type pos = ranged_probe_fn_base::operator()(r_key, pos_hash_pair.second, i); + + entry* const p_e = m_entries + pos; + switch(p_e->m_stat) + { + case empty_entry_status: + { + resize_base::notify_insert_search_end(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key);) + + return ((ins_pos == m_num_e) ? + std::make_pair(pos, pos_hash_pair.second) : + std::make_pair(ins_pos, pos_hash_pair.second)); + } + break; + case erased_entry_status: + if (ins_pos == m_num_e) + ins_pos = pos; + break; + case valid_entry_status: + if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), p_e->m_hash, + r_key, pos_hash_pair.second)) + { + resize_base::notify_insert_search_end(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(r_key);) + return std::make_pair(pos, pos_hash_pair.second); + } + break; + default: + _GLIBCXX_DEBUG_ASSERT(0); + }; + resize_base::notify_insert_search_collision(); + } + resize_base::notify_insert_search_end(); + if (ins_pos == m_num_e) + __throw_insert_error(); + return std::make_pair(ins_pos, pos_hash_pair.second); +} + +PB_DS_CLASS_T_DEC +inline std::pair<typename PB_DS_CLASS_C_DEC::point_iterator, bool> +PB_DS_CLASS_C_DEC:: +insert_imp(const_reference r_val, true_type) +{ + const_key_reference r_key = PB_DS_V2F(r_val); + comp_hash pos_hash_pair = find_ins_pos(r_key, + traits_base::m_store_extra_indicator); + + _GLIBCXX_DEBUG_ASSERT(pos_hash_pair.first < m_num_e); + entry_pointer p_e =& m_entries[pos_hash_pair.first]; + if (p_e->m_stat == valid_entry_status) + { + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(r_key)); + return std::make_pair(&p_e->m_value, false); + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key)); + return std::make_pair(insert_new_imp(r_val, pos_hash_pair), true); +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/iterator_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/iterator_fn_imps.hpp new file mode 100644 index 000000000000..0f5e835641fd --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/iterator_fn_imps.hpp @@ -0,0 +1,89 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file iterator_fn_imps.hpp + * Contains implementations of gp_ht_map_'s iterators related functions, e.g., + * begin(). + */ + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC::s_end_it; + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC::s_const_end_it; + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +begin() +{ + pointer_ p_value; + size_type pos; + get_start_it_state(p_value, pos); + return iterator(p_value, pos, this); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +end() +{ return s_end_it; } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +begin() const +{ + const_pointer_ p_value; + size_type pos; + get_start_it_state(p_value, pos); + return const_iterator(p_value, pos, this); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +end() const +{ return s_const_end_it; } + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/policy_access_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/policy_access_fn_imps.hpp new file mode 100644 index 000000000000..903fc34711f5 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/policy_access_fn_imps.hpp @@ -0,0 +1,106 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file policy_access_fn_imps.hpp + * Contains implementations of gp_ht_map_'s policy agpess + * functions. + */ + +PB_DS_CLASS_T_DEC +Hash_Fn& +PB_DS_CLASS_C_DEC:: +get_hash_fn() +{ return *this; } + +PB_DS_CLASS_T_DEC +const Hash_Fn& +PB_DS_CLASS_C_DEC:: +get_hash_fn() const +{ return *this; } + +PB_DS_CLASS_T_DEC +Eq_Fn& +PB_DS_CLASS_C_DEC:: +get_eq_fn() +{ return *this; } + +PB_DS_CLASS_T_DEC +const Eq_Fn& +PB_DS_CLASS_C_DEC:: +get_eq_fn() const +{ return *this; } + +PB_DS_CLASS_T_DEC +Probe_Fn& +PB_DS_CLASS_C_DEC:: +get_probe_fn() +{ return *this; } + +PB_DS_CLASS_T_DEC +const Probe_Fn& +PB_DS_CLASS_C_DEC:: +get_probe_fn() const +{ return *this; } + +PB_DS_CLASS_T_DEC +Comb_Probe_Fn& +PB_DS_CLASS_C_DEC:: +get_comb_probe_fn() +{ return *this; } + +PB_DS_CLASS_T_DEC +const Comb_Probe_Fn& +PB_DS_CLASS_C_DEC:: +get_comb_probe_fn() const +{ return *this; } + +PB_DS_CLASS_T_DEC +Resize_Policy& +PB_DS_CLASS_C_DEC:: +get_resize_policy() +{ return *this; } + +PB_DS_CLASS_T_DEC +const Resize_Policy& +PB_DS_CLASS_C_DEC:: +get_resize_policy() const +{ return *this; } diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/resize_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/resize_fn_imps.hpp new file mode 100644 index 000000000000..4368d12d6261 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/resize_fn_imps.hpp @@ -0,0 +1,143 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file resize_fn_imps.hpp + * Contains implementations of gp_ht_map_'s resize related functions. + */ + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +do_resize_if_needed() +{ + if (!resize_base::is_resize_needed()) + return false; + resize_imp(resize_base::get_new_size(m_num_e, m_num_used_e)); + return true; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +do_resize(size_type n) +{ resize_imp(resize_base::get_nearest_larger_size(n)); } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +do_resize_if_needed_no_throw() +{ + if (!resize_base::is_resize_needed()) + return; + + try + { + resize_imp(resize_base::get_new_size(m_num_e, m_num_used_e)); + } + catch(...) + { } + + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +resize_imp(size_type new_size) +{ +#ifdef PB_DS_REGRESSION + typename Allocator::group_throw_prob_adjustor adjust(m_num_e); +#endif + + if (new_size == m_num_e) + return; + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + const size_type old_size = m_num_e; + entry_array a_entries_resized = NULL; + + // Following line might throw an exception. + a_entries_resized = s_entry_allocator.allocate(new_size); + + ranged_probe_fn_base::notify_resized(new_size); + m_num_e = new_size; + + for (size_type i = 0; i < m_num_e; ++i) + a_entries_resized[i].m_stat = empty_entry_status; + + try + { + resize_imp(a_entries_resized, old_size); + } + catch(...) + { + erase_all_valid_entries(a_entries_resized, new_size); + m_num_e = old_size; + s_entry_allocator.deallocate(a_entries_resized, new_size); + ranged_probe_fn_base::notify_resized(old_size); + __throw_exception_again; + } + + // At this point no exceptions can be thrown. + _GLIBCXX_DEBUG_ONLY(assert_entry_array_valid(a_entries_resized, traits_base::m_store_extra_indicator);) + + Resize_Policy::notify_resized(new_size); + erase_all_valid_entries(m_entries, old_size); + s_entry_allocator.deallocate(m_entries, old_size); + m_entries = a_entries_resized; + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +resize_imp(entry_array a_entries_resized, size_type old_size) +{ + for (size_type pos = 0; pos < old_size; ++pos) + if (m_entries[pos].m_stat == valid_entry_status) + resize_imp_reassign(m_entries + pos, a_entries_resized, + traits_base::m_store_extra_indicator); +} + +#include <ext/pb_ds/detail/gp_hash_table_map_/resize_no_store_hash_fn_imps.hpp> +#include <ext/pb_ds/detail/gp_hash_table_map_/resize_store_hash_fn_imps.hpp> + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/resize_no_store_hash_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/resize_no_store_hash_fn_imps.hpp new file mode 100644 index 000000000000..2f4126a12d1e --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/resize_no_store_hash_fn_imps.hpp @@ -0,0 +1,78 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file resize_no_store_hash_fn_imps.hpp + * Contains implementations of gp_ht_map_'s resize related functions, when the + * hash value is not stored. + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +resize_imp_reassign(entry_pointer p_e, entry_array a_entries_resized, + false_type) +{ + const_key_reference r_key = PB_DS_V2F(p_e->m_value); + size_type hash = ranged_probe_fn_base::operator()(r_key); + size_type i; + for (i = 0; i < m_num_e; ++i) + { + const size_type pos = ranged_probe_fn_base::operator()(r_key, hash, i); + entry_pointer p_new_e = a_entries_resized + pos; + switch(p_new_e->m_stat) + { + case empty_entry_status: + new (&p_new_e->m_value) value_type(p_e->m_value); + p_new_e->m_stat = valid_entry_status; + return; + case erased_entry_status: + _GLIBCXX_DEBUG_ASSERT(0); + break; + case valid_entry_status: + break; + default: + _GLIBCXX_DEBUG_ASSERT(0); + }; + } + __throw_insert_error(); +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/resize_store_hash_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/resize_store_hash_fn_imps.hpp new file mode 100644 index 000000000000..ac2ce14cc05e --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/resize_store_hash_fn_imps.hpp @@ -0,0 +1,80 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file resize_store_hash_fn_imps.hpp + * Contains implementations of gp_ht_map_'s resize related functions, when the + * hash value is stored. + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +resize_imp_reassign(entry_pointer p_e, entry_array a_entries_resized, + true_type) +{ + const_key_reference r_key = PB_DS_V2F(p_e->m_value); + size_type hash = ranged_probe_fn_base::operator()(r_key, p_e->m_hash); + + size_type i; + for (i = 0; i < m_num_e; ++i) + { + const size_type pos = ranged_probe_fn_base::operator()(r_key, hash, i); + entry_pointer p_new_e = a_entries_resized + pos; + switch(p_new_e->m_stat) + { + case empty_entry_status: + new (&p_new_e->m_value) value_type(p_e->m_value); + p_new_e->m_hash = hash; + p_new_e->m_stat = valid_entry_status; + return; + case erased_entry_status: + _GLIBCXX_DEBUG_ASSERT(0); + break; + case valid_entry_status: + break; + default: + _GLIBCXX_DEBUG_ASSERT(0); + }; + } + __throw_insert_error(); +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/standard_policies.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/standard_policies.hpp new file mode 100644 index 000000000000..f4bf7c6e472e --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/standard_policies.hpp @@ -0,0 +1,80 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file standard_policies.hpp + * Contains standard policies for gp_ht_map types. + */ + +#ifndef PB_DS_GP_HT_MAP_STANDARD_POLICIES_HPP +#define PB_DS_GP_HT_MAP_STANDARD_POLICIES_HPP + +#include <ext/pb_ds/detail/standard_policies.hpp> +#include <ext/pb_ds/ht_load_check_resize_trigger.hpp> +#include <ext/pb_ds/linear_probe_fn.hpp> +#include <ext/pb_ds/quadratic_probe_fn.hpp> + +namespace pb_ds +{ + namespace detail + { + template<typename Comb_Probe_Fn> + struct default_probe_fn + { + private: + typedef typename Comb_Probe_Fn::size_type size_type; + + public: + typedef + typename __conditional_type< + is_same< + pb_ds::direct_mask_range_hashing<size_t>, + Comb_Probe_Fn>::value, + pb_ds::linear_probe_fn<size_type>, + pb_ds::quadratic_probe_fn<size_type> >::__type + type; + }; + + } // namespace detail +} // namespace pb_ds + +#endif + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/trace_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/trace_fn_imps.hpp new file mode 100644 index 000000000000..78240c4219c0 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/gp_hash_table_map_/trace_fn_imps.hpp @@ -0,0 +1,80 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file trace_fn_imps.hpp + * Contains implementations of gp_ht_map_'s trace-mode functions. + */ + +#ifdef PB_DS_HT_MAP_TRACE_ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +trace() const +{ + std::cerr << static_cast<unsigned long>(m_num_e) << " " << + static_cast<unsigned long>(m_num_used_e) << std::endl; + + for (size_type i = 0; i < m_num_e; ++i) + { + std::cerr << static_cast<unsigned long>(i) << " "; + + switch(m_entries[i].m_stat) + { + case empty_entry_status: + std::cerr << "<empty>"; + break; + case erased_entry_status: + std::cerr << "<erased>"; + break; + case valid_entry_status: + std::cerr << PB_DS_V2F(m_entries[i].m_value); + break; + default: + _GLIBCXX_DEBUG_ASSERT(0); + }; + + std::cerr << std::endl; + } +} + +#endif // #ifdef PB_DS_HT_MAP_TRACE_ diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/direct_mask_range_hashing_imp.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/direct_mask_range_hashing_imp.hpp new file mode 100644 index 000000000000..5295134a5c9e --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/direct_mask_range_hashing_imp.hpp @@ -0,0 +1,64 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file direct_mask_range_hashing_imp.hpp + * Contains a range-hashing policy implementation + */ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ mask_based_base::swap(other); } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +notify_resized(size_type size) +{ mask_based_base::notify_resized(size); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +operator()(size_type hash) const +{ return mask_based_base::range_hash(hash); } + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/direct_mod_range_hashing_imp.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/direct_mod_range_hashing_imp.hpp new file mode 100644 index 000000000000..5edff69aa954 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/direct_mod_range_hashing_imp.hpp @@ -0,0 +1,64 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file direct_mod_range_hashing_imp.hpp + * Contains a range-hashing policy implementation + */ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ mod_based_base::swap(other); } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +notify_resized(size_type n) +{ mod_based_base::notify_resized(n); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +operator()(size_type hash) const +{ return mod_based_base::range_hash(hash); } + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/linear_probe_fn_imp.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/linear_probe_fn_imp.hpp new file mode 100644 index 000000000000..c1e196c71c91 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/linear_probe_fn_imp.hpp @@ -0,0 +1,59 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file linear_probe_fn_imp.hpp + * Contains a probe policy implementation + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +operator()(size_type i) const +{ + return (i); +} diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/mask_based_range_hashing.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/mask_based_range_hashing.hpp new file mode 100644 index 000000000000..4aa1894bade4 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/mask_based_range_hashing.hpp @@ -0,0 +1,113 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file mask_based_range_hashing.hpp + * Contains a range hashing policy base. + */ + +#ifndef PB_DS_MASK_BASED_RANGE_HASHING_HPP +#define PB_DS_MASK_BASED_RANGE_HASHING_HPP + +namespace pb_ds +{ + namespace detail + { +#define PB_DS_CLASS_T_DEC template<typename Size_Type> +#define PB_DS_CLASS_C_DEC mask_based_range_hashing<Size_Type> + + template<typename Size_Type> + class mask_based_range_hashing + { + protected: + typedef Size_Type size_type; + + void + swap(mask_based_range_hashing& other) + { std::swap(m_mask, other.m_mask); } + + void + notify_resized(size_type size); + + inline size_type + range_hash(size_type hash) const + { return size_type(hash & m_mask); } + + private: + size_type m_mask; + const static size_type s_num_bits_in_size_type; + const static size_type s_highest_bit_1; + }; + + PB_DS_CLASS_T_DEC + const typename PB_DS_CLASS_C_DEC::size_type + PB_DS_CLASS_C_DEC::s_num_bits_in_size_type = + sizeof(typename PB_DS_CLASS_C_DEC::size_type) << 3; + + PB_DS_CLASS_T_DEC + const typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC::s_highest_bit_1 = static_cast<typename PB_DS_CLASS_C_DEC::size_type>(1) << (s_num_bits_in_size_type - 1); + + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + notify_resized(size_type size) + { + size_type i = 0; + while (size ^ s_highest_bit_1) + { + size <<= 1; + ++i; + } + + m_mask = 1; + i += 2; + while (i++ < s_num_bits_in_size_type) + m_mask = (m_mask << 1) ^ 1; + } + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/mod_based_range_hashing.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/mod_based_range_hashing.hpp new file mode 100644 index 000000000000..2d5e8d6ef55d --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/mod_based_range_hashing.hpp @@ -0,0 +1,114 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file mod_based_range_hashing.hpp + * Contains a range hashing policy base. + */ + +#ifndef PB_DS_MOD_BASED_RANGE_HASHING_HPP +#define PB_DS_MOD_BASED_RANGE_HASHING_HPP + +namespace pb_ds +{ + + namespace detail + { + +#define PB_DS_CLASS_T_DEC \ + template<typename Size_Type> + +#define PB_DS_CLASS_C_DEC \ + mod_based_range_hashing< \ + Size_Type> + + template<typename Size_Type> + class mod_based_range_hashing + { + protected: + typedef Size_Type size_type; + + protected: + void + swap(PB_DS_CLASS_C_DEC& other); + + void + notify_resized(size_type size); + + inline size_type + range_hash(size_type hash) const; + + private: + size_type m_size; + }; + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + swap(PB_DS_CLASS_C_DEC& other) + { + std::swap(m_size, other.m_size); + } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + notify_resized(size_type size) + { + m_size = size; + } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::size_type + PB_DS_CLASS_C_DEC:: + range_hash(size_type hash) const + { + return (hash % m_size); + } + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + + } // namespace detail + +} // namespace pb_ds + +#endif // #ifndef PB_DS_MOD_BASED_RANGE_HASHING_HPP diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/probe_fn_base.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/probe_fn_base.hpp new file mode 100644 index 000000000000..e72a47ef8256 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/probe_fn_base.hpp @@ -0,0 +1,65 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file probe_fn_base.hpp + * Contains a probe policy base. + */ + +#ifndef PB_DS_PROBE_FN_BASE_HPP +#define PB_DS_PROBE_FN_BASE_HPP + +#include <functional> + +namespace pb_ds +{ + namespace detail + { + template<typename Allocator> + class probe_fn_base + { + protected: + ~probe_fn_base() { } + }; +} // namespace detail +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/quadratic_probe_fn_imp.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/quadratic_probe_fn_imp.hpp new file mode 100644 index 000000000000..044b18ba61d8 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/quadratic_probe_fn_imp.hpp @@ -0,0 +1,59 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file quadratic_probe_fn_imp.hpp + * Contains a probe policy implementation + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +operator()(size_type i) const +{ + return (i* i); +} diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/ranged_hash_fn.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/ranged_hash_fn.hpp new file mode 100644 index 000000000000..179e59358fcf --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/ranged_hash_fn.hpp @@ -0,0 +1,365 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file ranged_hash_fn.hpp + * Contains a unified ranged hash functor, allowing the hash tables + * to deal with a single class for ranged hashing. + */ + +#ifndef PB_DS_RANGED_HASH_FN_HPP +#define PB_DS_RANGED_HASH_FN_HPP + +#include <ext/pb_ds/detail/basic_types.hpp> +#include <utility> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { + template<typename Key, typename Hash_Fn, typename Allocator, + typename Comb_Hash_Fn, bool Store_Hash> + class ranged_hash_fn; + +#define PB_DS_CLASS_T_DEC \ + template<typename Key, typename Hash_Fn, typename Allocator, \ + typename Comb_Hash_Fn> + +#define PB_DS_CLASS_C_DEC \ + ranged_hash_fn<Key, Hash_Fn, Allocator, Comb_Hash_Fn, false> + + /** + * Specialization 1 + * The client supplies a hash function and a ranged hash function, + * and requests that hash values not be stored. + **/ + template<typename Key, typename Hash_Fn, typename Allocator, + typename Comb_Hash_Fn> + class ranged_hash_fn< Key, Hash_Fn, Allocator, Comb_Hash_Fn, false> + : public Hash_Fn, public Comb_Hash_Fn + { + protected: + typedef typename Allocator::size_type size_type; + typedef Hash_Fn hash_fn_base; + typedef Comb_Hash_Fn comb_hash_fn_base; + typedef typename Allocator::template rebind< Key>::other key_allocator; + typedef typename key_allocator::const_reference const_key_reference; + + ranged_hash_fn(size_type); + + ranged_hash_fn(size_type, const Hash_Fn&); + + ranged_hash_fn(size_type, const Hash_Fn&, const Comb_Hash_Fn&); + + void + swap(PB_DS_CLASS_C_DEC&); + + void + notify_resized(size_type); + + inline size_type + operator()(const_key_reference) const; + }; + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_hash_fn(size_type size) + { Comb_Hash_Fn::notify_resized(size); } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_hash_fn(size_type size, const Hash_Fn& r_hash_fn) + : Hash_Fn(r_hash_fn) + { Comb_Hash_Fn::notify_resized(size); } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_hash_fn(size_type size, const Hash_Fn& r_hash_fn, + const Comb_Hash_Fn& r_comb_hash_fn) + : Hash_Fn(r_hash_fn), Comb_Hash_Fn(r_comb_hash_fn) + { comb_hash_fn_base::notify_resized(size); } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + swap(PB_DS_CLASS_C_DEC& other) + { + comb_hash_fn_base::swap(other); + std::swap((Hash_Fn& )(*this), (Hash_Fn& )other); + } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + notify_resized(size_type size) + { comb_hash_fn_base::notify_resized(size); } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::size_type + PB_DS_CLASS_C_DEC:: + operator()(const_key_reference r_key) const + { return (comb_hash_fn_base::operator()(hash_fn_base::operator()(r_key)));} + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +#define PB_DS_CLASS_T_DEC \ + template<typename Key, typename Hash_Fn, typename Allocator, \ + typename Comb_Hash_Fn> + +#define PB_DS_CLASS_C_DEC \ + ranged_hash_fn<Key,Hash_Fn, Allocator, Comb_Hash_Fn, true> + + /** + * Specialization 2 + * The client supplies a hash function and a ranged hash function, + * and requests that hash values be stored. + **/ + template<typename Key, typename Hash_Fn, typename Allocator, + typename Comb_Hash_Fn> + class ranged_hash_fn<Key, Hash_Fn, Allocator, Comb_Hash_Fn, true> + : public Hash_Fn, public Comb_Hash_Fn + { + protected: + typedef typename Allocator::size_type size_type; + typedef std::pair<size_type, size_type> comp_hash; + typedef Hash_Fn hash_fn_base; + typedef Comb_Hash_Fn comb_hash_fn_base; + typedef typename Allocator::template rebind<Key>::other key_allocator; + typedef typename key_allocator::const_reference const_key_reference; + + ranged_hash_fn(size_type); + + ranged_hash_fn(size_type, const Hash_Fn&); + + ranged_hash_fn(size_type, const Hash_Fn&, const Comb_Hash_Fn&); + + void + swap(PB_DS_CLASS_C_DEC&); + + void + notify_resized(size_type); + + inline comp_hash + operator()(const_key_reference) const; + + inline comp_hash + operator()(const_key_reference, size_type) const; + }; + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_hash_fn(size_type size) + { Comb_Hash_Fn::notify_resized(size); } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_hash_fn(size_type size, const Hash_Fn& r_hash_fn) : + Hash_Fn(r_hash_fn) + { Comb_Hash_Fn::notify_resized(size); } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_hash_fn(size_type size, const Hash_Fn& r_hash_fn, + const Comb_Hash_Fn& r_comb_hash_fn) + : Hash_Fn(r_hash_fn), Comb_Hash_Fn(r_comb_hash_fn) + { comb_hash_fn_base::notify_resized(size); } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + swap(PB_DS_CLASS_C_DEC& other) + { + comb_hash_fn_base::swap(other); + std::swap((Hash_Fn& )(*this), (Hash_Fn& )other); + } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + notify_resized(size_type size) + { comb_hash_fn_base::notify_resized(size); } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::comp_hash + PB_DS_CLASS_C_DEC:: + operator()(const_key_reference r_key) const + { + const size_type hash = hash_fn_base::operator()(r_key); + return std::make_pair(comb_hash_fn_base::operator()(hash), hash); + } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::comp_hash + PB_DS_CLASS_C_DEC:: + operator() +#ifdef _GLIBCXX_DEBUG + (const_key_reference r_key, size_type hash) const +#else + (const_key_reference /*r_key*/, size_type hash) const +#endif + { + _GLIBCXX_DEBUG_ASSERT(hash == hash_fn_base::operator()(r_key)); + return std::make_pair(comb_hash_fn_base::operator()(hash), hash); + } + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +#define PB_DS_CLASS_T_DEC \ + template<typename Key, typename Allocator, typename Comb_Hash_Fn> + +#define PB_DS_CLASS_C_DEC \ + ranged_hash_fn<Key, null_hash_fn, Allocator, Comb_Hash_Fn, false> + + /** + * Specialization 3 + * The client does not supply a hash function (by specifying + * null_hash_fn as the Hash_Fn parameter), and requests that hash + * values not be stored. + **/ + template<typename Key, typename Allocator, typename Comb_Hash_Fn> + class ranged_hash_fn<Key, null_hash_fn, Allocator, Comb_Hash_Fn, false> + : public null_hash_fn, public Comb_Hash_Fn + { + protected: + typedef typename Allocator::size_type size_type; + typedef Comb_Hash_Fn comb_hash_fn_base; + + ranged_hash_fn(size_type); + + ranged_hash_fn(size_type, const Comb_Hash_Fn&); + + ranged_hash_fn(size_type, const null_hash_fn&, const Comb_Hash_Fn&); + + void + swap(PB_DS_CLASS_C_DEC&); + }; + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_hash_fn(size_type size) + { Comb_Hash_Fn::notify_resized(size); } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_hash_fn(size_type size, const Comb_Hash_Fn& r_comb_hash_fn) : + Comb_Hash_Fn(r_comb_hash_fn) + { } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_hash_fn(size_type size, const null_hash_fn& r_null_hash_fn, + const Comb_Hash_Fn& r_comb_hash_fn) + : Comb_Hash_Fn(r_comb_hash_fn) + { } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + swap(PB_DS_CLASS_C_DEC& other) + { comb_hash_fn_base::swap(other); } + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +#define PB_DS_CLASS_T_DEC \ + template<typename Key, typename Allocator, typename Comb_Hash_Fn> + +#define PB_DS_CLASS_C_DEC \ + ranged_hash_fn<Key, null_hash_fn, Allocator, Comb_Hash_Fn, true> + + /** + * Specialization 4 + * The client does not supply a hash function (by specifying + * null_hash_fn as the Hash_Fn parameter), and requests that hash + * values be stored. + **/ + template<typename Key, typename Allocator, typename Comb_Hash_Fn> + class ranged_hash_fn<Key, null_hash_fn, Allocator, Comb_Hash_Fn, true> + : public null_hash_fn, public Comb_Hash_Fn + { + protected: + typedef typename Allocator::size_type size_type; + typedef Comb_Hash_Fn comb_hash_fn_base; + + ranged_hash_fn(size_type); + + ranged_hash_fn(size_type, const Comb_Hash_Fn&); + + ranged_hash_fn(size_type, const null_hash_fn&, const Comb_Hash_Fn&); + + void + swap(PB_DS_CLASS_C_DEC&); + }; + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_hash_fn(size_type size) + { Comb_Hash_Fn::notify_resized(size); } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_hash_fn(size_type size, const Comb_Hash_Fn& r_comb_hash_fn) + : Comb_Hash_Fn(r_comb_hash_fn) + { } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_hash_fn(size_type size, const null_hash_fn& r_null_hash_fn, + const Comb_Hash_Fn& r_comb_hash_fn) + : Comb_Hash_Fn(r_comb_hash_fn) + { } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + swap(PB_DS_CLASS_C_DEC& other) + { comb_hash_fn_base::swap(other); } + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/ranged_probe_fn.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/ranged_probe_fn.hpp new file mode 100644 index 000000000000..b665dbf36f8d --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/ranged_probe_fn.hpp @@ -0,0 +1,333 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file ranged_probe_fn.hpp + * Contains a unified ranged probe functor, allowing the probe tables to deal with + * a single class for ranged probeing. + */ + +#ifndef PB_DS_RANGED_PROBE_FN_HPP +#define PB_DS_RANGED_PROBE_FN_HPP + +#include <ext/pb_ds/detail/basic_types.hpp> +#include <utility> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { + template<typename Key, typename Hash_Fn, typename Allocator, + typename Comb_Probe_Fn, typename Probe_Fn, bool Store_Hash> + class ranged_probe_fn; + +#define PB_DS_CLASS_T_DEC \ + template<typename Key, typename Hash_Fn, typename Allocator, \ + typename Comb_Probe_Fn, typename Probe_Fn> + +#define PB_DS_CLASS_C_DEC \ + ranged_probe_fn<Key, Hash_Fn, Allocator, Comb_Probe_Fn, Probe_Fn, false> + + /** + * Specialization 1 + * The client supplies a probe function and a ranged probe + * function, and requests that hash values not be stored. + **/ + template<typename Key, typename Hash_Fn, typename Allocator, + typename Comb_Probe_Fn, typename Probe_Fn> + class ranged_probe_fn<Key, Hash_Fn, Allocator, Comb_Probe_Fn, + Probe_Fn, false> + : public Hash_Fn, public Comb_Probe_Fn, public Probe_Fn + { + protected: + typedef typename Allocator::size_type size_type; + typedef Comb_Probe_Fn comb_probe_fn_base; + typedef Hash_Fn hash_fn_base; + typedef Probe_Fn probe_fn_base; + typedef typename Allocator::template rebind<Key>::other key_allocator; + typedef typename key_allocator::const_reference const_key_reference; + + ranged_probe_fn(size_type); + + ranged_probe_fn(size_type, const Hash_Fn&); + + ranged_probe_fn(size_type, const Hash_Fn&, const Comb_Probe_Fn&); + + ranged_probe_fn(size_type, const Hash_Fn&, const Comb_Probe_Fn&, + const Probe_Fn&); + + void + swap(PB_DS_CLASS_C_DEC&); + + void + notify_resized(size_type); + + inline size_type + operator()(const_key_reference) const; + + inline size_type + operator()(const_key_reference, size_type, size_type) const; + }; + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_probe_fn(size_type size) + { Comb_Probe_Fn::notify_resized(size); } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_probe_fn(size_type size, const Hash_Fn& r_hash_fn) + : Hash_Fn(r_hash_fn) + { Comb_Probe_Fn::notify_resized(size); } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_probe_fn(size_type size, const Hash_Fn& r_hash_fn, + const Comb_Probe_Fn& r_comb_probe_fn) + : Hash_Fn(r_hash_fn), Comb_Probe_Fn(r_comb_probe_fn) + { comb_probe_fn_base::notify_resized(size); } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_probe_fn(size_type size, const Hash_Fn& r_hash_fn, + const Comb_Probe_Fn& r_comb_probe_fn, + const Probe_Fn& r_probe_fn) + : Hash_Fn(r_hash_fn), Comb_Probe_Fn(r_comb_probe_fn), Probe_Fn(r_probe_fn) + { comb_probe_fn_base::notify_resized(size); } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + swap(PB_DS_CLASS_C_DEC& other) + { + comb_probe_fn_base::swap(other); + std::swap((Hash_Fn& )(*this), (Hash_Fn&)other); + } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + notify_resized(size_type size) + { comb_probe_fn_base::notify_resized(size); } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::size_type + PB_DS_CLASS_C_DEC:: + operator()(const_key_reference r_key) const + { return comb_probe_fn_base::operator()(hash_fn_base::operator()(r_key)); } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::size_type + PB_DS_CLASS_C_DEC:: + operator()(const_key_reference, size_type hash, size_type i) const + { + return comb_probe_fn_base::operator()(hash + probe_fn_base::operator()(i)); + } + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +#define PB_DS_CLASS_T_DEC \ + template<typename Key, typename Hash_Fn, typename Allocator, \ + typename Comb_Probe_Fn, typename Probe_Fn> + +#define PB_DS_CLASS_C_DEC \ + ranged_probe_fn<Key, Hash_Fn, Allocator, Comb_Probe_Fn, Probe_Fn, true> + + /** + * Specialization 2- The client supplies a probe function and a ranged + * probe function, and requests that hash values not be stored. + **/ + template<typename Key, typename Hash_Fn, typename Allocator, + typename Comb_Probe_Fn, typename Probe_Fn> + class ranged_probe_fn<Key, Hash_Fn, Allocator, Comb_Probe_Fn, + Probe_Fn, true> + : public Hash_Fn, public Comb_Probe_Fn, public Probe_Fn + { + protected: + typedef typename Allocator::size_type size_type; + typedef std::pair<size_type, size_type> comp_hash; + typedef Comb_Probe_Fn comb_probe_fn_base; + typedef Hash_Fn hash_fn_base; + typedef Probe_Fn probe_fn_base; + typedef typename Allocator::template rebind<Key>::other key_allocator; + typedef typename key_allocator::const_reference const_key_reference; + + ranged_probe_fn(size_type); + + ranged_probe_fn(size_type, const Hash_Fn&); + + ranged_probe_fn(size_type, const Hash_Fn&, + const Comb_Probe_Fn&); + + ranged_probe_fn(size_type, const Hash_Fn&, const Comb_Probe_Fn&, + const Probe_Fn&); + + void + swap(PB_DS_CLASS_C_DEC&); + + void + notify_resized(size_type); + + inline comp_hash + operator()(const_key_reference) const; + + inline size_type + operator()(const_key_reference, size_type, size_type) const; + + inline size_type + operator()(const_key_reference, size_type) const; + }; + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_probe_fn(size_type size) + { Comb_Probe_Fn::notify_resized(size); } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_probe_fn(size_type size, const Hash_Fn& r_hash_fn) + : Hash_Fn(r_hash_fn) + { Comb_Probe_Fn::notify_resized(size); } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_probe_fn(size_type size, const Hash_Fn& r_hash_fn, + const Comb_Probe_Fn& r_comb_probe_fn) + : Hash_Fn(r_hash_fn), Comb_Probe_Fn(r_comb_probe_fn) + { comb_probe_fn_base::notify_resized(size); } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ranged_probe_fn(size_type size, const Hash_Fn& r_hash_fn, + const Comb_Probe_Fn& r_comb_probe_fn, + const Probe_Fn& r_probe_fn) + : Hash_Fn(r_hash_fn), Comb_Probe_Fn(r_comb_probe_fn), Probe_Fn(r_probe_fn) + { comb_probe_fn_base::notify_resized(size); } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + swap(PB_DS_CLASS_C_DEC& other) + { + comb_probe_fn_base::swap(other); + std::swap((Hash_Fn& )(*this), (Hash_Fn& )other); + } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + notify_resized(size_type size) + { comb_probe_fn_base::notify_resized(size); } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::comp_hash + PB_DS_CLASS_C_DEC:: + operator()(const_key_reference r_key) const + { + const size_type hash = hash_fn_base::operator()(r_key); + return std::make_pair(comb_probe_fn_base::operator()(hash), hash); + } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::size_type + PB_DS_CLASS_C_DEC:: + operator()(const_key_reference, size_type hash, size_type i) const + { + return comb_probe_fn_base::operator()(hash + probe_fn_base::operator()(i)); + } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::size_type + PB_DS_CLASS_C_DEC:: + operator() +#ifdef _GLIBCXX_DEBUG + (const_key_reference r_key, size_type hash) const +#else + (const_key_reference /*r_key*/, size_type hash) const +#endif + { + _GLIBCXX_DEBUG_ASSERT(hash == hash_fn_base::operator()(r_key)); + return hash; + } + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + + /** + * Specialization 3 and 4 + * The client does not supply a hash function or probe function, + * and requests that hash values not be stored. + **/ + template<typename Key, typename Allocator, typename Comb_Probe_Fn> + class ranged_probe_fn<Key, null_hash_fn, Allocator, Comb_Probe_Fn, + null_probe_fn, false> + : public Comb_Probe_Fn, public null_hash_fn, public null_probe_fn + { + protected: + typedef typename Allocator::size_type size_type; + typedef Comb_Probe_Fn comb_probe_fn_base; + typedef typename Allocator::template rebind<Key>::other key_allocator; + typedef typename key_allocator::const_reference const_key_reference; + + ranged_probe_fn(size_type size) + { Comb_Probe_Fn::notify_resized(size); } + + ranged_probe_fn(size_type, const Comb_Probe_Fn& r_comb_probe_fn) + : Comb_Probe_Fn(r_comb_probe_fn) + { } + + ranged_probe_fn(size_type, const null_hash_fn&, + const Comb_Probe_Fn& r_comb_probe_fn, + const null_probe_fn&) + : Comb_Probe_Fn(r_comb_probe_fn) + { } + + void + swap(ranged_probe_fn& other) + { comb_probe_fn_base::swap(other); } + }; + } // namespace detail +} // namespace pb_ds + +#endif + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/sample_probe_fn.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/sample_probe_fn.hpp new file mode 100644 index 000000000000..908a7199fa2a --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/sample_probe_fn.hpp @@ -0,0 +1,79 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file sample_probe_fn.hpp + * Contains a sample probe policy. + */ + +#ifndef PB_DS_SAMPLE_PROBE_FN_HPP +#define PB_DS_SAMPLE_PROBE_FN_HPP + +// A sample probe policy. +class sample_probe_fn +{ + +public: + + // Size type. + typedef size_t size_type; + +public: + + // Default constructor. + sample_probe_fn(); + + // Copy constructor. + sample_probe_fn(const sample_probe_fn& other); + + // Swaps content. + inline void + swap(sample_probe_fn& other); + +protected: + + // Returns the i-th offset from the hash value of some key r_key. + inline size_type + operator()(const_key_reference r_key, size_type i) const; + +}; + +#endif // #ifndef PB_DS_SAMPLE_PROBE_FN_HPP diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/sample_range_hashing.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/sample_range_hashing.hpp new file mode 100644 index 000000000000..40ab29a921f0 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/sample_range_hashing.hpp @@ -0,0 +1,83 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file sample_range_hashing.hpp + * Contains a range hashing policy. + */ + +#ifndef PB_DS_SAMPLE_RANGE_HASHING_HPP +#define PB_DS_SAMPLE_RANGE_HASHING_HPP + +// A sample range-hashing functor. +class sample_range_hashing +{ + +public: + + // Size type. + typedef size_t size_type; + +public: + + // Default constructor. + sample_range_hashing(); + + // Copy constructor. + sample_range_hashing(const sample_range_hashing& other); + + // Swaps content. + inline void + swap(sample_range_hashing& other); + +protected: + + // Notifies the policy object that the container's __size has changed to size. + void + notify_resized(size_type size); + + // Transforms the __hash value hash into a ranged-hash value. + inline size_type + operator()(size_type hash) const; + +}; + +#endif // #ifndef PB_DS_SAMPLE_RANGE_HASHING_HPP diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/sample_ranged_hash_fn.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/sample_ranged_hash_fn.hpp new file mode 100644 index 000000000000..55a115d53c35 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/sample_ranged_hash_fn.hpp @@ -0,0 +1,83 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file sample_ranged_hash_fn.hpp + * Contains a ranged hash policy. + */ + +#ifndef PB_DS_SAMPLE_RANGED_HASH_FN_HPP +#define PB_DS_SAMPLE_RANGED_HASH_FN_HPP + +// A sample ranged-hash functor. +class sample_ranged_hash_fn +{ + +public: + + // Size type. + typedef size_t size_type; + +public: + + // Default constructor. + sample_ranged_hash_fn(); + + // Copy constructor. + sample_ranged_hash_fn(const sample_ranged_hash_fn& other); + + // Swaps content. + inline void + swap(sample_ranged_hash_fn& other); + +protected: + + // Notifies the policy object that the container's __size has changed to size. + void + notify_resized(size_type size); + + // Transforms r_key into a position within the table. + inline size_type + operator()(const_key_reference r_key) const; + +}; + +#endif // #ifndef PB_DS_SAMPLE_RANGED_HASH_FN_HPP diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/sample_ranged_probe_fn.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/sample_ranged_probe_fn.hpp new file mode 100644 index 000000000000..01697bb41ff8 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/hash_fn/sample_ranged_probe_fn.hpp @@ -0,0 +1,83 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file sample_ranged_probe_fn.hpp + * Contains a ranged probe policy. + */ + +#ifndef PB_DS_SAMPLE_RANGED_PROBE_FN_HPP +#define PB_DS_SAMPLE_RANGED_PROBE_FN_HPP + +// A sample ranged-probe functor. +class sample_ranged_probe_fn +{ + +public: + + // Size type. + typedef size_t size_type; + +public: + + // Default constructor. + sample_ranged_probe_fn(); + + // Copy constructor. + sample_ranged_probe_fn(const sample_ranged_probe_fn& other); + + // Swaps content. + inline void + swap(sample_ranged_probe_fn& other); + +protected: + + // Notifies the policy object that the container's __size has changed to size. + void + notify_resized(size_type size); + + // Transforms the const key reference r_key into the i-th position within the table. This method is called for each collision within the probe sequence. + inline size_type + operator()(const_key_reference r_key, size_t hash, size_type i) const; + +}; + +#endif // #ifndef PB_DS_SAMPLE_RANGED_PROBE_FN_HPP diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/const_iterator.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/const_iterator.hpp new file mode 100644 index 000000000000..cff9bb808dd1 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/const_iterator.hpp @@ -0,0 +1,168 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file const_iterator.hpp + * Contains an iterator class returned by the table's const find and insert + * methods. + */ + +#ifndef PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_CONST_ITERATOR_HPP +#define PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_CONST_ITERATOR_HPP + +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/const_point_iterator.hpp> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_CLASS_C_DEC \ + left_child_next_sibling_heap_const_iterator_<Node, Allocator> + +#define PB_DS_BASE_C_DEC \ + left_child_next_sibling_heap_node_const_point_iterator_<Node, Allocator> + + // Const point-type iterator. + template<typename Node, class Allocator> + class left_child_next_sibling_heap_const_iterator_ : public PB_DS_BASE_C_DEC + { + + private: + typedef typename PB_DS_BASE_C_DEC::node_pointer node_pointer; + + typedef PB_DS_BASE_C_DEC base_type; + + public: + + // Category. + typedef std::forward_iterator_tag iterator_category; + + // Difference type. + typedef typename Allocator::difference_type difference_type; + + // Iterator's value type. + typedef typename base_type::value_type value_type; + + // Iterator's pointer type. + typedef typename base_type::pointer pointer; + + // Iterator's const pointer type. + typedef typename base_type::const_pointer const_pointer; + + // Iterator's reference type. + typedef typename base_type::reference reference; + + // Iterator's const reference type. + typedef typename base_type::const_reference const_reference; + + public: + + inline + left_child_next_sibling_heap_const_iterator_(node_pointer p_nd) : base_type(p_nd) + { } + + // Default constructor. + inline + left_child_next_sibling_heap_const_iterator_() + { } + + // Copy constructor. + inline + left_child_next_sibling_heap_const_iterator_(const PB_DS_CLASS_C_DEC& other) : base_type(other) + { } + + // Compares content to a different iterator object. + inline bool + operator==(const PB_DS_CLASS_C_DEC& other) const + { return (base_type::m_p_nd == other.m_p_nd); } + + // Compares content (negatively) to a different iterator object. + inline bool + operator!=(const PB_DS_CLASS_C_DEC& other) const + { return (base_type::m_p_nd != other.m_p_nd); } + + inline PB_DS_CLASS_C_DEC& + operator++() + { + _GLIBCXX_DEBUG_ASSERT(base_type::m_p_nd != NULL); + inc(); + return (*this); + } + + inline PB_DS_CLASS_C_DEC + operator++(int) + { + PB_DS_CLASS_C_DEC ret_it(base_type::m_p_nd); + operator++(); + return (ret_it); + } + + private: + void + inc() + { + if (base_type::m_p_nd->m_p_next_sibling != NULL) + { + base_type::m_p_nd = base_type::m_p_nd->m_p_next_sibling; + while (base_type::m_p_nd->m_p_l_child != NULL) + base_type::m_p_nd = base_type::m_p_nd->m_p_l_child; + return; + } + + while (true) + { + node_pointer p_next = base_type::m_p_nd; + base_type::m_p_nd = base_type::m_p_nd->m_p_prev_or_parent; + if (base_type::m_p_nd == NULL || base_type::m_p_nd->m_p_l_child == p_next) + return; + } + } + }; + +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_BASE_C_DEC + + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/const_point_iterator.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/const_point_iterator.hpp new file mode 100644 index 000000000000..ea45b624ac1f --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/const_point_iterator.hpp @@ -0,0 +1,160 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file const_point_iterator.hpp + * Contains an iterator class returned by the table's const find and insert + * methods. + */ + +#ifndef PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_CONST_FIND_ITERATOR_HPP +#define PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_CONST_FIND_ITERATOR_HPP + +#include <ext/pb_ds/tag_and_trait.hpp> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_CLASS_T_DEC \ + template<typename Node, class Allocator> + +#define PB_DS_CLASS_C_DEC \ + left_child_next_sibling_heap_node_const_point_iterator_<Node, Allocator> + + // Const point-type iterator. + template<typename Node, class Allocator> + class left_child_next_sibling_heap_node_const_point_iterator_ + { + + protected: + typedef typename Allocator::template rebind<Node>::other::pointer node_pointer; + + public: + + // Category. + typedef trivial_iterator_tag iterator_category; + + // Difference type. + typedef trivial_iterator_difference_type difference_type; + + // Iterator's value type. + typedef typename Node::value_type value_type; + + // Iterator's pointer type. + typedef + typename Allocator::template rebind< + value_type>::other::pointer + pointer; + + // Iterator's const pointer type. + typedef + typename Allocator::template rebind< + value_type>::other::const_pointer + const_pointer; + + // Iterator's reference type. + typedef + typename Allocator::template rebind< + value_type>::other::reference + reference; + + // Iterator's const reference type. + typedef + typename Allocator::template rebind< + value_type>::other::const_reference + const_reference; + + public: + + inline + left_child_next_sibling_heap_node_const_point_iterator_(node_pointer p_nd) : m_p_nd(p_nd) + { } + + // Default constructor. + inline + left_child_next_sibling_heap_node_const_point_iterator_() : m_p_nd(NULL) + { } + + // Copy constructor. + inline + left_child_next_sibling_heap_node_const_point_iterator_(const PB_DS_CLASS_C_DEC& other) : m_p_nd(other.m_p_nd) + { } + + // Access. + inline const_pointer + operator->() const + { + _GLIBCXX_DEBUG_ASSERT(m_p_nd != NULL); + return &m_p_nd->m_value; + } + + // Access. + inline const_reference + operator*() const + { + _GLIBCXX_DEBUG_ASSERT(m_p_nd != NULL); + return m_p_nd->m_value; + } + + // Compares content to a different iterator object. + inline bool + operator==(const PB_DS_CLASS_C_DEC& other) const + { return m_p_nd == other.m_p_nd; } + + // Compares content (negatively) to a different iterator object. + inline bool + operator!=(const PB_DS_CLASS_C_DEC& other) const + { return m_p_nd != other.m_p_nd; } + + public: + node_pointer m_p_nd; + }; + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/constructors_destructor_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/constructors_destructor_fn_imps.hpp new file mode 100644 index 000000000000..85d2511cac6c --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/constructors_destructor_fn_imps.hpp @@ -0,0 +1,158 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructors_destructor_fn_imps.hpp + * Contains an implementation class for left_child_next_sibling_heap_. + */ + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::node_allocator +PB_DS_CLASS_C_DEC::s_node_allocator; + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::no_throw_copies_t +PB_DS_CLASS_C_DEC::s_no_throw_copies_ind; + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +left_child_next_sibling_heap_() : + m_p_root(NULL), + m_size(0) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +left_child_next_sibling_heap_(const Cmp_Fn& r_cmp_fn) : + Cmp_Fn(r_cmp_fn), + m_p_root(NULL), + m_size(0) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +left_child_next_sibling_heap_(const PB_DS_CLASS_C_DEC& other) +: Cmp_Fn(other), m_p_root(NULL), m_size(0) +{ + m_size = other.m_size; + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + m_p_root = recursive_copy_node(other.m_p_root); + m_size = other.m_size; + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + value_swap(other); + std::swap((Cmp_Fn& )(*this), (Cmp_Fn& )other); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +value_swap(PB_DS_CLASS_C_DEC& other) +{ + std::swap(m_p_root, other.m_p_root); + std::swap(m_size, other.m_size); +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +~left_child_next_sibling_heap_() +{ + clear(); +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +recursive_copy_node(const_node_pointer p_nd) +{ + if (p_nd == NULL) + return (NULL); + + node_pointer p_ret = s_node_allocator.allocate(1); + + try + { + new (p_ret) node(*p_nd); + } + catch(...) + { + s_node_allocator.deallocate(p_ret, 1); + __throw_exception_again; + } + + p_ret->m_p_l_child = p_ret->m_p_next_sibling = + p_ret->m_p_prev_or_parent = NULL; + + try + { + p_ret->m_p_l_child = recursive_copy_node(p_nd->m_p_l_child); + p_ret->m_p_next_sibling = recursive_copy_node(p_nd->m_p_next_sibling); + } + catch(...) + { + clear_imp(p_ret); + __throw_exception_again; + } + + if (p_ret->m_p_l_child != NULL) + p_ret->m_p_l_child->m_p_prev_or_parent = p_ret; + + if (p_ret->m_p_next_sibling != NULL) + p_ret->m_p_next_sibling->m_p_prev_or_parent = + p_nd->m_p_next_sibling->m_p_prev_or_parent == p_nd ? p_ret : NULL; + + return p_ret; +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/debug_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/debug_fn_imps.hpp new file mode 100644 index 000000000000..f16e912018fb --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/debug_fn_imps.hpp @@ -0,0 +1,147 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_fn_imps.hpp + * Contains an implementation class for left_child_next_sibling_heap_. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_valid() const +{ + _GLIBCXX_DEBUG_ASSERT(m_p_root == NULL || m_p_root->m_p_prev_or_parent == NULL); + + if (m_p_root != NULL) + assert_node_consistent(m_p_root, Single_Link_Roots); + assert_size(); + assert_iterators(); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_node_consistent(const_node_pointer p_nd, bool single_link) const +{ + if (p_nd == NULL) + return; + + assert_node_consistent(p_nd->m_p_l_child, false); + assert_node_consistent(p_nd->m_p_next_sibling, single_link); + + if (single_link) + _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_prev_or_parent == NULL); + else if (p_nd->m_p_next_sibling != NULL) + _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_next_sibling->m_p_prev_or_parent == p_nd); + + if (p_nd->m_p_l_child == NULL) + return; + + const_node_pointer p_child = p_nd->m_p_l_child; + while (p_child != NULL) + { + const_node_pointer p_next_child = p_child->m_p_next_sibling; + _GLIBCXX_DEBUG_ASSERT(!Cmp_Fn::operator()(p_nd->m_value, p_child->m_value)); + p_child = p_next_child; + } + _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_l_child->m_p_prev_or_parent == p_nd); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_iterators() const +{ + const size_type calc_size = std::distance(begin(), end()); + if (calc_size == size()) + return; + _GLIBCXX_DEBUG_ASSERT(0); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_size() const +{ + if (size_from_node(m_p_root) == m_size) + return; + _GLIBCXX_DEBUG_ASSERT(0); +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +size_under_node(const_node_pointer p_nd) +{ return 1 + size_from_node(p_nd->m_p_l_child); } + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +size_from_node(const_node_pointer p_nd) +{ + size_type ret = 0; + while (p_nd != NULL) + { + ret += 1 + size_from_node(p_nd->m_p_l_child); + p_nd = p_nd->m_p_next_sibling; + } + return ret; +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +degree(const_node_pointer p_nd) +{ + size_type ret = 0; + const_node_pointer p_child = p_nd->m_p_l_child; + while (p_child != NULL) + { + ++ret; + p_child = p_child->m_p_next_sibling; + } + return ret; +} + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/erase_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/erase_fn_imps.hpp new file mode 100644 index 000000000000..52817639f999 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/erase_fn_imps.hpp @@ -0,0 +1,156 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file erase_fn_imps.hpp + * Contains an implementation class for left_child_next_sibling_heap_. + */ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +clear() +{ + clear_imp(m_p_root); + _GLIBCXX_DEBUG_ASSERT(m_size == 0); + m_p_root = NULL; +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +actual_erase_node(node_pointer p_nd) +{ + _GLIBCXX_DEBUG_ASSERT(m_size > 0); + --m_size; + p_nd->~node(); + s_node_allocator.deallocate(p_nd, 1); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +clear_imp(node_pointer p_nd) +{ + while (p_nd != NULL) + { + clear_imp(p_nd->m_p_l_child); + node_pointer p_next = p_nd->m_p_next_sibling; + actual_erase_node(p_nd); + p_nd = p_next; + } +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +to_linked_list() +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + node_pointer p_cur = m_p_root; + while (p_cur != NULL) + if (p_cur->m_p_l_child != NULL) + { + node_pointer p_child_next = p_cur->m_p_l_child->m_p_next_sibling; + p_cur->m_p_l_child->m_p_next_sibling = p_cur->m_p_next_sibling; + p_cur->m_p_next_sibling = p_cur->m_p_l_child; + p_cur->m_p_l_child = p_child_next; + } + else + p_cur = p_cur->m_p_next_sibling; + +#ifdef _GLIBCXX_DEBUG + const_node_pointer p_counter = m_p_root; + size_type count = 0; + while (p_counter != NULL) + { + ++count; + _GLIBCXX_DEBUG_ASSERT(p_counter->m_p_l_child == NULL); + p_counter = p_counter->m_p_next_sibling; + } + _GLIBCXX_DEBUG_ASSERT(count == m_size); +#endif +} + +PB_DS_CLASS_T_DEC +template<typename Pred> +typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +prune(Pred pred) +{ + node_pointer p_cur = m_p_root; + m_p_root = NULL; + node_pointer p_out = NULL; + while (p_cur != NULL) + { + node_pointer p_next = p_cur->m_p_next_sibling; + if (pred(p_cur->m_value)) + { + p_cur->m_p_next_sibling = p_out; + if (p_out != NULL) + p_out->m_p_prev_or_parent = p_cur; + p_out = p_cur; + } + else + { + p_cur->m_p_next_sibling = m_p_root; + if (m_p_root != NULL) + m_p_root->m_p_prev_or_parent = p_cur; + m_p_root = p_cur; + } + p_cur = p_next; + } + return p_out; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +bubble_to_top(node_pointer p_nd) +{ + node_pointer p_parent = parent(p_nd); + while (p_parent != NULL) + { + swap_with_parent(p_nd, p_parent); + p_parent = parent(p_nd); + } +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/info_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/info_fn_imps.hpp new file mode 100644 index 000000000000..3c0dde816ce8 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/info_fn_imps.hpp @@ -0,0 +1,70 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file info_fn_imps.hpp + * Contains an implementation class for left_child_next_sibling_heap_. + */ + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +empty() const +{ + return (m_size == 0); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +size() const +{ + return (m_size); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +max_size() const +{ + return (s_node_allocator.max_size()); +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/insert_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/insert_fn_imps.hpp new file mode 100644 index 000000000000..479690d2bc9b --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/insert_fn_imps.hpp @@ -0,0 +1,181 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file insert_fn_imps.hpp + * Contains an implementation class for left_child_next_sibling_heap_. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +get_new_node_for_insert(const_reference r_val) +{ + return get_new_node_for_insert(r_val, s_no_throw_copies_ind); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +get_new_node_for_insert(const_reference r_val, false_type) +{ + node_pointer p_new_nd = s_node_allocator.allocate(1); + + cond_dealtor_t cond(p_new_nd); + + new (const_cast<void* >( + static_cast<const void* >(&p_new_nd->m_value))) + typename node::value_type(r_val); + + cond.set_no_action(); + + ++m_size; + + return (p_new_nd); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +get_new_node_for_insert(const_reference r_val, true_type) +{ + node_pointer p_new_nd = s_node_allocator.allocate(1); + + new (const_cast<void* >( + static_cast<const void* >(&p_new_nd->m_value))) + typename node::value_type(r_val); + + ++m_size; + + return (p_new_nd); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +make_child_of(node_pointer p_nd, node_pointer p_new_parent) +{ + _GLIBCXX_DEBUG_ASSERT(p_nd != NULL); + _GLIBCXX_DEBUG_ASSERT(p_new_parent != NULL); + + p_nd->m_p_next_sibling = p_new_parent->m_p_l_child; + + if (p_new_parent->m_p_l_child != NULL) + p_new_parent->m_p_l_child->m_p_prev_or_parent = p_nd; + + p_nd->m_p_prev_or_parent = p_new_parent; + + p_new_parent->m_p_l_child = p_nd; +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +parent(node_pointer p_nd) +{ + while (true) + { + node_pointer p_pot = p_nd->m_p_prev_or_parent; + + if (p_pot == NULL || p_pot->m_p_l_child == p_nd) + return p_pot; + + p_nd = p_pot; + } +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +swap_with_parent(node_pointer p_nd, node_pointer p_parent) +{ + if (p_parent == m_p_root) + m_p_root = p_nd; + + _GLIBCXX_DEBUG_ASSERT(p_nd != NULL); + _GLIBCXX_DEBUG_ASSERT(p_parent != NULL); + _GLIBCXX_DEBUG_ASSERT(parent(p_nd) == p_parent); + + const bool nd_direct_child = p_parent->m_p_l_child == p_nd; + const bool parent_root = p_parent->m_p_prev_or_parent == NULL; + const bool parent_direct_child = + !parent_root&& p_parent->m_p_prev_or_parent->m_p_l_child == p_parent; + + std::swap(p_parent->m_p_prev_or_parent, p_nd->m_p_prev_or_parent); + std::swap(p_parent->m_p_next_sibling, p_nd->m_p_next_sibling); + std::swap(p_parent->m_p_l_child, p_nd->m_p_l_child); + std::swap(p_parent->m_metadata, p_nd->m_metadata); + + _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_l_child != NULL); + _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_prev_or_parent != NULL); + + if (p_nd->m_p_next_sibling != NULL) + p_nd->m_p_next_sibling->m_p_prev_or_parent = p_nd; + + if (p_parent->m_p_next_sibling != NULL) + p_parent->m_p_next_sibling->m_p_prev_or_parent = p_parent; + + if (p_parent->m_p_l_child != NULL) + p_parent->m_p_l_child->m_p_prev_or_parent = p_parent; + + if (parent_direct_child) + p_nd->m_p_prev_or_parent->m_p_l_child = p_nd; + else if (!parent_root) + p_nd->m_p_prev_or_parent->m_p_next_sibling = p_nd; + + if (!nd_direct_child) + { + p_nd->m_p_l_child->m_p_prev_or_parent = p_nd; + + p_parent->m_p_prev_or_parent->m_p_next_sibling = p_parent; + } + else + { + _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_l_child == p_nd); + _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_prev_or_parent == p_parent); + + p_nd->m_p_l_child = p_parent; + p_parent->m_p_prev_or_parent = p_nd; + } + + _GLIBCXX_DEBUG_ASSERT(parent(p_parent) == p_nd); +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/iterators_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/iterators_fn_imps.hpp new file mode 100644 index 000000000000..02e99821f9b0 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/iterators_fn_imps.hpp @@ -0,0 +1,94 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file iterators_fn_imps.hpp + * Contains an implementation class for left_child_next_sibling_heap_. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +begin() +{ + node_pointer p_nd = m_p_root; + + if (p_nd == NULL) + return (iterator(NULL)); + + while (p_nd->m_p_l_child != NULL) + p_nd = p_nd->m_p_l_child; + + return (iterator(p_nd)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +begin() const +{ + node_pointer p_nd = m_p_root; + + if (p_nd == NULL) + return (const_iterator(NULL)); + + while (p_nd->m_p_l_child != NULL) + p_nd = p_nd->m_p_l_child; + + return (const_iterator(p_nd)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +end() +{ + return (iterator(NULL)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +end() const +{ + return (const_iterator(NULL)); +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/left_child_next_sibling_heap_.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/left_child_next_sibling_heap_.hpp new file mode 100644 index 000000000000..e06358d2f22b --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/left_child_next_sibling_heap_.hpp @@ -0,0 +1,355 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file left_child_next_sibling_heap_.hpp + * Contains an implementation class for a basic heap. + */ + +#ifndef PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_HPP +#define PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_HPP + +/* + * Based on CLRS. + */ + +#include <iterator> +#include <ext/pb_ds/detail/cond_dealtor.hpp> +#include <ext/pb_ds/detail/type_utils.hpp> +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/node.hpp> +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/const_point_iterator.hpp> +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/const_iterator.hpp> +#ifdef PB_DS_LC_NS_HEAP_TRACE_ +#include <iostream> +#endif +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { + +#ifdef _GLIBCXX_DEBUG +#define PB_DS_CLASS_T_DEC \ + template< \ + typename Value_Type, \ + class Cmp_Fn, \ + typename Node_Metadata, \ + class Allocator, \ + bool Single_Link_Roots> +#else +#define PB_DS_CLASS_T_DEC \ + template< \ + typename Value_Type, \ + class Cmp_Fn, \ + typename Node_Metadata, \ + class Allocator> +#endif + +#ifdef _GLIBCXX_DEBUG +#define PB_DS_CLASS_C_DEC \ + left_child_next_sibling_heap_< \ + Value_Type, \ + Cmp_Fn, \ + Node_Metadata, \ + Allocator, \ + Single_Link_Roots> +#else +#define PB_DS_CLASS_C_DEC \ + left_child_next_sibling_heap_< \ + Value_Type, \ + Cmp_Fn, \ + Node_Metadata, \ + Allocator> +#endif + + /** + * class description = "Base class for some types of h3ap$"> + **/ +#ifdef _GLIBCXX_DEBUG + template<typename Value_Type, + class Cmp_Fn, + typename Node_Metadata, + class Allocator, + bool Single_Link_Roots> +#else + template<typename Value_Type, + class Cmp_Fn, + typename Node_Metadata, + class Allocator> +#endif + class left_child_next_sibling_heap_ : public Cmp_Fn + { + + protected: + typedef + typename Allocator::template rebind< + left_child_next_sibling_heap_node_< + Value_Type, + Node_Metadata, + Allocator> >::other + node_allocator; + + typedef typename node_allocator::value_type node; + + typedef typename node_allocator::pointer node_pointer; + + typedef typename node_allocator::const_pointer const_node_pointer; + + typedef Node_Metadata node_metadata; + + typedef std::pair< node_pointer, node_pointer> node_pointer_pair; + + private: + typedef cond_dealtor< node, Allocator> cond_dealtor_t; + + enum + { + simple_value = is_simple<Value_Type>::value + }; + + typedef integral_constant<int, simple_value> no_throw_copies_t; + + public: + + typedef typename Allocator::size_type size_type; + + typedef typename Allocator::difference_type difference_type; + + typedef Value_Type value_type; + + typedef + typename Allocator::template rebind< + value_type>::other::pointer + pointer; + + typedef + typename Allocator::template rebind< + value_type>::other::const_pointer + const_pointer; + + typedef + typename Allocator::template rebind< + value_type>::other::reference + reference; + + typedef + typename Allocator::template rebind< + value_type>::other::const_reference + const_reference; + + typedef + left_child_next_sibling_heap_node_const_point_iterator_< + node, + Allocator> + const_point_iterator; + + typedef const_point_iterator point_iterator; + + typedef + left_child_next_sibling_heap_const_iterator_< + node, + Allocator> + const_iterator; + + typedef const_iterator iterator; + + typedef Cmp_Fn cmp_fn; + + typedef Allocator allocator; + + public: + + left_child_next_sibling_heap_(); + + left_child_next_sibling_heap_(const Cmp_Fn& r_cmp_fn); + + left_child_next_sibling_heap_(const PB_DS_CLASS_C_DEC& other); + + void + swap(PB_DS_CLASS_C_DEC& other); + + ~left_child_next_sibling_heap_(); + + inline bool + empty() const; + + inline size_type + size() const; + + inline size_type + max_size() const; + + Cmp_Fn& + get_cmp_fn(); + + const Cmp_Fn& + get_cmp_fn() const; + + inline iterator + begin(); + + inline const_iterator + begin() const; + + inline iterator + end(); + + inline const_iterator + end() const; + + void + clear(); + +#ifdef PB_DS_LC_NS_HEAP_TRACE_ + void + trace() const; +#endif + + protected: + + inline node_pointer + get_new_node_for_insert(const_reference r_val); + + inline static void + make_child_of(node_pointer p_nd, node_pointer p_new_parent); + + void + value_swap(PB_DS_CLASS_C_DEC& other); + + inline static node_pointer + parent(node_pointer p_nd); + + inline void + swap_with_parent(node_pointer p_nd, node_pointer p_parent); + + void + bubble_to_top(node_pointer p_nd); + + inline void + actual_erase_node(node_pointer p_nd); + + void + clear_imp(node_pointer p_nd); + + void + to_linked_list(); + + template<typename Pred> + node_pointer + prune(Pred pred); + +#ifdef _GLIBCXX_DEBUG + void + assert_valid() const; + + void + assert_node_consistent(const_node_pointer p_nd, bool single_link) const; + + static size_type + size_under_node(const_node_pointer p_nd); + + static size_type + degree(const_node_pointer p_nd); +#endif + +#ifdef PB_DS_LC_NS_HEAP_TRACE_ + static void + trace_node(const_node_pointer, size_type level); +#endif + + protected: + node_pointer m_p_root; + + size_type m_size; + + private: +#ifdef _GLIBCXX_DEBUG + void + assert_iterators() const; + + void + assert_size() const; + + static size_type + size_from_node(const_node_pointer p_nd); +#endif + + node_pointer + recursive_copy_node(const_node_pointer p_nd); + + inline node_pointer + get_new_node_for_insert(const_reference r_val, false_type); + + inline node_pointer + get_new_node_for_insert(const_reference r_val, true_type); + +#ifdef PB_DS_LC_NS_HEAP_TRACE_ + template<typename Metadata_> + static void + trace_node_metadata(const_node_pointer p_nd, type_to_type<Metadata_>); + + static void + trace_node_metadata(const_node_pointer, type_to_type<null_left_child_next_sibling_heap_node_metadata>); +#endif + + private: + static node_allocator s_node_allocator; + + static no_throw_copies_t s_no_throw_copies_ind; + }; + +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/constructors_destructor_fn_imps.hpp> +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/iterators_fn_imps.hpp> +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/debug_fn_imps.hpp> +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/trace_fn_imps.hpp> +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/insert_fn_imps.hpp> +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/erase_fn_imps.hpp> +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/info_fn_imps.hpp> +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/policy_access_fn_imps.hpp> + +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_CLASS_T_DEC + + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/node.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/node.hpp new file mode 100644 index 000000000000..e3460add5ee5 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/node.hpp @@ -0,0 +1,129 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file node.hpp + * Contains an implementation struct for this type of heap's node. + */ + +#ifndef PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_NODE_HPP +#define PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_NODE_HPP + +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/null_metadata.hpp> + +namespace pb_ds +{ + namespace detail + { + + template<typename Value_Type, typename Metadata_Type, class Allocator> + struct left_child_next_sibling_heap_node_ + { + private: + typedef + left_child_next_sibling_heap_node_< + Value_Type, + Metadata_Type, + Allocator> + this_type; + + public: + typedef typename Allocator::size_type size_type; + + typedef + typename Allocator::template rebind< + this_type>::other::pointer + node_pointer; + + typedef Value_Type value_type; + + typedef Metadata_Type metadata_type; + + public: + value_type m_value; + + metadata_type m_metadata; + + node_pointer m_p_l_child; + + node_pointer m_p_next_sibling; + + node_pointer m_p_prev_or_parent; + }; + + template<typename Value_Type, class Allocator> + struct left_child_next_sibling_heap_node_< + Value_Type, + null_left_child_next_sibling_heap_node_metadata, + Allocator> + { + private: + typedef + left_child_next_sibling_heap_node_< + Value_Type, + null_left_child_next_sibling_heap_node_metadata, + Allocator> + this_type; + + public: + typedef typename Allocator::size_type size_type; + + typedef + typename Allocator::template rebind< + this_type>::other::pointer + node_pointer; + + typedef Value_Type value_type; + + public: + value_type m_value; + + node_pointer m_p_l_child; + + node_pointer m_p_next_sibling; + + node_pointer m_p_prev_or_parent; + }; + + } // namespace detail +} // namespace pb_ds + +#endif // #ifndef PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_NODE_HPP diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/null_metadata.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/null_metadata.hpp new file mode 100644 index 000000000000..1716fd1aa644 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/null_metadata.hpp @@ -0,0 +1,63 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file null_metadata.hpp + * Contains an implementation struct for this type of heap's node. + */ + +#ifndef PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_NULL_METADATA_HPP +#define PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_NULL_METADATA_HPP + +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/null_metadata.hpp> + +namespace pb_ds +{ + namespace detail + { + + struct null_left_child_next_sibling_heap_node_metadata + { }; + + } // namespace detail +} // namespace pb_ds + +#endif // #ifndef PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_NULL_METADATA_HPP diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/policy_access_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/policy_access_fn_imps.hpp new file mode 100644 index 000000000000..b7503c2caf46 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/policy_access_fn_imps.hpp @@ -0,0 +1,62 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file policy_access_fn_imps.hpp + * Contains an implementation class for left_child_next_sibling_heap_. + */ + +PB_DS_CLASS_T_DEC +Cmp_Fn& +PB_DS_CLASS_C_DEC:: +get_cmp_fn() +{ + return (*this); +} + +PB_DS_CLASS_T_DEC +const Cmp_Fn& +PB_DS_CLASS_C_DEC:: +get_cmp_fn() const +{ + return (*this); +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/trace_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/trace_fn_imps.hpp new file mode 100644 index 000000000000..5c0d9acc11dd --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/left_child_next_sibling_heap_/trace_fn_imps.hpp @@ -0,0 +1,101 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file trace_fn_imps.hpp + * Contains an implementation class for left_child_next_sibling_heap_. + */ + +#ifdef PB_DS_LC_NS_HEAP_TRACE_ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +trace() const +{ + std::cerr << std::endl; + + trace_node(m_p_root, 0); + + std::cerr << std::endl; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +trace_node(const_node_pointer p_nd, size_type level) +{ + while (p_nd != NULL) + { + for (size_type i = 0; i < level; ++i) + std::cerr << ' '; + + std::cerr << p_nd << + " prev = " << p_nd->m_p_prev_or_parent << + " next " << p_nd->m_p_next_sibling << + " left = " << p_nd->m_p_l_child << " "; + + trace_node_metadata(p_nd, type_to_type<node_metadata>()); + + std::cerr << p_nd->m_value << std::endl; + + trace_node(p_nd->m_p_l_child, level + 1); + + p_nd = p_nd->m_p_next_sibling; + } +} + +PB_DS_CLASS_T_DEC +template<typename Metadata_> +void +PB_DS_CLASS_C_DEC:: +trace_node_metadata(const_node_pointer p_nd, type_to_type<Metadata_>) +{ + std::cerr << "(" << p_nd->m_metadata << ") "; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +trace_node_metadata(const_node_pointer, type_to_type<null_left_child_next_sibling_heap_node_metadata>) +{ } + +#endif // #ifdef PB_DS_LC_NS_HEAP_TRACE_ diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/list_update_map_/constructor_destructor_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/list_update_map_/constructor_destructor_fn_imps.hpp new file mode 100644 index 000000000000..a311a79757de --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/list_update_map_/constructor_destructor_fn_imps.hpp @@ -0,0 +1,147 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructor_destructor_fn_imps.hpp + * Contains implementations of PB_DS_CLASS_NAME. + */ + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::entry_allocator +PB_DS_CLASS_C_DEC::s_entry_allocator; + +PB_DS_CLASS_T_DEC +Eq_Fn PB_DS_CLASS_C_DEC::s_eq_fn; + +PB_DS_CLASS_T_DEC +null_lu_metadata PB_DS_CLASS_C_DEC::s_null_lu_metadata; + +PB_DS_CLASS_T_DEC +Update_Policy PB_DS_CLASS_C_DEC::s_update_policy; + +PB_DS_CLASS_T_DEC +type_to_type< + typename PB_DS_CLASS_C_DEC::update_metadata> PB_DS_CLASS_C_DEC::s_metadata_type_indicator; + +PB_DS_CLASS_T_DEC +template<typename It> +void +PB_DS_CLASS_C_DEC:: +copy_from_range(It first_it, It last_it) +{ + while (first_it != last_it) + insert(*(first_it++)); +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME() : m_p_l(NULL) +{ _GLIBCXX_DEBUG_ONLY(assert_valid();) } + +PB_DS_CLASS_T_DEC +template<typename It> +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(It first_it, It last_it) : m_p_l(NULL) +{ + copy_from_range(first_it, last_it); + _GLIBCXX_DEBUG_ONLY(assert_valid();); +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const PB_DS_CLASS_C_DEC& other) : +#ifdef _GLIBCXX_DEBUG + map_debug_base(), +#endif +m_p_l(NULL) +{ + try + { + for (const_iterator it = other.begin(); it != other.end(); ++it) + { + entry_pointer p_l = allocate_new_entry(*it, + PB_DS_TYPES_TRAITS_C_DEC::m_no_throw_copies_indicator); + + p_l->m_p_next = m_p_l; + m_p_l = p_l; + } + } + catch(...) + { + deallocate_all(); + __throw_exception_again; + } + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + _GLIBCXX_DEBUG_ONLY(map_debug_base::swap(other);) + std::swap(m_p_l, other.m_p_l); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +deallocate_all() +{ + entry_pointer p_l = m_p_l; + while (p_l != NULL) + { + entry_pointer p_next_l = p_l->m_p_next; + actual_erase_entry(p_l); + p_l = p_next_l; + } + m_p_l = NULL; +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +~PB_DS_CLASS_NAME() +{ deallocate_all(); } + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/list_update_map_/debug_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/list_update_map_/debug_fn_imps.hpp new file mode 100644 index 000000000000..1427f83749bb --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/list_update_map_/debug_fn_imps.hpp @@ -0,0 +1,63 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_fn_imps.hpp + * Contains implementations of cc_ht_map_'s debug-mode functions. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_valid() const +{ + size_type calc_size = 0; + for (const_iterator it = begin(); it != end(); ++it) + { + map_debug_base::check_key_exists(PB_DS_V2F(*it)); + ++calc_size; + } + map_debug_base::check_size(calc_size); +} + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/list_update_map_/entry_metadata_base.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/list_update_map_/entry_metadata_base.hpp new file mode 100644 index 000000000000..7d711a21d71b --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/list_update_map_/entry_metadata_base.hpp @@ -0,0 +1,66 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file entry_metadata_base.hpp + * Contains an implementation for a list update map. + */ + +#ifndef PB_DS_LU_MAP_ENTRY_METADATA_BASE_HPP +#define PB_DS_LU_MAP_ENTRY_METADATA_BASE_HPP + +namespace pb_ds +{ + namespace detail + { + template<typename Metadata> + struct lu_map_entry_metadata_base + { + Metadata m_update_metadata; + }; + + template<> + struct lu_map_entry_metadata_base<null_lu_metadata> + { }; + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/list_update_map_/erase_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/list_update_map_/erase_fn_imps.hpp new file mode 100644 index 000000000000..85ac02d30122 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/list_update_map_/erase_fn_imps.hpp @@ -0,0 +1,141 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file erase_fn_imps.hpp + * Contains implementations of lu_map_. + */ + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +erase(const_key_reference r_key) +{ + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) + if (m_p_l == NULL) + return false; + + if (s_eq_fn(r_key, PB_DS_V2F(m_p_l->m_value))) + { + entry_pointer p_next = m_p_l->m_p_next; + actual_erase_entry(m_p_l); + m_p_l = p_next; + return true; + } + + entry_pointer p_l = m_p_l; + while (p_l->m_p_next != NULL) + if (s_eq_fn(r_key, PB_DS_V2F(p_l->m_p_next->m_value))) + { + erase_next(p_l); + return true; + } + else + p_l = p_l->m_p_next; + return false; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +clear() +{ + deallocate_all(); +} + +PB_DS_CLASS_T_DEC +template<typename Pred> +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +erase_if(Pred pred) +{ + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) + size_type num_ersd = 0; + while (m_p_l != NULL && pred(m_p_l->m_value)) + { + entry_pointer p_next = m_p_l->m_p_next; + ++num_ersd; + actual_erase_entry(m_p_l); + m_p_l = p_next; + } + + if (m_p_l == NULL) + return num_ersd; + + entry_pointer p_l = m_p_l; + while (p_l->m_p_next != NULL) + { + if (pred(p_l->m_p_next->m_value)) + { + ++num_ersd; + erase_next(p_l); + } + else + p_l = p_l->m_p_next; + } + + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) + return num_ersd; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +erase_next(entry_pointer p_l) +{ + _GLIBCXX_DEBUG_ASSERT(p_l != NULL); + _GLIBCXX_DEBUG_ASSERT(p_l != m_p_l); + _GLIBCXX_DEBUG_ASSERT(p_l->m_p_next != NULL); + entry_pointer p_next_l = p_l->m_p_next->m_p_next; + actual_erase_entry(p_l->m_p_next); + p_l->m_p_next = p_next_l; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +actual_erase_entry(entry_pointer p_l) +{ + _GLIBCXX_DEBUG_ONLY(map_debug_base::erase_existing(PB_DS_V2F(p_l->m_value));) + p_l->~entry(); + s_entry_allocator.deallocate(p_l, 1); +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/list_update_map_/find_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/list_update_map_/find_fn_imps.hpp new file mode 100644 index 000000000000..37c173de1e4d --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/list_update_map_/find_fn_imps.hpp @@ -0,0 +1,96 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file find_fn_imps.hpp + * Contains implementations of lu_map_. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::entry_pointer +PB_DS_CLASS_C_DEC:: +find_imp(const_key_reference r_key) const +{ + if (m_p_l == NULL) + return NULL; + if (s_eq_fn(r_key, PB_DS_V2F(m_p_l->m_value))) + { + apply_update(m_p_l, s_metadata_type_indicator); + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(r_key);) + return m_p_l; + } + + entry_pointer p_l = m_p_l; + while (p_l->m_p_next != NULL) + { + entry_pointer p_next = p_l->m_p_next; + if (s_eq_fn(r_key, PB_DS_V2F(p_next->m_value))) + { + if (apply_update(p_next, s_metadata_type_indicator)) + { + p_l->m_p_next = p_next->m_p_next; + p_next->m_p_next = m_p_l; + m_p_l = p_next; + return m_p_l; + } + return p_next; + } + else + p_l = p_next; + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key);) + return NULL; +} + +PB_DS_CLASS_T_DEC +template<typename Metadata> +inline bool +PB_DS_CLASS_C_DEC:: +apply_update(entry_pointer p_l, type_to_type<Metadata>) +{ return s_update_policy(p_l->m_update_metadata); } + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +apply_update(entry_pointer, type_to_type<null_lu_metadata>) +{ return s_update_policy(s_null_lu_metadata); } + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/list_update_map_/info_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/list_update_map_/info_fn_imps.hpp new file mode 100644 index 000000000000..a7fe8c45c3f5 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/list_update_map_/info_fn_imps.hpp @@ -0,0 +1,63 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file info_fn_imps.hpp + * Contains implementations of lu_map_. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +size() const +{ return std::distance(begin(), end()); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +max_size() const +{ return s_entry_allocator.max_size(); } + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +empty() const +{ return (m_p_l == NULL); } diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/list_update_map_/insert_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/list_update_map_/insert_fn_imps.hpp new file mode 100644 index 000000000000..af60c07b5074 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/list_update_map_/insert_fn_imps.hpp @@ -0,0 +1,112 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file insert_fn_imps.hpp + * Contains implementations of lu_map_. + */ + +PB_DS_CLASS_T_DEC +inline std::pair< + typename PB_DS_CLASS_C_DEC::point_iterator, + bool> +PB_DS_CLASS_C_DEC:: +insert(const_reference r_val) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + entry_pointer p_l = find_imp(PB_DS_V2F(r_val)); + + if (p_l != NULL) + { + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(PB_DS_V2F(r_val));) + return std::make_pair(point_iterator(&p_l->m_value), false); + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(PB_DS_V2F(r_val));) + + p_l = allocate_new_entry(r_val, traits_base::m_no_throw_copies_indicator); + p_l->m_p_next = m_p_l; + m_p_l = p_l; + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return std::make_pair(point_iterator(&p_l->m_value), true); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::entry_pointer +PB_DS_CLASS_C_DEC:: +allocate_new_entry(const_reference r_val, false_type) +{ + entry_pointer p_l = s_entry_allocator.allocate(1); + cond_dealtor_t cond(p_l); + new (const_cast<void* >(static_cast<const void* >(&p_l->m_value))) + value_type(r_val); + + cond.set_no_action(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::insert_new(PB_DS_V2F(r_val));) + init_entry_metadata(p_l, s_metadata_type_indicator); + return p_l; +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::entry_pointer +PB_DS_CLASS_C_DEC:: +allocate_new_entry(const_reference r_val, true_type) +{ + entry_pointer p_l = s_entry_allocator.allocate(1); + new (&p_l->m_value) value_type(r_val); + _GLIBCXX_DEBUG_ONLY(map_debug_base::insert_new(PB_DS_V2F(r_val));) + init_entry_metadata(p_l, s_metadata_type_indicator); + return p_l; +} + +PB_DS_CLASS_T_DEC +template<typename Metadata> +inline void +PB_DS_CLASS_C_DEC:: +init_entry_metadata(entry_pointer p_l, type_to_type<Metadata>) +{ new (&p_l->m_update_metadata) Metadata(s_update_policy()); } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +init_entry_metadata(entry_pointer, type_to_type<null_lu_metadata>) +{ } + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/list_update_map_/iterators_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/list_update_map_/iterators_fn_imps.hpp new file mode 100644 index 000000000000..e9620320ba74 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/list_update_map_/iterators_fn_imps.hpp @@ -0,0 +1,86 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file iterators_fn_imps.hpp + * Contains implementations of lu_map_. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +begin() +{ + if (m_p_l == NULL) + { + _GLIBCXX_DEBUG_ASSERT(empty()); + return end(); + } + return iterator(&m_p_l->m_value, m_p_l, this); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +begin() const +{ + if (m_p_l == NULL) + { + _GLIBCXX_DEBUG_ASSERT(empty()); + return end(); + } + return iterator(&m_p_l->m_value, m_p_l, const_cast<PB_DS_CLASS_C_DEC* >(this)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +end() +{ return iterator(NULL, NULL, this); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +end() const +{ + return const_iterator(NULL, NULL, const_cast<PB_DS_CLASS_C_DEC* const>(this)); +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/list_update_map_/lu_map_.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/list_update_map_/lu_map_.hpp new file mode 100644 index 000000000000..e99dc735ab4d --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/list_update_map_/lu_map_.hpp @@ -0,0 +1,365 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file lu_map_.hpp + * Contains a list update map. + */ + +#include <utility> +#include <iterator> +#include <ext/pb_ds/detail/cond_dealtor.hpp> +#include <ext/pb_ds/tag_and_trait.hpp> +#include <ext/pb_ds/detail/types_traits.hpp> +#include <ext/pb_ds/detail/list_update_map_/entry_metadata_base.hpp> +#include <ext/pb_ds/exception.hpp> +#ifdef _GLIBCXX_DEBUG +#include <ext/pb_ds/detail/map_debug_base.hpp> +#endif +#ifdef PB_DS_LU_MAP_TRACE_ +#include <iostream> +#endif +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { +#define PB_DS_CLASS_T_DEC \ + template<typename Key, typename Mapped, class Eq_Fn, \ + class Allocator, class Update_Policy> + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_CLASS_NAME lu_map_data_ +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#define PB_DS_CLASS_NAME lu_map_no_data_ +#endif + +#define PB_DS_CLASS_C_DEC \ + PB_DS_CLASS_NAME<Key, Mapped, Eq_Fn, Allocator, Update_Policy> + +#define PB_DS_TYPES_TRAITS_C_DEC \ + types_traits<Key, Mapped, Allocator, false> + +#ifdef _GLIBCXX_DEBUG +#define PB_DS_MAP_DEBUG_BASE_C_DEC \ + map_debug_base<Key, Eq_Fn, \ + typename Allocator::template rebind<Key>::other::const_reference> +#endif + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_V2F(X) (X).first +#define PB_DS_V2S(X) (X).second +#define PB_DS_EP2VP(X)& ((X)->m_value) +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#define PB_DS_V2F(X) (X) +#define PB_DS_V2S(X) Mapped_Data() +#define PB_DS_EP2VP(X)& ((X)->m_value.first) +#endif + + /* Skip to the lu, my darling. */ + // list-based (with updates) associative container. + template<typename Key, + typename Mapped, + class Eq_Fn, + class Allocator, + class Update_Policy> + class PB_DS_CLASS_NAME : +#ifdef _GLIBCXX_DEBUG + protected PB_DS_MAP_DEBUG_BASE_C_DEC, +#endif + public PB_DS_TYPES_TRAITS_C_DEC + { + private: + typedef PB_DS_TYPES_TRAITS_C_DEC traits_base; + + struct entry + : public lu_map_entry_metadata_base<typename Update_Policy::metadata_type> + { + typename traits_base::value_type m_value; + typename Allocator::template rebind<entry>::other::pointer m_p_next; + }; + + typedef typename Allocator::template rebind<entry>::other entry_allocator; + typedef typename entry_allocator::pointer entry_pointer; + typedef typename entry_allocator::const_pointer const_entry_pointer; + typedef typename entry_allocator::reference entry_reference; + typedef typename entry_allocator::const_reference const_entry_reference; + + typedef typename Allocator::template rebind<entry_pointer>::other entry_pointer_allocator; + typedef typename entry_pointer_allocator::pointer entry_pointer_array; + + typedef typename traits_base::value_type value_type_; + typedef typename traits_base::pointer pointer_; + typedef typename traits_base::const_pointer const_pointer_; + typedef typename traits_base::reference reference_; + typedef typename traits_base::const_reference const_reference_; + +#define PB_DS_GEN_POS entry_pointer + +#include <ext/pb_ds/detail/unordered_iterator/const_point_iterator.hpp> +#include <ext/pb_ds/detail/unordered_iterator/point_iterator.hpp> +#include <ext/pb_ds/detail/unordered_iterator/const_iterator.hpp> +#include <ext/pb_ds/detail/unordered_iterator/iterator.hpp> + +#undef PB_DS_GEN_POS + + +#ifdef _GLIBCXX_DEBUG + typedef PB_DS_MAP_DEBUG_BASE_C_DEC map_debug_base; +#endif + + typedef cond_dealtor<entry, Allocator> cond_dealtor_t; + + public: + typedef Allocator allocator; + typedef typename Allocator::size_type size_type; + typedef typename Allocator::difference_type difference_type; + typedef Eq_Fn eq_fn; + typedef Update_Policy update_policy; + typedef typename Update_Policy::metadata_type update_metadata; + typedef typename traits_base::key_type key_type; + typedef typename traits_base::key_pointer key_pointer; + typedef typename traits_base::const_key_pointer const_key_pointer; + typedef typename traits_base::key_reference key_reference; + typedef typename traits_base::const_key_reference const_key_reference; + typedef typename traits_base::mapped_type mapped_type; + typedef typename traits_base::mapped_pointer mapped_pointer; + typedef typename traits_base::const_mapped_pointer const_mapped_pointer; + typedef typename traits_base::mapped_reference mapped_reference; + typedef typename traits_base::const_mapped_reference const_mapped_reference; + typedef typename traits_base::value_type value_type; + typedef typename traits_base::pointer pointer; + typedef typename traits_base::const_pointer const_pointer; + typedef typename traits_base::reference reference; + typedef typename traits_base::const_reference const_reference; + +#ifdef PB_DS_DATA_TRUE_INDICATOR + typedef point_iterator_ point_iterator; +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR + typedef const_point_iterator_ point_iterator; +#endif + + typedef const_point_iterator_ const_point_iterator; + +#ifdef PB_DS_DATA_TRUE_INDICATOR + typedef iterator_ iterator; +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR + typedef const_iterator_ iterator; +#endif + + typedef const_iterator_ const_iterator; + + public: + PB_DS_CLASS_NAME(); + + PB_DS_CLASS_NAME(const PB_DS_CLASS_C_DEC&); + + virtual + ~PB_DS_CLASS_NAME(); + + template<typename It> + PB_DS_CLASS_NAME(It first_it, It last_it); + + void + swap(PB_DS_CLASS_C_DEC&); + + inline size_type + size() const; + + inline size_type + max_size() const; + + inline bool + empty() const; + + inline mapped_reference + operator[](const_key_reference r_key) + { +#ifdef PB_DS_DATA_TRUE_INDICATOR + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return insert(std::make_pair(r_key, mapped_type())).first->second; +#else + insert(r_key); + return traits_base::s_null_mapped; +#endif + } + + inline std::pair<point_iterator, bool> + insert(const_reference); + + inline point_iterator + find(const_key_reference r_key) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + entry_pointer p_e = find_imp(r_key); + return point_iterator(p_e == NULL ? NULL: &p_e->m_value); + } + + inline const_point_iterator + find(const_key_reference r_key) const + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + entry_pointer p_e = find_imp(r_key); + return const_point_iterator(p_e == NULL ? NULL: &p_e->m_value); + } + + inline bool + erase(const_key_reference); + + template<typename Pred> + inline size_type + erase_if(Pred); + + void + clear(); + + inline iterator + begin(); + + inline const_iterator + begin() const; + + inline iterator + end(); + + inline const_iterator + end() const; + +#ifdef _GLIBCXX_DEBUG + void + assert_valid() const; +#endif + +#ifdef PB_DS_LU_MAP_TRACE_ + void + trace() const; +#endif + + protected: + + template<typename It> + void + copy_from_range(It, It); + + private: +#ifdef PB_DS_DATA_TRUE_INDICATOR + friend class iterator_; +#endif + + friend class const_iterator_; + + inline entry_pointer + allocate_new_entry(const_reference, false_type); + + inline entry_pointer + allocate_new_entry(const_reference, true_type); + + template<typename Metadata> + inline static void + init_entry_metadata(entry_pointer, type_to_type<Metadata>); + + inline static void + init_entry_metadata(entry_pointer, type_to_type<null_lu_metadata>); + + void + deallocate_all(); + + void + erase_next(entry_pointer); + + void + actual_erase_entry(entry_pointer); + + void + inc_it_state(const_pointer& r_p_value, entry_pointer& r_pos) const + { + r_pos = r_pos->m_p_next; + r_p_value = (r_pos == NULL) ? NULL : &r_pos->m_value; + } + + template<typename Metadata> + inline static bool + apply_update(entry_pointer, type_to_type<Metadata>); + + inline static bool + apply_update(entry_pointer, type_to_type<null_lu_metadata>); + + inline entry_pointer + find_imp(const_key_reference) const; + + static entry_allocator s_entry_allocator; + static Eq_Fn s_eq_fn; + static Update_Policy s_update_policy; + static type_to_type<update_metadata> s_metadata_type_indicator; + static null_lu_metadata s_null_lu_metadata; + + mutable entry_pointer m_p_l; + }; + +#include <ext/pb_ds/detail/list_update_map_/constructor_destructor_fn_imps.hpp> +#include <ext/pb_ds/detail/list_update_map_/info_fn_imps.hpp> +#include <ext/pb_ds/detail/list_update_map_/debug_fn_imps.hpp> +#include <ext/pb_ds/detail/list_update_map_/iterators_fn_imps.hpp> +#include <ext/pb_ds/detail/list_update_map_/erase_fn_imps.hpp> +#include <ext/pb_ds/detail/list_update_map_/find_fn_imps.hpp> +#include <ext/pb_ds/detail/list_update_map_/insert_fn_imps.hpp> +#include <ext/pb_ds/detail/list_update_map_/trace_fn_imps.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_TYPES_TRAITS_C_DEC +#undef PB_DS_MAP_DEBUG_BASE_C_DEC +#undef PB_DS_CLASS_NAME +#undef PB_DS_V2F +#undef PB_DS_EP2VP +#undef PB_DS_V2S + + } // namespace detail +} // namespace pb_ds diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/list_update_map_/trace_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/list_update_map_/trace_fn_imps.hpp new file mode 100644 index 000000000000..28bd7c4f6e75 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/list_update_map_/trace_fn_imps.hpp @@ -0,0 +1,65 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file trace_fn_imps.hpp + * Contains implementations of lu_map_. + */ + +#ifdef PB_DS_LU_MAP_TRACE_ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +trace() const +{ + std::cerr << m_p_l << std::endl << std::endl; + const_entry_pointer p_l = m_p_l; + while (p_l != NULL) + { + std::cerr << PB_DS_V2F(p_l->m_value) << std::endl; + p_l = p_l->m_p_next; + } + std::cerr << std::endl; +} + +#endif + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/list_update_policy/counter_lu_metadata.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/list_update_policy/counter_lu_metadata.hpp new file mode 100644 index 000000000000..d8cd28916831 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/list_update_policy/counter_lu_metadata.hpp @@ -0,0 +1,92 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file counter_lu_metadata.hpp + * Contains implementation of a lu counter policy's metadata. + */ + +namespace pb_ds +{ + namespace detail + { + template<typename Size_Type> + class counter_lu_policy_base; + + // A list-update metadata type that moves elements to the front of + // the list based on the counter algorithm. + template<typename Size_Type = size_t> + class counter_lu_metadata + { + public: + typedef Size_Type size_type; + + private: + counter_lu_metadata(size_type init_count) : m_count(init_count) + { } + + friend class counter_lu_policy_base<size_type>; + + mutable size_type m_count; + }; + + template<typename Size_Type> + class counter_lu_policy_base + { + protected: + typedef Size_Type size_type; + + counter_lu_metadata<size_type> + operator()(size_type max_size) const + { return counter_lu_metadata<Size_Type>(rand() % max_size); } + + template<typename Metadata_Reference> + bool + operator()(Metadata_Reference r_data, size_type m_max_count) const + { + if (++r_data.m_count != m_max_count) + return false; + r_data.m_count = 0; + return true; + } + }; + } // namespace detail +} // namespace pb_ds diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/list_update_policy/counter_lu_policy_imp.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/list_update_policy/counter_lu_policy_imp.hpp new file mode 100644 index 000000000000..42e1bdf2836c --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/list_update_policy/counter_lu_policy_imp.hpp @@ -0,0 +1,57 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file counter_lu_policy_imp.hpp + * Contains a lu counter policy implementation. + */ + +PB_DS_CLASS_T_DEC +detail::counter_lu_metadata<typename Allocator::size_type> +PB_DS_CLASS_C_DEC:: +operator()() const +{ return (base_type::operator()(max_count)); } + +PB_DS_CLASS_T_DEC +bool +PB_DS_CLASS_C_DEC:: +operator()(metadata_reference r_data) const +{ return (base_type::operator()(r_data, max_count)); } diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/list_update_policy/mtf_lu_policy_imp.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/list_update_policy/mtf_lu_policy_imp.hpp new file mode 100644 index 000000000000..8f9d9460df21 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/list_update_policy/mtf_lu_policy_imp.hpp @@ -0,0 +1,61 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file mtf_lu_policy_imp.hpp + * Contains a move-to-front policy implementation. + */ + +PB_DS_CLASS_T_DEC +null_lu_metadata PB_DS_CLASS_C_DEC::s_metadata; + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::metadata_type +PB_DS_CLASS_C_DEC:: +operator()() const +{ return s_metadata; } + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +operator()(metadata_reference /*r_data*/) const +{ return true; } + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/list_update_policy/sample_update_policy.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/list_update_policy/sample_update_policy.hpp new file mode 100644 index 000000000000..8cfc1f2310d1 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/list_update_policy/sample_update_policy.hpp @@ -0,0 +1,80 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file sample_update_policy.hpp + * Contains a sample policy for list update containers. + */ + +#ifndef PB_DS_SAMPLE_UPDATE_POLICY_HPP +#define PB_DS_SAMPLE_UPDATE_POLICY_HPP + +// A sample list-update policy. +struct sample_update_policy +{ + // Default constructor. + sample_update_policy(); + + // Copy constructor. + sample_update_policy(const sample_update_policy&); + + // Swaps content. + inline void + swap(sample_update_policy& other); + +protected: + // Metadata on which this functor operates. + typedef some_metadata_type metadata_type; + + // Creates a metadata object. + metadata_type + operator()() const; + + // Decides whether a metadata object should be moved to the front of + // the list. A list-update based containers object will call this + // method to decide whether to move a node to the front of the + // list. The method shoule return true if the node should be moved + // to the front of the list. + bool + operator()(metadata_reference) const; +}; + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/map_debug_base.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/map_debug_base.hpp new file mode 100644 index 000000000000..d31a0c2699c0 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/map_debug_base.hpp @@ -0,0 +1,356 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file map_debug_base.hpp + * Contains a debug-mode base for all maps. + */ + +#ifndef PB_DS_MAP_DEBUG_BASE_HPP +#define PB_DS_MAP_DEBUG_BASE_HPP + +#ifdef _GLIBCXX_DEBUG + +#include <list> +#include <utility> +#include <ext/throw_allocator.h> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_CLASS_T_DEC \ + template<typename Key, class Eq_Fn, typename Const_Key_Reference> + +#define PB_DS_CLASS_C_DEC \ + map_debug_base<Key, Eq_Fn, Const_Key_Reference> + + template<typename Key, class Eq_Fn, typename Const_Key_Reference> + class map_debug_base + { + private: + typedef typename std::allocator< Key> key_allocator; + + typedef typename key_allocator::size_type size_type; + + typedef Const_Key_Reference const_key_reference; + + protected: + map_debug_base(); + + map_debug_base(const PB_DS_CLASS_C_DEC& other); + + ~map_debug_base(); + + inline void + insert_new(const_key_reference r_key); + + inline void + erase_existing(const_key_reference r_key); + + void + clear(); + + inline void + check_key_exists(const_key_reference r_key) const; + + inline void + check_key_does_not_exist(const_key_reference r_key) const; + + inline void + check_size(size_type size) const; + + void + swap(PB_DS_CLASS_C_DEC& other); + + template<typename Cmp_Fn> + void + split(const_key_reference, Cmp_Fn, PB_DS_CLASS_C_DEC&); + + void + join(PB_DS_CLASS_C_DEC& other); + + private: + typedef std::list< Key> key_set; + typedef typename key_set::iterator key_set_iterator; + typedef typename key_set::const_iterator const_key_set_iterator; + +#ifdef _GLIBCXX_DEBUG + void + assert_valid() const; +#endif + + const_key_set_iterator + find(const_key_reference r_key) const; + + key_set_iterator + find(const_key_reference r_key); + + key_set m_key_set; + Eq_Fn m_eq; + }; + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + map_debug_base() + { _GLIBCXX_DEBUG_ONLY(assert_valid();) } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + map_debug_base(const PB_DS_CLASS_C_DEC& other) : m_key_set(other.m_key_set) + { _GLIBCXX_DEBUG_ONLY(assert_valid();) } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ~map_debug_base() + { _GLIBCXX_DEBUG_ONLY(assert_valid();) } + + PB_DS_CLASS_T_DEC + inline void + PB_DS_CLASS_C_DEC:: + insert_new(const_key_reference r_key) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + __gnu_cxx::throw_allocator<char> alloc; + const double orig_throw_prob = alloc.get_throw_prob(); + alloc.set_throw_prob(0); + if (find(r_key) != m_key_set.end()) + { + std::cerr << "insert_new " << r_key << std::endl; + abort(); + } + + try + { + m_key_set.push_back(r_key); + } + catch(...) + { + std::cerr << "insert_new 1" << r_key << std::endl; + abort(); + } + alloc.set_throw_prob(orig_throw_prob); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + + PB_DS_CLASS_T_DEC + inline void + PB_DS_CLASS_C_DEC:: + erase_existing(const_key_reference r_key) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + key_set_iterator it = find(r_key); + if (it == m_key_set.end()) + { + std::cerr << "erase_existing " << r_key << std::endl; + abort(); + } + m_key_set.erase(it); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + clear() + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + m_key_set.clear(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + + PB_DS_CLASS_T_DEC + inline void + PB_DS_CLASS_C_DEC:: + check_key_exists(const_key_reference r_key) const + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + if (find(r_key) == m_key_set.end()) + { + std::cerr << "check_key_exists " << r_key << std::endl; + abort(); + } + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + + PB_DS_CLASS_T_DEC + inline void + PB_DS_CLASS_C_DEC:: + check_key_does_not_exist(const_key_reference r_key) const + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + if (find(r_key) != m_key_set.end()) + { + std::cerr << "check_key_does_not_exist " << r_key << std::endl; + abort(); + } + } + + PB_DS_CLASS_T_DEC + inline void + PB_DS_CLASS_C_DEC:: + check_size(size_type size) const + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + const size_type key_set_size = m_key_set.size(); + if (size != key_set_size) + { + std::cerr << "check_size " << size + << " " << key_set_size << std::endl; + abort(); + } + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + swap(PB_DS_CLASS_C_DEC& other) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + m_key_set.swap(other.m_key_set); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::const_key_set_iterator + PB_DS_CLASS_C_DEC:: + find(const_key_reference r_key) const + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + typedef const_key_set_iterator iterator_type; + for (iterator_type it = m_key_set.begin(); it != m_key_set.end(); ++it) + if (m_eq(*it, r_key)) + return it; + return m_key_set.end(); + } + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::key_set_iterator + PB_DS_CLASS_C_DEC:: + find(const_key_reference r_key) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + key_set_iterator it = m_key_set.begin(); + while (it != m_key_set.end()) + { + if (m_eq(*it, r_key)) + return it; + ++it; + } + return it; + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + +#ifdef _GLIBCXX_DEBUG + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + assert_valid() const + { + const_key_set_iterator prime_it = m_key_set.begin(); + while (prime_it != m_key_set.end()) + { + const_key_set_iterator sec_it = prime_it; + ++sec_it; + while (sec_it != m_key_set.end()) + { + _GLIBCXX_DEBUG_ASSERT(!m_eq(*sec_it, *prime_it)); + _GLIBCXX_DEBUG_ASSERT(!m_eq(*prime_it, *sec_it)); + ++sec_it; + } + ++prime_it; + } + } +#endif + + PB_DS_CLASS_T_DEC + template<typename Cmp_Fn> + void + PB_DS_CLASS_C_DEC:: + split(const_key_reference r_key, Cmp_Fn cmp_fn, PB_DS_CLASS_C_DEC& other) + { + __gnu_cxx::throw_allocator<char> alloc; + const double orig_throw_prob = alloc.get_throw_prob(); + alloc.set_throw_prob(0); + other.clear(); + key_set_iterator it = m_key_set.begin(); + while (it != m_key_set.end()) + if (cmp_fn(r_key, * it)) + { + other.insert_new(*it); + it = m_key_set.erase(it); + } + else + ++it; + alloc.set_throw_prob(orig_throw_prob); + } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + join(PB_DS_CLASS_C_DEC& other) + { + __gnu_cxx::throw_allocator<char> alloc; + const double orig_throw_prob = alloc.get_throw_prob(); + alloc.set_throw_prob(0); + key_set_iterator it = other.m_key_set.begin(); + while (it != other.m_key_set.end()) + { + insert_new(*it); + it = other.m_key_set.erase(it); + } + _GLIBCXX_DEBUG_ASSERT(other.m_key_set.empty()); + alloc.set_throw_prob(orig_throw_prob); + } + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +} // namespace detail +} // namespace pb_ds + +#endif + +#endif + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/cond_dtor.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/cond_dtor.hpp new file mode 100644 index 000000000000..072fce447a8f --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/cond_dtor.hpp @@ -0,0 +1,80 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file cond_dtor.hpp + * Contains a conditional destructor + */ + +template<typename Size_Type> +class cond_dtor +{ +public: + cond_dtor(value_vector a_vec, iterator& r_last_it, Size_Type total_size) + : m_a_vec(a_vec), m_r_last_it(r_last_it), m_max_size(total_size), + m_no_action(false) + { } + + ~cond_dtor() + { + if (m_no_action) + return; + iterator it = m_a_vec; + while (it != m_r_last_it) + { + it->~value_type(); + ++it; + } + + if (m_max_size > 0) + value_allocator().deallocate(m_a_vec, m_max_size); + } + + inline void + set_no_action() + { m_no_action = true; } + +protected: + value_vector m_a_vec; + iterator& m_r_last_it; + const Size_Type m_max_size; + bool m_no_action; +}; diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/constructors_destructor_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/constructors_destructor_fn_imps.hpp new file mode 100644 index 000000000000..83a47250f83f --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/constructors_destructor_fn_imps.hpp @@ -0,0 +1,279 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructors_destructor_fn_imps.hpp + * Contains an implementation class for ov_tree_. + */ + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::value_allocator +PB_DS_CLASS_C_DEC::s_value_alloc; + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::metadata_allocator +PB_DS_CLASS_C_DEC::s_metadata_alloc; + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_OV_TREE_CLASS_NAME() : + m_a_values(NULL), + m_a_metadata(NULL), + m_end_it(NULL), + m_size(0) +{ _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_OV_TREE_CLASS_NAME(const Cmp_Fn& r_cmp_fn) : + cmp_fn_base(r_cmp_fn), + m_a_values(NULL), + m_a_metadata(NULL), + m_end_it(NULL), + m_size(0) +{ _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_OV_TREE_CLASS_NAME(const Cmp_Fn& r_cmp_fn, const node_update& r_node_update) : + cmp_fn_base(r_cmp_fn), + node_update(r_node_update), + m_a_values(NULL), + m_a_metadata(NULL), + m_end_it(NULL), + m_size(0) +{ _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_OV_TREE_CLASS_NAME(const PB_DS_CLASS_C_DEC& other) : +#ifdef _GLIBCXX_DEBUG + map_debug_base(other), +#endif +#ifdef PB_DS_TREE_TRACE + PB_DS_TREE_TRACE_BASE_C_DEC(other), +#endif + cmp_fn_base(other), + node_update(other), + m_a_values(NULL), + m_a_metadata(NULL), + m_end_it(NULL), + m_size(0) +{ + copy_from_ordered_range(other.begin(), other.end()); + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) +} + +PB_DS_CLASS_T_DEC +template<typename It> +inline void +PB_DS_CLASS_C_DEC:: +copy_from_range(It first_it, It last_it) +{ +#ifdef PB_DS_DATA_TRUE_INDICATOR + typedef + std::map< + key_type, + mapped_type, + Cmp_Fn, + typename Allocator::template rebind< + value_type>::other> + map_type; +#else + typedef + std::set< + key_type, + Cmp_Fn, + typename Allocator::template rebind< + Key>::other> + map_type; +#endif + + map_type m(first_it, last_it); + copy_from_ordered_range(m.begin(), m.end()); +} + +PB_DS_CLASS_T_DEC +template<typename It> +void +PB_DS_CLASS_C_DEC:: +copy_from_ordered_range(It first_it, It last_it) +{ + const size_type len = std::distance(first_it, last_it); + if (len == 0) + return; + + value_vector a_values = s_value_alloc.allocate(len); + iterator target_it = a_values; + It source_it = first_it; + It source_end_it = last_it; + + cond_dtor<size_type> cd(a_values, target_it, len); + while (source_it != source_end_it) + { + new (const_cast<void* >(static_cast<const void* >(target_it))) + value_type(*source_it++); + + ++target_it; + } + + reallocate_metadata((node_update* )this, len); + cd.set_no_action(); + m_a_values = a_values; + m_size = len; + m_end_it = m_a_values + m_size; + update(PB_DS_node_begin_imp(), (node_update* )this); + +#ifdef _GLIBCXX_DEBUG + const_iterator dbg_it = m_a_values; + while (dbg_it != m_end_it) + { + map_debug_base::insert_new(PB_DS_V2F(*dbg_it)); + dbg_it++; + } + PB_DS_CLASS_C_DEC::assert_valid(); +#endif +} + +PB_DS_CLASS_T_DEC +template<typename It> +void +PB_DS_CLASS_C_DEC:: +copy_from_ordered_range(It first_it, It last_it, It other_first_it, + It other_last_it) +{ + clear(); + const size_type len = std::distance(first_it, last_it) + + std::distance(other_first_it, other_last_it); + + value_vector a_values = s_value_alloc.allocate(len); + + iterator target_it = a_values; + It source_it = first_it; + It source_end_it = last_it; + + cond_dtor<size_type> cd(a_values, target_it, len); + while (source_it != source_end_it) + { + new (const_cast<void* >(static_cast<const void* >(target_it))) + value_type(*source_it++); + ++target_it; + } + + source_it = other_first_it; + source_end_it = other_last_it; + + while (source_it != source_end_it) + { + new (const_cast<void* >(static_cast<const void* >(target_it))) + value_type(*source_it++); + ++target_it; + } + + reallocate_metadata((node_update* )this, len); + cd.set_no_action(); + m_a_values = a_values; + m_size = len; + m_end_it = m_a_values + m_size; + update(PB_DS_node_begin_imp(), (node_update* )this); + +#ifdef _GLIBCXX_DEBUG + const_iterator dbg_it = m_a_values; + while (dbg_it != m_end_it) + { + map_debug_base::insert_new(PB_DS_V2F(*dbg_it)); + dbg_it++; + } + PB_DS_CLASS_C_DEC::assert_valid(); +#endif +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + value_swap(other); + std::swap((Cmp_Fn& )(*this), (Cmp_Fn& )other); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +value_swap(PB_DS_CLASS_C_DEC& other) +{ + std::swap(m_a_values, other.m_a_values); + std::swap(m_a_metadata, other.m_a_metadata); + std::swap(m_size, other.m_size); + std::swap(m_end_it, other.m_end_it); + _GLIBCXX_DEBUG_ONLY(map_debug_base::swap(other);) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +~PB_DS_OV_TREE_CLASS_NAME() +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + cond_dtor<size_type> cd(m_a_values, m_end_it, m_size); + reallocate_metadata((node_update* )this, 0); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +update(node_iterator /*it*/, null_node_update_pointer) +{ } + +PB_DS_CLASS_T_DEC +template<typename Node_Update> +void +PB_DS_CLASS_C_DEC:: +update(node_iterator nd_it, Node_Update* p_update) +{ + const_node_iterator end_it = PB_DS_node_end_imp(); + if (nd_it == end_it) + return; + update(nd_it.get_l_child(), p_update); + update(nd_it.get_r_child(), p_update); + node_update::operator()(nd_it, end_it); +} diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/debug_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/debug_fn_imps.hpp new file mode 100644 index 000000000000..b1a36555ce33 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/debug_fn_imps.hpp @@ -0,0 +1,90 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_fn_imps.hpp + * Contains an implementation class for ov_tree_. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_valid() const +{ + std::cout << "av1" << std::endl; + + if (m_a_values == NULL || m_end_it == NULL || m_size == 0) + _GLIBCXX_DEBUG_ASSERT(m_a_values == NULL && m_end_it == NULL && m_size == 0); + + std::cout << "av2" << std::endl; + assert_iterators(); + std::cout << "av3" << std::endl; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_iterators() const +{ + map_debug_base::check_size(m_size); + size_type iterated_num = 0; + const_iterator prev_it = end(); + _GLIBCXX_DEBUG_ASSERT( m_end_it == m_a_values + m_size); + for (const_iterator it = begin(); it != end(); ++it) + { + ++iterated_num; + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(PB_DS_V2F(*it));) + _GLIBCXX_DEBUG_ASSERT(lower_bound(PB_DS_V2F(*it)) == it); + const_iterator upper_bound_it = upper_bound(PB_DS_V2F(*it)); + --upper_bound_it; + _GLIBCXX_DEBUG_ASSERT(upper_bound_it == it); + if (prev_it != end()) + _GLIBCXX_DEBUG_ASSERT(Cmp_Fn::operator()(PB_DS_V2F(*prev_it), + PB_DS_V2F(*it))); + prev_it = it; + } + _GLIBCXX_DEBUG_ASSERT(iterated_num == m_size); +} + +#endif + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/erase_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/erase_fn_imps.hpp new file mode 100644 index 000000000000..936d5492e8d1 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/erase_fn_imps.hpp @@ -0,0 +1,199 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file erase_fn_imps.hpp + * Contains an implementation class for ov_tree_. + */ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +clear() +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + if (m_size == 0) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return; + } + else + { + reallocate_metadata((node_update* )this, 0); + cond_dtor<size_type> cd(m_a_values, m_end_it, m_size); + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::clear();) + m_a_values = NULL; + m_size = 0; + m_end_it = m_a_values; + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +template<typename Pred> +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +erase_if(Pred pred) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + +#ifdef PB_DS_REGRESSION + typename Allocator::group_throw_prob_adjustor adjust(m_size); +#endif + + size_type new_size = 0; + size_type num_val_ersd = 0; + iterator source_it = m_a_values; + for (source_it = begin(); source_it != m_end_it; ++source_it) + if (!pred(*source_it)) + ++new_size; + else + ++num_val_ersd; + + if (new_size == 0) + { + clear(); + return num_val_ersd; + } + + value_vector a_new_values = s_value_alloc.allocate(new_size); + iterator target_it = a_new_values; + cond_dtor<size_type> cd(a_new_values, target_it, new_size); + _GLIBCXX_DEBUG_ONLY(map_debug_base::clear()); + for (source_it = begin(); source_it != m_end_it; ++source_it) + { + if (!pred(*source_it)) + { + new (const_cast<void*>(static_cast<const void* >(target_it))) + value_type(*source_it); + + _GLIBCXX_DEBUG_ONLY(map_debug_base::insert_new(PB_DS_V2F(*source_it))); + ++target_it; + } + } + + reallocate_metadata((node_update* )this, new_size); + cd.set_no_action(); + + { + cond_dtor<size_type> cd1(m_a_values, m_end_it, m_size); + } + + m_a_values = a_new_values; + m_size = new_size; + m_end_it = target_it; + update(node_begin(), (node_update* )this); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return num_val_ersd; +} + +PB_DS_CLASS_T_DEC +template<typename It> +It +PB_DS_CLASS_C_DEC:: +erase_imp(It it) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + if (it == end()) + return end(); + + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::check_key_exists(PB_DS_V2F(*it));) + +#ifdef PB_DS_REGRESSION + typename Allocator::group_throw_prob_adjustor adjust(m_size); +#endif + + _GLIBCXX_DEBUG_ASSERT(m_size > 0); + value_vector a_values = s_value_alloc.allocate(m_size - 1); + iterator source_it = begin(); + iterator source_end_it = end(); + iterator target_it = a_values; + iterator ret_it = end(); + + cond_dtor<size_type> cd(a_values, target_it, m_size - 1); + + _GLIBCXX_DEBUG_ONLY(size_type cnt = 0;) + + while (source_it != source_end_it) + { + if (source_it != it) + { + _GLIBCXX_DEBUG_ONLY(++cnt;) + _GLIBCXX_DEBUG_ASSERT(cnt != m_size); + new (const_cast<void* >(static_cast<const void* >(target_it))) + value_type(*source_it); + + ++target_it; + } + else + ret_it = target_it; + ++source_it; + } + + _GLIBCXX_DEBUG_ASSERT(m_size > 0); + reallocate_metadata((node_update* )this, m_size - 1); + cd.set_no_action(); + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::erase_existing(PB_DS_V2F(*it));) + { + cond_dtor<size_type> cd1(m_a_values, m_end_it, m_size); + } + + m_a_values = a_values; + --m_size; + m_end_it = m_a_values + m_size; + update(node_begin(), (node_update* )this); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return It(ret_it); +} + +PB_DS_CLASS_T_DEC +bool +PB_DS_CLASS_C_DEC:: +erase(const_key_reference r_key) +{ + point_iterator it = find(r_key); + if (it == end()) + return false; + erase(it); + return true; +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/info_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/info_fn_imps.hpp new file mode 100644 index 000000000000..05161cb97499 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/info_fn_imps.hpp @@ -0,0 +1,66 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file info_fn_imps.hpp + * Contains an implementation class for ov_tree_. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +size() const +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return m_size; +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +max_size() const +{ return s_value_alloc.max_size(); } + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +empty() const +{ return size() == 0; } diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/insert_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/insert_fn_imps.hpp new file mode 100644 index 000000000000..16d6f04e683c --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/insert_fn_imps.hpp @@ -0,0 +1,69 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file insert_fn_imps.hpp + * Contains an implementation class for ov_tree_. + */ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +reallocate_metadata(null_node_update_pointer, size_type) +{ } + +PB_DS_CLASS_T_DEC +template<typename Node_Update_> +void +PB_DS_CLASS_C_DEC:: +reallocate_metadata(Node_Update_* , size_type new_size) +{ + metadata_pointer a_new_metadata_vec =(new_size == 0) ? NULL : s_metadata_alloc.allocate(new_size); + + if (m_a_metadata != NULL) + { + for (size_type i = 0; i < m_size; ++i) + m_a_metadata[i].~metadata_type(); + s_metadata_alloc.deallocate(m_a_metadata, m_size); + } + std::swap(m_a_metadata, a_new_metadata_vec); +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/iterators_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/iterators_fn_imps.hpp new file mode 100644 index 000000000000..38d4cee5d41c --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/iterators_fn_imps.hpp @@ -0,0 +1,109 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file iterators_fn_imps.hpp + * Contains an implementation class for ov_tree_. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_node_iterator +PB_DS_CLASS_C_DEC:: +node_begin() const +{ return PB_DS_node_begin_imp(); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_node_iterator +PB_DS_CLASS_C_DEC:: +node_end() const +{ return PB_DS_node_end_imp(); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_iterator +PB_DS_CLASS_C_DEC:: +node_begin() +{ return PB_DS_node_begin_imp(); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_iterator +PB_DS_CLASS_C_DEC:: +node_end() +{ return PB_DS_node_end_imp(); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_node_iterator +PB_DS_CLASS_C_DEC:: +PB_DS_node_begin_imp() const +{ + return const_node_iterator(const_cast<pointer>(mid_pointer(begin(), end())), + const_cast<pointer>(begin()), + const_cast<pointer>(end()),(m_a_metadata == NULL)? + NULL : + mid_pointer(m_a_metadata, m_a_metadata + m_size)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_node_iterator +PB_DS_CLASS_C_DEC:: +PB_DS_node_end_imp() const +{ + return const_node_iterator(end(), end(), end(), + (m_a_metadata == NULL) ? NULL : m_a_metadata + m_size); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_iterator +PB_DS_CLASS_C_DEC:: +PB_DS_node_begin_imp() +{ + return node_iterator(mid_pointer(begin(), end()), begin(), end(), + (m_a_metadata == NULL) ? NULL : mid_pointer(m_a_metadata, m_a_metadata + m_size)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_iterator +PB_DS_CLASS_C_DEC:: +PB_DS_node_end_imp() +{ + return node_iterator(end(), end(), + end(),(m_a_metadata == NULL) ? NULL : m_a_metadata + m_size); +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/node_iterators.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/node_iterators.hpp new file mode 100644 index 000000000000..d64ad2023396 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/node_iterators.hpp @@ -0,0 +1,303 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file node_iterators.hpp + * Contains an implementation class for ov_tree_. + */ + +#ifndef PB_DS_OV_TREE_NODE_ITERATORS_HPP +#define PB_DS_OV_TREE_NODE_ITERATORS_HPP + +#include <ext/pb_ds/tag_and_trait.hpp> +#include <ext/pb_ds/detail/type_utils.hpp> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { +#define PB_DS_STATIC_ASSERT(UNIQUE, E) \ + typedef \ + static_assert_dumclass<sizeof(static_assert<(bool)(E)>)> \ + UNIQUE##static_assert_type + +#define PB_DS_OV_TREE_CONST_NODE_ITERATOR_C_DEC \ + ov_tree_node_const_it_<Value_Type, Metadata_Type, Allocator> + + // Const node reference. + template<typename Value_Type, typename Metadata_Type, class Allocator> + class ov_tree_node_const_it_ + { + + protected: + typedef + typename Allocator::template rebind< + Value_Type>::other::pointer + pointer; + + typedef + typename Allocator::template rebind< + Value_Type>::other::const_pointer + const_pointer; + + typedef + typename Allocator::template rebind< + Metadata_Type>::other::const_pointer + const_metadata_pointer; + + typedef PB_DS_OV_TREE_CONST_NODE_ITERATOR_C_DEC this_type; + + protected: + + template<typename Ptr> + inline static Ptr + mid_pointer(Ptr p_begin, Ptr p_end) + { + _GLIBCXX_DEBUG_ASSERT(p_end >= p_begin); + return (p_begin + (p_end - p_begin) / 2); + } + + public: + + typedef trivial_iterator_tag iterator_category; + + typedef trivial_iterator_difference_type difference_type; + + typedef + typename Allocator::template rebind< + Value_Type>::other::const_pointer + value_type; + + typedef + typename Allocator::template rebind< + typename remove_const< + Value_Type>::type>::other::const_pointer + reference; + + typedef + typename Allocator::template rebind< + typename remove_const< + Value_Type>::type>::other::const_pointer + const_reference; + + typedef Metadata_Type metadata_type; + + typedef + typename Allocator::template rebind< + metadata_type>::other::const_reference + const_metadata_reference; + + public: + inline + ov_tree_node_const_it_(const_pointer p_nd = NULL, const_pointer p_begin_nd = NULL, const_pointer p_end_nd = NULL, const_metadata_pointer p_metadata = NULL) : m_p_value(const_cast<pointer>(p_nd)), m_p_begin_value(const_cast<pointer>(p_begin_nd)), m_p_end_value(const_cast<pointer>(p_end_nd)), m_p_metadata(p_metadata) + { } + + inline const_reference + operator*() const + { return m_p_value; } + + inline const_metadata_reference + get_metadata() const + { + enum + { + has_metadata = !is_same<Metadata_Type, null_node_metadata>::value + }; + + PB_DS_STATIC_ASSERT(should_have_metadata, has_metadata); + _GLIBCXX_DEBUG_ASSERT(m_p_metadata != NULL); + return *m_p_metadata; + } + + inline this_type + get_l_child() const + { + if (m_p_begin_value == m_p_value) + return (this_type(m_p_begin_value, m_p_begin_value, m_p_begin_value)); + + const_metadata_pointer p_begin_metadata = + m_p_metadata - (m_p_value - m_p_begin_value); + + return (this_type(mid_pointer(m_p_begin_value, m_p_value), + m_p_begin_value, + m_p_value, + mid_pointer(p_begin_metadata, m_p_metadata))); + } + + inline this_type + get_r_child() const + { + if (m_p_value == m_p_end_value) + return (this_type(m_p_end_value, m_p_end_value, m_p_end_value)); + + const_metadata_pointer p_end_metadata = + m_p_metadata + (m_p_end_value - m_p_value); + + return (this_type(mid_pointer(m_p_value + 1, m_p_end_value), + m_p_value + 1, + m_p_end_value,(m_p_metadata == NULL) ? + NULL : mid_pointer(m_p_metadata + 1, p_end_metadata))); + } + + inline bool + operator==(const this_type& other) const + { + const bool is_end = m_p_begin_value == m_p_end_value; + const bool is_other_end = other.m_p_begin_value == other.m_p_end_value; + + if (is_end) + return (is_other_end); + + if (is_other_end) + return (is_end); + + return m_p_value == other.m_p_value; + } + + inline bool + operator!=(const this_type& other) const + { return !operator==(other); } + + public: + pointer m_p_value; + pointer m_p_begin_value; + pointer m_p_end_value; + + const_metadata_pointer m_p_metadata; + }; + +#define PB_DS_OV_TREE_NODE_ITERATOR_C_DEC \ + ov_tree_node_it_<Value_Type, Metadata_Type, Allocator> + + // Node reference. + template<typename Value_Type, typename Metadata_Type, class Allocator> + class ov_tree_node_it_ : public PB_DS_OV_TREE_CONST_NODE_ITERATOR_C_DEC + { + + private: + typedef PB_DS_OV_TREE_NODE_ITERATOR_C_DEC this_type; + + typedef PB_DS_OV_TREE_CONST_NODE_ITERATOR_C_DEC base_type; + + typedef typename base_type::pointer pointer; + + typedef typename base_type::const_pointer const_pointer; + + typedef + typename base_type::const_metadata_pointer + const_metadata_pointer; + + public: + + typedef trivial_iterator_tag iterator_category; + + typedef trivial_iterator_difference_type difference_type; + + typedef + typename Allocator::template rebind< + Value_Type>::other::pointer + value_type; + + typedef + typename Allocator::template rebind< + typename remove_const< + Value_Type>::type>::other::pointer + reference; + + typedef + typename Allocator::template rebind< + typename remove_const< + Value_Type>::type>::other::pointer + const_reference; + + public: + inline + ov_tree_node_it_(const_pointer p_nd = NULL, const_pointer p_begin_nd = NULL, const_pointer p_end_nd = NULL, const_metadata_pointer p_metadata = NULL) : base_type( p_nd, p_begin_nd, p_end_nd, p_metadata) + { } + + // Access. + inline reference + operator*() const + { return reference(base_type::m_p_value); } + + // Returns the node reference associated with the left node. + inline ov_tree_node_it_ + get_l_child() const + { + if (base_type::m_p_begin_value == base_type::m_p_value) + return (this_type(base_type::m_p_begin_value, base_type::m_p_begin_value, base_type::m_p_begin_value)); + + const_metadata_pointer p_begin_metadata = + base_type::m_p_metadata - (base_type::m_p_value - base_type::m_p_begin_value); + + return (this_type(base_type::mid_pointer(base_type::m_p_begin_value, base_type::m_p_value), + base_type::m_p_begin_value, + base_type::m_p_value, + base_type::mid_pointer(p_begin_metadata, base_type::m_p_metadata))); + } + + // Returns the node reference associated with the right node. + inline ov_tree_node_it_ + get_r_child() const + { + if (base_type::m_p_value == base_type::m_p_end_value) + return (this_type(base_type::m_p_end_value, base_type::m_p_end_value, base_type::m_p_end_value)); + + const_metadata_pointer p_end_metadata = + base_type::m_p_metadata + (base_type::m_p_end_value - base_type::m_p_value); + + return (this_type(base_type::mid_pointer(base_type::m_p_value + 1, base_type::m_p_end_value), + base_type::m_p_value + 1, + base_type::m_p_end_value,(base_type::m_p_metadata == NULL)? + NULL : base_type::mid_pointer(base_type::m_p_metadata + 1, p_end_metadata))); + } + + }; + +#undef PB_DS_OV_TREE_NODE_ITERATOR_C_DEC +#undef PB_DS_OV_TREE_CONST_NODE_ITERATOR_C_DEC +#undef PB_DS_STATIC_ASSERT + +} // namespace detail +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/ov_tree_map_.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/ov_tree_map_.hpp new file mode 100644 index 000000000000..f9e271443125 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/ov_tree_map_.hpp @@ -0,0 +1,528 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file ov_tree_map_.hpp + * Contains an implementation class for ov_tree_. + */ + +#include <map> +#include <set> +#include <ext/pb_ds/tree_policy.hpp> +#include <ext/pb_ds/detail/eq_fn/eq_by_less.hpp> +#include <ext/pb_ds/detail/types_traits.hpp> +#include <ext/pb_ds/detail/map_debug_base.hpp> +#include <ext/pb_ds/detail/type_utils.hpp> +#include <ext/pb_ds/exception.hpp> +#include <ext/pb_ds/detail/tree_trace_base.hpp> +#include <utility> +#include <functional> +#include <algorithm> +#include <vector> +#include <assert.h> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { +#define PB_DS_CLASS_T_DEC \ + template<typename Key, typename Mapped, class Cmp_Fn, \ + class Node_And_It_Traits, class Allocator> + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_OV_TREE_CLASS_NAME ov_tree_data_ +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#define PB_DS_OV_TREE_CLASS_NAME ov_tree_no_data_ +#endif + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_CONST_NODE_ITERATOR_NAME ov_tree_const_node_iterator_data_ +#else +#define PB_DS_CONST_NODE_ITERATOR_NAME ov_tree_const_node_iterator_no_data_ +#endif + +#define PB_DS_CLASS_C_DEC \ + PB_DS_OV_TREE_CLASS_NAME<Key, Mapped, Cmp_Fn, Node_And_It_Traits, Allocator> + +#define PB_DS_TYPES_TRAITS_C_DEC \ + types_traits<Key, Mapped, Allocator, false> + +#ifdef _GLIBCXX_DEBUG +#define PB_DS_MAP_DEBUG_BASE_C_DEC \ + map_debug_base<Key, eq_by_less<Key, Cmp_Fn>, \ + typename Allocator::template rebind<Key>::other::const_reference> +#endif + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_V2F(X) (X).first +#define PB_DS_V2S(X) (X).second +#define PB_DS_EP2VP(X)& ((X)->m_value) +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#define PB_DS_V2F(X) (X) +#define PB_DS_V2S(X) Mapped_Data() +#define PB_DS_EP2VP(X)& ((X)->m_value.first) +#endif + +#ifdef PB_DS_TREE_TRACE +#define PB_DS_TREE_TRACE_BASE_C_DEC \ + tree_trace_base<typename Node_And_It_Traits::const_node_iterator, \ + typename Node_And_It_Traits::node_iterator, \ + Cmp_Fn, false, Allocator> +#endif + + // Ordered-vector tree associative-container. + template<typename Key, typename Mapped, class Cmp_Fn, + class Node_And_It_Traits, class Allocator> + class PB_DS_OV_TREE_CLASS_NAME : +#ifdef _GLIBCXX_DEBUG + protected PB_DS_MAP_DEBUG_BASE_C_DEC, +#endif +#ifdef PB_DS_TREE_TRACE + public PB_DS_TREE_TRACE_BASE_C_DEC, +#endif + public Cmp_Fn, + public Node_And_It_Traits::node_update, + public PB_DS_TYPES_TRAITS_C_DEC + { + private: + typedef PB_DS_TYPES_TRAITS_C_DEC traits_base; + + typedef typename remove_const<typename traits_base::value_type>::type non_const_value_type; + + typedef typename Allocator::template rebind<non_const_value_type>::other value_allocator; + typedef typename value_allocator::pointer value_vector; + + + typedef Cmp_Fn cmp_fn_base; + +#ifdef _GLIBCXX_DEBUG + typedef PB_DS_MAP_DEBUG_BASE_C_DEC map_debug_base; +#endif + + typedef typename traits_base::pointer mapped_pointer_; + typedef typename traits_base::const_pointer const_mapped_pointer_; + + typedef typename Node_And_It_Traits::metadata_type metadata_type; + + typedef typename Allocator::template rebind<metadata_type>::other metadata_allocator; + typedef typename metadata_allocator::pointer metadata_pointer; + typedef typename metadata_allocator::const_reference const_metadata_reference; + typedef typename metadata_allocator::reference metadata_reference; + + typedef + typename Node_And_It_Traits::null_node_update_pointer + null_node_update_pointer; + + public: + + typedef Allocator allocator; + typedef typename Allocator::size_type size_type; + typedef typename Allocator::difference_type difference_type; + + typedef Cmp_Fn cmp_fn; + + typedef typename Node_And_It_Traits::node_update node_update; + + typedef typename traits_base::key_type key_type; + typedef typename traits_base::key_pointer key_pointer; + typedef typename traits_base::const_key_pointer const_key_pointer; + typedef typename traits_base::key_reference key_reference; + typedef typename traits_base::const_key_reference const_key_reference; + typedef typename traits_base::mapped_type mapped_type; + typedef typename traits_base::mapped_pointer mapped_pointer; + typedef typename traits_base::const_mapped_pointer const_mapped_pointer; + typedef typename traits_base::mapped_reference mapped_reference; + typedef typename traits_base::const_mapped_reference const_mapped_reference; + typedef typename traits_base::value_type value_type; + typedef typename traits_base::pointer pointer; + typedef typename traits_base::const_pointer const_pointer; + typedef typename traits_base::reference reference; + typedef typename traits_base::const_reference const_reference; + + typedef const_pointer const_point_iterator; + +#ifdef PB_DS_DATA_TRUE_INDICATOR + typedef pointer point_iterator; +#else + typedef const_point_iterator point_iterator; +#endif + + typedef const_point_iterator const_iterator; + + typedef point_iterator iterator; + +#include <ext/pb_ds/detail/ov_tree_map_/cond_dtor.hpp> + + typedef + typename Node_And_It_Traits::const_node_iterator + const_node_iterator; + + typedef typename Node_And_It_Traits::node_iterator node_iterator; + + public: + + PB_DS_OV_TREE_CLASS_NAME(); + + PB_DS_OV_TREE_CLASS_NAME(const Cmp_Fn&); + + PB_DS_OV_TREE_CLASS_NAME(const Cmp_Fn&, const node_update&); + + PB_DS_OV_TREE_CLASS_NAME(const PB_DS_CLASS_C_DEC&); + + ~PB_DS_OV_TREE_CLASS_NAME(); + + void + swap(PB_DS_CLASS_C_DEC&); + + template<typename It> + void + copy_from_range(It, It); + + inline size_type + max_size() const; + + inline bool + empty() const; + + inline size_type + size() const; + + Cmp_Fn& + get_cmp_fn(); + + const Cmp_Fn& + get_cmp_fn() const; + + inline mapped_reference + operator[](const_key_reference r_key) + { +#ifdef PB_DS_DATA_TRUE_INDICATOR + _GLIBCXX_DEBUG_ONLY(assert_valid();) + point_iterator it = lower_bound(r_key); + if (it != end() && !Cmp_Fn::operator()(r_key, PB_DS_V2F(*it))) + { + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(r_key)); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return it->second; + } + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return (insert_new_val(it, std::make_pair(r_key, mapped_type()))->second); +#else + insert(r_key); + return traits_base::s_null_mapped; +#endif + } + + inline std::pair<point_iterator, bool> + insert(const_reference r_value) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + const_key_reference r_key = PB_DS_V2F(r_value); + point_iterator it = lower_bound(r_key); + + if (it != end()&& !Cmp_Fn::operator()(r_key, PB_DS_V2F(*it))) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(r_key)); + return std::make_pair(it, false); + } + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return std::make_pair(insert_new_val(it, r_value), true); + } + + inline point_iterator + lower_bound(const_key_reference r_key) + { + pointer it = m_a_values; + pointer e_it = m_a_values + m_size; + while (it != e_it) + { + pointer mid_it = it + ((e_it - it) >> 1); + if (cmp_fn_base::operator()(PB_DS_V2F(*mid_it), r_key)) + it = ++mid_it; + else + e_it = mid_it; + } + return it; + } + + inline const_point_iterator + lower_bound(const_key_reference r_key) const + { return const_cast<PB_DS_CLASS_C_DEC& >(*this).lower_bound(r_key); } + + inline point_iterator + upper_bound(const_key_reference r_key) + { + iterator pot_it = lower_bound(r_key); + if (pot_it != end()&& !Cmp_Fn::operator()(r_key, PB_DS_V2F(*pot_it))) + { + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(r_key)); + return ++pot_it; + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key)); + return pot_it; + } + + inline const_point_iterator + upper_bound(const_key_reference r_key) const + { return const_cast<PB_DS_CLASS_C_DEC&>(*this).upper_bound(r_key); } + + inline point_iterator + find(const_key_reference r_key) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + iterator pot_it = lower_bound(r_key); + if (pot_it != end() && !Cmp_Fn::operator()(r_key, PB_DS_V2F(*pot_it))) + { + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(r_key)); + return pot_it; + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key)); + return end(); + } + + inline const_point_iterator + find(const_key_reference r_key) const + { return (const_cast<PB_DS_CLASS_C_DEC& >(*this).find(r_key)); } + + bool + erase(const_key_reference); + + template<typename Pred> + inline size_type + erase_if(Pred); + + inline iterator + erase(iterator it) + { return erase_imp<iterator>(it); } + + void + clear(); + + void + join(PB_DS_CLASS_C_DEC&); + + void + split(const_key_reference, PB_DS_CLASS_C_DEC&); + + inline iterator + begin() + { return m_a_values; } + + inline const_iterator + begin() const + { return m_a_values; } + + inline iterator + end() + { return m_end_it; } + + inline const_iterator + end() const + { return m_end_it; } + + inline const_node_iterator + node_begin() const; + + inline const_node_iterator + node_end() const; + + inline node_iterator + node_begin(); + + inline node_iterator + node_end(); + + private: + + inline void + update(node_iterator /*it*/, null_node_update_pointer); + + template<typename Node_Update> + void + update(node_iterator, Node_Update*); + + void + reallocate_metadata(null_node_update_pointer, size_type); + + template<typename Node_Update_> + void + reallocate_metadata(Node_Update_*, size_type); + + template<typename It> + void + copy_from_ordered_range(It, It); + + void + value_swap(PB_DS_CLASS_C_DEC&); + + template<typename It> + void + copy_from_ordered_range(It, It, It, It); + + template<typename Ptr> + inline static Ptr + mid_pointer(Ptr p_begin, Ptr p_end) + { + _GLIBCXX_DEBUG_ASSERT(p_end >= p_begin); + return (p_begin + (p_end - p_begin) / 2); + } + + inline iterator + insert_new_val(iterator it, const_reference r_value) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) +#ifdef PB_DS_REGRESSION + typename Allocator::group_throw_prob_adjustor adjust(m_size); +#endif + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(PB_DS_V2F(r_value))); + + value_vector a_values = s_value_alloc.allocate(m_size + 1); + + iterator source_it = begin(); + iterator source_end_it = end(); + iterator target_it = a_values; + iterator ret_it; + + cond_dtor<size_type> cd(a_values, target_it, m_size + 1); + while (source_it != it) + { + new (const_cast<void* >(static_cast<const void* >(target_it))) + value_type(*source_it++); + ++target_it; + } + + new (const_cast<void* >(static_cast<const void* >(ret_it = target_it))) + value_type(r_value); + ++target_it; + + while (source_it != source_end_it) + { + new (const_cast<void* >(static_cast<const void* >(target_it))) + value_type(*source_it++); + ++target_it; + } + + reallocate_metadata((node_update* )this, m_size + 1); + cd.set_no_action(); + if (m_size != 0) + { + cond_dtor<size_type> cd1(m_a_values, m_end_it, m_size); + } + + ++m_size; + m_a_values = a_values; + m_end_it = m_a_values + m_size; + _GLIBCXX_DEBUG_ONLY(map_debug_base::insert_new(PB_DS_V2F(r_value))); + update(node_begin(), (node_update* )this); + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) + return ret_it; + } + +#ifdef _GLIBCXX_DEBUG + void + assert_valid() const; + + void + assert_iterators() const; +#endif + + template<typename It> + It + erase_imp(It it); + + inline const_node_iterator + PB_DS_node_begin_imp() const; + + inline const_node_iterator + PB_DS_node_end_imp() const; + + inline node_iterator + PB_DS_node_begin_imp(); + + inline node_iterator + PB_DS_node_end_imp(); + + private: + static value_allocator s_value_alloc; + static metadata_allocator s_metadata_alloc; + + value_vector m_a_values; + metadata_pointer m_a_metadata; + iterator m_end_it; + size_type m_size; + }; + +#include <ext/pb_ds/detail/ov_tree_map_/constructors_destructor_fn_imps.hpp> +#include <ext/pb_ds/detail/ov_tree_map_/iterators_fn_imps.hpp> +#include <ext/pb_ds/detail/ov_tree_map_/debug_fn_imps.hpp> +#include <ext/pb_ds/detail/ov_tree_map_/erase_fn_imps.hpp> +#include <ext/pb_ds/detail/ov_tree_map_/insert_fn_imps.hpp> +#include <ext/pb_ds/detail/ov_tree_map_/info_fn_imps.hpp> +#include <ext/pb_ds/detail/ov_tree_map_/split_join_fn_imps.hpp> +#include <ext/pb_ds/detail/bin_search_tree_/policy_access_fn_imps.hpp> + +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_OV_TREE_CLASS_NAME +#undef PB_DS_TYPES_TRAITS_C_DEC +#undef PB_DS_MAP_DEBUG_BASE_C_DEC +#ifdef PB_DS_TREE_TRACE +#undef PB_DS_TREE_TRACE_BASE_C_DEC +#endif + +#undef PB_DS_V2F +#undef PB_DS_EP2VP +#undef PB_DS_V2S +#undef PB_DS_CONST_NODE_ITERATOR_NAME + + } // namespace detail +} // namespace pb_ds diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/policy_access_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/policy_access_fn_imps.hpp new file mode 100644 index 000000000000..8ed19f1ef20e --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/policy_access_fn_imps.hpp @@ -0,0 +1,57 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file policy_access_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +Cmp_Fn& +PB_DS_CLASS_C_DEC:: +get_cmp_fn() +{ return *this; } + +PB_DS_CLASS_T_DEC +const Cmp_Fn& +PB_DS_CLASS_C_DEC:: +get_cmp_fn() const +{ return *this; } diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/split_join_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/split_join_fn_imps.hpp new file mode 100644 index 000000000000..3b6abcd6c773 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/split_join_fn_imps.hpp @@ -0,0 +1,143 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file split_join_fn_imps.hpp + * Contains an implementation class for ov_tree_. + */ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +split(const_key_reference r_key, PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + + if (m_size == 0) + { + other.clear(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + return; + } + + if (Cmp_Fn::operator()(r_key, PB_DS_V2F(*begin()))) + { + value_swap(other); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + return; + } + + if (!Cmp_Fn::operator()(r_key, PB_DS_V2F(*(end() - 1)))) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + return; + } + + if (m_size == 1) + { + value_swap(other); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + return; + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::join(other);) + iterator it = upper_bound(r_key); + PB_DS_CLASS_C_DEC new_other(other, other); + new_other.copy_from_ordered_range(it, end()); + PB_DS_CLASS_C_DEC new_this(*this, * this); + new_this.copy_from_ordered_range(begin(), it); + + // No exceptions from this point. + _GLIBCXX_DEBUG_ONLY(map_debug_base::split(r_key,(Cmp_Fn& )(*this), other);) + other.update(other.node_begin(), (node_update* )(&other)); + update(node_begin(), (node_update* )this); + other.value_swap(new_other); + value_swap(new_this); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +join(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + if (other.m_size == 0) + return; + + if (m_size == 0) + { + value_swap(other); + return; + } + + const bool greater = Cmp_Fn::operator()(PB_DS_V2F(*(end() - 1)), + PB_DS_V2F(*other.begin())); + + const bool lesser = Cmp_Fn::operator()(PB_DS_V2F(*(other.end() - 1)), + PB_DS_V2F(*begin())); + + if (!greater && !lesser) + __throw_join_error(); + + PB_DS_CLASS_C_DEC new_this(*this, *this); + + if (greater) + new_this.copy_from_ordered_range(begin(), end(), + other.begin(), other.end()); + else + new_this.copy_from_ordered_range(other.begin(), other.end(), + begin(), end()); + + // No exceptions from this point. + _GLIBCXX_DEBUG_ONLY(map_debug_base::join(other);) + value_swap(new_this); + other.clear(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) +} diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/traits.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/traits.hpp new file mode 100644 index 000000000000..182c0c8d3930 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/ov_tree_map_/traits.hpp @@ -0,0 +1,189 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file traits.hpp + * Contains an implementation class for ov_tree_. + */ + +#ifndef PB_DS_OV_TREE_NODE_AND_IT_TRAITS_HPP +#define PB_DS_OV_TREE_NODE_AND_IT_TRAITS_HPP + +#include <ext/pb_ds/detail/ov_tree_map_/node_iterators.hpp> + +namespace pb_ds +{ + namespace detail + { + + template<typename Key, + typename Mapped, + class Cmp_Fn, + template<typename Const_Node_Iterator, + class Node_Iterator, + class Cmp_Fn_, + class Allocator_> + class Node_Update, + class Allocator> + struct tree_traits< + Key, + Mapped, + Cmp_Fn, + Node_Update, + ov_tree_tag, + Allocator> + { + private: + typedef + typename types_traits< + Key, + Mapped, + Allocator, + false>::value_type + value_type; + + public: + typedef + typename tree_node_metadata_selector< + Key, + Mapped, + Cmp_Fn, + Node_Update, + Allocator>::type + metadata_type; + + typedef + ov_tree_node_const_it_< + value_type, + metadata_type, + Allocator> + const_node_iterator; + + typedef + ov_tree_node_it_< + value_type, + metadata_type, + Allocator> + node_iterator; + + typedef + Node_Update< + const_node_iterator, + node_iterator, + Cmp_Fn, + Allocator> + node_update; + + typedef + pb_ds::null_tree_node_update< + const_node_iterator, + node_iterator, + Cmp_Fn, + Allocator>* + null_node_update_pointer; + }; + + template<typename Key, + class Cmp_Fn, + template<typename Const_Node_Iterator, + class Node_Iterator, + class Cmp_Fn_, + class Allocator_> + class Node_Update, + class Allocator> + struct tree_traits< + Key, + null_mapped_type, + Cmp_Fn, + Node_Update, + ov_tree_tag, + Allocator> + { + private: + typedef + typename types_traits< + Key, + null_mapped_type, + Allocator, + false>::value_type + value_type; + + public: + typedef + typename tree_node_metadata_selector< + Key, + null_mapped_type, + Cmp_Fn, + Node_Update, + Allocator>::type + metadata_type; + + typedef + ov_tree_node_const_it_< + value_type, + metadata_type, + Allocator> + const_node_iterator; + + typedef const_node_iterator node_iterator; + + typedef + Node_Update< + const_node_iterator, + const_node_iterator, + Cmp_Fn, + Allocator> + node_update; + + typedef + pb_ds::null_tree_node_update< + const_node_iterator, + node_iterator, + Cmp_Fn, + Allocator>* + null_node_update_pointer; + }; + + } // namespace detail +} // namespace pb_ds + +#endif // #ifndef PB_DS_OV_TREE_NODE_AND_IT_TRAITS_HPP + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/pairing_heap_/constructors_destructor_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/pairing_heap_/constructors_destructor_fn_imps.hpp new file mode 100644 index 000000000000..6534f208604c --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/pairing_heap_/constructors_destructor_fn_imps.hpp @@ -0,0 +1,97 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructors_destructor_fn_imps.hpp + * Contains an implementation class for a pairing heap. + */ + +PB_DS_CLASS_T_DEC +template<typename It> +void +PB_DS_CLASS_C_DEC:: +copy_from_range(It first_it, It last_it) +{ + while (first_it != last_it) + push(*(first_it++)); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +pairing_heap_() +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +pairing_heap_(const Cmp_Fn& r_cmp_fn) : + PB_DS_BASE_C_DEC(r_cmp_fn) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +pairing_heap_(const PB_DS_CLASS_C_DEC& other) : + PB_DS_BASE_C_DEC(other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + PB_DS_BASE_C_DEC::swap(other); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +~pairing_heap_() +{ } diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/pairing_heap_/debug_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/pairing_heap_/debug_fn_imps.hpp new file mode 100644 index 000000000000..5e6bb373968b --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/pairing_heap_/debug_fn_imps.hpp @@ -0,0 +1,59 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_fn_imps.hpp + * Contains an implementation class for a pairing heap. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_valid() const +{ + _GLIBCXX_DEBUG_ASSERT(base_type::m_p_root == NULL + || base_type::m_p_root->m_p_next_sibling == NULL); + base_type::assert_valid(); +} + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/pairing_heap_/erase_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/pairing_heap_/erase_fn_imps.hpp new file mode 100644 index 000000000000..038b490b46c1 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/pairing_heap_/erase_fn_imps.hpp @@ -0,0 +1,242 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file erase_fn_imps.hpp + * Contains an implementation class for a pairing heap. + */ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +pop() +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); + + node_pointer p_new_root = join_node_children(base_type::m_p_root); + _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_new_root, false);) + if (p_new_root != NULL) + p_new_root->m_p_prev_or_parent = NULL; + + base_type::actual_erase_node(base_type::m_p_root); + base_type::m_p_root = p_new_root; + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +erase(point_iterator it) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); + remove_node(it.m_p_nd); + base_type::actual_erase_node(it.m_p_nd); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +remove_node(node_pointer p_nd) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); + node_pointer p_new_child = join_node_children(p_nd); + +#ifdef _GLIBCXX_DEBUG + if (p_new_child != NULL) + base_type::assert_node_consistent(p_new_child, false); +#endif + + if (p_nd == base_type::m_p_root) + { + if (p_new_child != NULL) + p_new_child->m_p_prev_or_parent = NULL; + base_type::m_p_root = p_new_child; + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(base_type::m_p_root, false);) + return; + } + + _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_prev_or_parent != NULL); + if (p_nd->m_p_prev_or_parent->m_p_l_child == p_nd) + { + if (p_new_child != NULL) + { + p_new_child->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; + p_new_child->m_p_next_sibling = p_nd->m_p_next_sibling; + if (p_new_child->m_p_next_sibling != NULL) + p_new_child->m_p_next_sibling->m_p_prev_or_parent = p_new_child; + p_nd->m_p_prev_or_parent->m_p_l_child = p_new_child; + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_nd->m_p_prev_or_parent, false);) + return; + } + + p_nd->m_p_prev_or_parent->m_p_l_child = p_nd->m_p_next_sibling; + if (p_nd->m_p_next_sibling != NULL) + p_nd->m_p_next_sibling->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_nd->m_p_prev_or_parent, false);) + return; + } + + if (p_new_child != NULL) + { + p_new_child->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; + p_new_child->m_p_next_sibling = p_nd->m_p_next_sibling; + if (p_new_child->m_p_next_sibling != NULL) + p_new_child->m_p_next_sibling->m_p_prev_or_parent = p_new_child; + p_new_child->m_p_prev_or_parent->m_p_next_sibling = p_new_child; + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_nd->m_p_prev_or_parent, false);) + return; + } + + p_nd->m_p_prev_or_parent->m_p_next_sibling = p_nd->m_p_next_sibling; + if (p_nd->m_p_next_sibling != NULL) + p_nd->m_p_next_sibling->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_nd->m_p_prev_or_parent, false);) +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +join_node_children(node_pointer p_nd) +{ + _GLIBCXX_DEBUG_ASSERT(p_nd != NULL); + node_pointer p_ret = p_nd->m_p_l_child; + if (p_ret == NULL) + return NULL; + while (p_ret->m_p_next_sibling != NULL) + p_ret = forward_join(p_ret, p_ret->m_p_next_sibling); + while (p_ret->m_p_prev_or_parent != p_nd) + p_ret = back_join(p_ret->m_p_prev_or_parent, p_ret); + _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_ret, false);) + return p_ret; +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +forward_join(node_pointer p_nd, node_pointer p_next) +{ + _GLIBCXX_DEBUG_ASSERT(p_nd != NULL); + _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_next_sibling == p_next); + if (Cmp_Fn::operator()(p_nd->m_value, p_next->m_value)) + { + p_next->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; + base_type::make_child_of(p_nd, p_next); + return p_next->m_p_next_sibling == NULL + ? p_next : p_next->m_p_next_sibling; + } + + if (p_next->m_p_next_sibling != NULL) + { + p_next->m_p_next_sibling->m_p_prev_or_parent = p_nd; + p_nd->m_p_next_sibling = p_next->m_p_next_sibling; + base_type::make_child_of(p_next, p_nd); + return p_nd->m_p_next_sibling; + } + + p_nd->m_p_next_sibling = NULL; + base_type::make_child_of(p_next, p_nd); + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_nd, false)); + return p_nd; +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +back_join(node_pointer p_nd, node_pointer p_next) +{ + _GLIBCXX_DEBUG_ASSERT(p_nd != NULL); + _GLIBCXX_DEBUG_ASSERT(p_next->m_p_next_sibling == NULL); + + if (Cmp_Fn::operator()(p_nd->m_value, p_next->m_value)) + { + p_next->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; + base_type::make_child_of(p_nd, p_next); + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_next, false)); + return p_next; + } + + p_nd->m_p_next_sibling = NULL; + base_type::make_child_of(p_next, p_nd); + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_nd, false)); + return p_nd; +} + +PB_DS_CLASS_T_DEC +template<typename Pred> +typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +erase_if(Pred pred) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + if (base_type::empty()) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return 0; + } + base_type::to_linked_list(); + node_pointer p_out = base_type::prune(pred); + size_type ersd = 0; + while (p_out != NULL) + { + ++ersd; + node_pointer p_next = p_out->m_p_next_sibling; + base_type::actual_erase_node(p_out); + p_out = p_next; + } + + node_pointer p_cur = base_type::m_p_root; + base_type::m_p_root = NULL; + while (p_cur != NULL) + { + node_pointer p_next = p_cur->m_p_next_sibling; + p_cur->m_p_l_child = p_cur->m_p_next_sibling = p_cur->m_p_prev_or_parent = NULL; + + push_imp(p_cur); + p_cur = p_next; + } + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return ersd; +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/pairing_heap_/find_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/pairing_heap_/find_fn_imps.hpp new file mode 100644 index 000000000000..f74b0bbbf3c9 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/pairing_heap_/find_fn_imps.hpp @@ -0,0 +1,56 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file find_fn_imps.hpp + * Contains an implementation class for a pairing heap. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_reference +PB_DS_CLASS_C_DEC:: +top() const +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); + + return base_type::m_p_root->m_value; +} diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/pairing_heap_/insert_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/pairing_heap_/insert_fn_imps.hpp new file mode 100644 index 000000000000..41ff3918b85b --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/pairing_heap_/insert_fn_imps.hpp @@ -0,0 +1,107 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file insert_fn_imps.hpp + * Contains an implementation class for a pairing heap. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::point_iterator +PB_DS_CLASS_C_DEC:: +push(const_reference r_val) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + node_pointer p_new_nd = base_type::get_new_node_for_insert(r_val); + + push_imp(p_new_nd); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + return point_iterator(p_new_nd); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +push_imp(node_pointer p_nd) +{ + p_nd->m_p_l_child = NULL; + + if (base_type::m_p_root == NULL) + { + p_nd->m_p_next_sibling = p_nd->m_p_prev_or_parent = NULL; + + base_type::m_p_root = p_nd; + } + else if (Cmp_Fn::operator()(base_type::m_p_root->m_value, p_nd->m_value)) + { + p_nd->m_p_next_sibling = p_nd->m_p_prev_or_parent = NULL; + + base_type::make_child_of(base_type::m_p_root, p_nd); + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_nd, false)); + + base_type::m_p_root = p_nd; + } + else + { + base_type::make_child_of(p_nd, base_type::m_p_root); + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(base_type::m_p_root, false)); + } +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +modify(point_iterator it, const_reference r_new_val) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + remove_node(it.m_p_nd); + + it.m_p_nd->m_value = r_new_val; + + push_imp(it.m_p_nd); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/pairing_heap_/pairing_heap_.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/pairing_heap_/pairing_heap_.hpp new file mode 100644 index 000000000000..647547497964 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/pairing_heap_/pairing_heap_.hpp @@ -0,0 +1,222 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file pairing_heap_.hpp + * Contains an implementation class for a pairing heap. + */ + +/* + * Pairing heap: + * Michael L. Fredman, Robert Sedgewick, Daniel Dominic Sleator, + * and Robert Endre Tarjan, The Pairing Heap: + * A New Form of Self-Adjusting Heap, Algorithmica, 1(1):111-129, 1986. + */ + +#include <ext/pb_ds/detail/cond_dealtor.hpp> +#include <ext/pb_ds/detail/type_utils.hpp> +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/left_child_next_sibling_heap_.hpp> +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/null_metadata.hpp> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_CLASS_T_DEC \ + template<typename Value_Type, class Cmp_Fn, class Allocator> + +#define PB_DS_CLASS_C_DEC \ + pairing_heap_<Value_Type, Cmp_Fn, Allocator> + +#ifdef _GLIBCXX_DEBUG +#define PB_DS_BASE_C_DEC \ + left_child_next_sibling_heap_< \ + Value_Type, \ + Cmp_Fn, \ + null_left_child_next_sibling_heap_node_metadata, \ + Allocator, \ + false> +#else +#define PB_DS_BASE_C_DEC \ + left_child_next_sibling_heap_< \ + Value_Type, \ + Cmp_Fn, \ + null_left_child_next_sibling_heap_node_metadata, \ + Allocator> +#endif + + /** + * class description = "P4ri|\|g h3ap$"> + **/ + template<typename Value_Type, class Cmp_Fn, class Allocator> + class pairing_heap_ : public PB_DS_BASE_C_DEC + { + + private: + typedef PB_DS_BASE_C_DEC base_type; + + typedef typename base_type::node_pointer node_pointer; + + public: + + typedef typename Allocator::size_type size_type; + + typedef typename Allocator::difference_type difference_type; + + typedef Value_Type value_type; + + typedef + typename Allocator::template rebind< + value_type>::other::pointer + pointer; + + typedef + typename Allocator::template rebind< + value_type>::other::const_pointer + const_pointer; + + typedef + typename Allocator::template rebind< + value_type>::other::reference + reference; + + typedef + typename Allocator::template rebind< + value_type>::other::const_reference + const_reference; + + typedef + typename PB_DS_BASE_C_DEC::const_point_iterator + const_point_iterator; + + typedef typename PB_DS_BASE_C_DEC::point_iterator point_iterator; + + typedef typename PB_DS_BASE_C_DEC::const_iterator const_iterator; + + typedef typename PB_DS_BASE_C_DEC::iterator iterator; + + typedef Cmp_Fn cmp_fn; + + typedef Allocator allocator; + + + pairing_heap_(); + + pairing_heap_(const Cmp_Fn& r_cmp_fn); + + pairing_heap_(const PB_DS_CLASS_C_DEC& other); + + void + swap(PB_DS_CLASS_C_DEC& other); + + ~pairing_heap_(); + + inline point_iterator + push(const_reference r_val); + + void + modify(point_iterator it, const_reference r_new_val); + + inline const_reference + top() const; + + void + pop(); + + void + erase(point_iterator it); + + template<typename Pred> + size_type + erase_if(Pred pred); + + template<typename Pred> + void + split(Pred pred, PB_DS_CLASS_C_DEC& other); + + void + join(PB_DS_CLASS_C_DEC& other); + + protected: + + template<typename It> + void + copy_from_range(It first_it, It last_it); + +#ifdef _GLIBCXX_DEBUG + void + assert_valid() const; +#endif + + private: + + inline void + push_imp(node_pointer p_nd); + + node_pointer + join_node_children(node_pointer p_nd); + + node_pointer + forward_join(node_pointer p_nd, node_pointer p_next); + + node_pointer + back_join(node_pointer p_nd, node_pointer p_next); + + void + remove_node(node_pointer p_nd); + + }; + +#include <ext/pb_ds/detail/pairing_heap_/constructors_destructor_fn_imps.hpp> +#include <ext/pb_ds/detail/pairing_heap_/debug_fn_imps.hpp> +#include <ext/pb_ds/detail/pairing_heap_/find_fn_imps.hpp> +#include <ext/pb_ds/detail/pairing_heap_/insert_fn_imps.hpp> +#include <ext/pb_ds/detail/pairing_heap_/erase_fn_imps.hpp> +#include <ext/pb_ds/detail/pairing_heap_/split_join_fn_imps.hpp> + +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_BASE_C_DEC + + } // namespace detail +} // namespace pb_ds diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/pairing_heap_/split_join_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/pairing_heap_/split_join_fn_imps.hpp new file mode 100644 index 000000000000..29b802500acf --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/pairing_heap_/split_join_fn_imps.hpp @@ -0,0 +1,146 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file split_join_fn_imps.hpp + * Contains an implementation class for a pairing heap. + */ + +PB_DS_CLASS_T_DEC +template<typename Pred> +void +PB_DS_CLASS_C_DEC:: +split(Pred pred, PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + + other.clear(); + + if (base_type::empty()) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + + return; + } + + base_type::to_linked_list(); + + node_pointer p_out = base_type::prune(pred); + + while (p_out != NULL) + { + _GLIBCXX_DEBUG_ASSERT(base_type::m_size > 0); + --base_type::m_size; + + ++other.m_size; + + node_pointer p_next = p_out->m_p_next_sibling; + + p_out->m_p_l_child = p_out->m_p_next_sibling = p_out->m_p_prev_or_parent = NULL; + + other.push_imp(p_out); + + p_out = p_next; + } + + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + + node_pointer p_cur = base_type::m_p_root; + + base_type::m_p_root = NULL; + + while (p_cur != NULL) + { + node_pointer p_next = p_cur->m_p_next_sibling; + + p_cur->m_p_l_child = p_cur->m_p_next_sibling = p_cur->m_p_prev_or_parent = NULL; + + push_imp(p_cur); + + p_cur = p_next; + } + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +join(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + + if (other.m_p_root == NULL) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + + return; + } + + if (base_type::m_p_root == NULL) + base_type::m_p_root = other.m_p_root; + else if (Cmp_Fn::operator()(base_type::m_p_root->m_value, other.m_p_root->m_value)) + { + base_type::make_child_of(base_type::m_p_root, other.m_p_root); + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(other.m_p_root, false)); + + base_type::m_p_root = other.m_p_root; + } + else + { + base_type::make_child_of(other.m_p_root, base_type::m_p_root); + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(base_type::m_p_root, false)); + } + + base_type::m_size += other.m_size; + + other.m_p_root = NULL; + other.m_size = 0; + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + } + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/child_iterator.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/child_iterator.hpp new file mode 100644 index 000000000000..82c3fbd3aa67 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/child_iterator.hpp @@ -0,0 +1,99 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file child_iterator.hpp + * Contains a iterator for a patricia tree. + */ + +struct iterator : public const_iterator +{ +public: + typedef std::forward_iterator_tag iterator_category; + typedef typename Allocator::difference_type difference_type; + typedef node_pointer value_type; + typedef node_pointer_pointer pointer; + typedef node_pointer_reference reference; + + inline + iterator(node_pointer_pointer p_p_cur = NULL, + node_pointer_pointer p_p_end = NULL) + : const_iterator(p_p_cur, p_p_end) + { } + + inline bool + operator==(const iterator& other) const + { return const_iterator::m_p_p_cur == other.m_p_p_cur; } + + inline bool + operator!=(const iterator& other) const + { return const_iterator::m_p_p_cur != other.m_p_p_cur; } + + inline iterator& + operator++() + { + const_iterator::operator++(); + return *this; + } + + inline iterator + operator++(int) + { + iterator ret_it(*this); + operator++(); + return ret_it; + } + + node_pointer_pointer + operator->() + { + _GLIBCXX_DEBUG_ONLY(const_iterator::assert_referencible();) + return const_iterator::m_p_p_cur; + } + + node_pointer + operator*() + { + _GLIBCXX_DEBUG_ONLY(const_iterator::assert_referencible();) + return *const_iterator::m_p_p_cur; + } +}; + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/cond_dtor_entry_dealtor.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/cond_dtor_entry_dealtor.hpp new file mode 100644 index 000000000000..64c16b1d2aa2 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/cond_dtor_entry_dealtor.hpp @@ -0,0 +1,85 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file cond_dtor_entry_dealtor.hpp + * Contains a binary tree container conditional deallocator + */ + +class cond_dealtor +{ +public: + inline + cond_dealtor(leaf_pointer p_nd) : m_p_nd(p_nd), + m_no_action_dtor(false), + m_call_destructor(false) + { } + + inline void + set_no_action_dtor() + { + m_no_action_dtor = true; + } + + inline void + set_call_destructor() + { + m_call_destructor = true; + } + + inline + ~cond_dealtor() + { + if (m_no_action_dtor) + return; + + if (m_call_destructor) + m_p_nd->~leaf(); + + s_leaf_allocator.deallocate(m_p_nd, 1); + } + +protected: + leaf_pointer m_p_nd; + bool m_no_action_dtor; + bool m_call_destructor; +}; + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/const_child_iterator.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/const_child_iterator.hpp new file mode 100644 index 000000000000..cd3837558962 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/const_child_iterator.hpp @@ -0,0 +1,117 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file const_child_iterator.hpp + * Contains a const_iterator for a patricia tree. + */ + +struct const_iterator +{ +public: + typedef std::forward_iterator_tag iterator_category; + + typedef typename Allocator::difference_type difference_type; + + typedef node_pointer value_type; + + typedef node_pointer_pointer pointer; + + typedef node_pointer_reference reference; + +public: + inline + const_iterator(node_pointer_pointer p_p_cur = NULL, + node_pointer_pointer p_p_end = NULL) + : m_p_p_cur(p_p_cur), m_p_p_end(p_p_end) + { } + + inline bool + operator==(const const_iterator& other) const + { return m_p_p_cur == other.m_p_p_cur; } + + inline bool + operator!=(const const_iterator& other) const + { return m_p_p_cur != other.m_p_p_cur; } + + inline const_iterator& + operator++() + { + do + ++m_p_p_cur; + while (m_p_p_cur != m_p_p_end&& * m_p_p_cur == NULL); + return *this; + } + + inline const_iterator + operator++(int) + { + const_iterator ret_it(*this); + operator++(); + return ret_it; + } + + const node_pointer_pointer + operator->() const + { + _GLIBCXX_DEBUG_ONLY(assert_referencible();) + return (m_p_p_cur); + } + + const_node_pointer + operator*() const + { + _GLIBCXX_DEBUG_ONLY(assert_referencible();) + return (*m_p_p_cur); + } + +protected: +#ifdef _GLIBCXX_DEBUG + void + assert_referencible() const + { _GLIBCXX_DEBUG_ASSERT(m_p_p_cur != m_p_p_end&& * m_p_p_cur != NULL); } +#endif + +public: + node_pointer_pointer m_p_p_cur; + node_pointer_pointer m_p_p_end; +}; + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/constructors_destructor_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/constructors_destructor_fn_imps.hpp new file mode 100644 index 000000000000..a5a96a5a3893 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/constructors_destructor_fn_imps.hpp @@ -0,0 +1,220 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructors_destructor_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::head_allocator +PB_DS_CLASS_C_DEC::s_head_allocator; + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::internal_node_allocator +PB_DS_CLASS_C_DEC::s_internal_node_allocator; + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::leaf_allocator +PB_DS_CLASS_C_DEC::s_leaf_allocator; + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME() : + m_p_head(s_head_allocator.allocate(1)), + m_size(0) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const e_access_traits& r_e_access_traits) : + synth_e_access_traits(r_e_access_traits), + m_p_head(s_head_allocator.allocate(1)), + m_size(0) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const PB_DS_CLASS_C_DEC& other) : +#ifdef _GLIBCXX_DEBUG + map_debug_base(other), +#endif + synth_e_access_traits(other), + node_update(other), + m_p_head(s_head_allocator.allocate(1)), + m_size(0) +{ + initialize(); + m_size = other.m_size; + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + if (other.m_p_head->m_p_parent == NULL) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return; + } + try + { + m_p_head->m_p_parent = recursive_copy_node(other.m_p_head->m_p_parent); + } + catch(...) + { + s_head_allocator.deallocate(m_p_head, 1); + __throw_exception_again; + } + + m_p_head->m_p_min = leftmost_descendant(m_p_head->m_p_parent); + m_p_head->m_p_max = rightmost_descendant(m_p_head->m_p_parent); + m_p_head->m_p_parent->m_p_parent = m_p_head; + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + value_swap(other); + std::swap((e_access_traits& )(*this), (e_access_traits& )other); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +value_swap(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(map_debug_base::swap(other);) + std::swap(m_p_head, other.m_p_head); + std::swap(m_size, other.m_size); +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +~PB_DS_CLASS_NAME() +{ + clear(); + s_head_allocator.deallocate(m_p_head, 1); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +initialize() +{ + new (m_p_head) head(); + m_p_head->m_p_parent = NULL; + m_p_head->m_p_min = m_p_head; + m_p_head->m_p_max = m_p_head; + m_size = 0; +} + +PB_DS_CLASS_T_DEC +template<typename It> +void +PB_DS_CLASS_C_DEC:: +copy_from_range(It first_it, It last_it) +{ + while (first_it != last_it) + insert(*(first_it++)); +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +recursive_copy_node(const_node_pointer p_other_nd) +{ + _GLIBCXX_DEBUG_ASSERT(p_other_nd != NULL); + if (p_other_nd->m_type == pat_trie_leaf_node_type) + { + const_leaf_pointer p_other_leaf = static_cast<const_leaf_pointer>(p_other_nd); + + leaf_pointer p_new_lf = s_leaf_allocator.allocate(1); + cond_dealtor cond(p_new_lf); + new (p_new_lf) leaf(p_other_leaf->value()); + apply_update(p_new_lf, (node_update* )this); + cond.set_no_action_dtor(); + return (p_new_lf); + } + + _GLIBCXX_DEBUG_ASSERT(p_other_nd->m_type == pat_trie_internal_node_type); + node_pointer a_p_children[internal_node::arr_size]; + size_type child_i = 0; + const_internal_node_pointer p_other_internal_nd = + static_cast<const_internal_node_pointer>(p_other_nd); + + typename internal_node::const_iterator child_it = + p_other_internal_nd->begin(); + + internal_node_pointer p_ret; + try + { + while (child_it != p_other_internal_nd->end()) + a_p_children[child_i++] = recursive_copy_node(*(child_it++)); + p_ret = s_internal_node_allocator.allocate(1); + } + catch(...) + { + while (child_i-- > 0) + clear_imp(a_p_children[child_i]); + __throw_exception_again; + } + + new (p_ret) internal_node(p_other_internal_nd->get_e_ind(), + pref_begin(a_p_children[0])); + + --child_i; + _GLIBCXX_DEBUG_ASSERT(child_i > 1); + do + p_ret->add_child(a_p_children[child_i], pref_begin(a_p_children[child_i]), + pref_end(a_p_children[child_i]), this); + while (child_i-- > 0); + apply_update(p_ret, (node_update* )this); + return p_ret; +} diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/debug_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/debug_fn_imps.hpp new file mode 100644 index 000000000000..a2253a6a5027 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/debug_fn_imps.hpp @@ -0,0 +1,123 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_fn_imps.hpp + * Contains an implementation class for pat_trie_. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_valid() const +{ + if (m_p_head->m_p_parent != NULL) + m_p_head->m_p_parent->assert_valid(this); + assert_iterators(); + assert_reverse_iterators(); + if (m_p_head->m_p_parent == NULL) + { + _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_min == m_p_head); + _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_max == m_p_head); + _GLIBCXX_DEBUG_ASSERT(empty()); + return; + } + + _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_min->m_type == pat_trie_leaf_node_type); + _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_max->m_type == pat_trie_leaf_node_type); + _GLIBCXX_DEBUG_ASSERT(!empty()); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_iterators() const +{ + size_type calc_size = 0; + for (const_iterator it = begin(); it != end(); ++it) + { + ++calc_size; + map_debug_base::check_key_exists(PB_DS_V2F(*it)); + _GLIBCXX_DEBUG_ASSERT(lower_bound(PB_DS_V2F(*it)) == it); + _GLIBCXX_DEBUG_ASSERT(--upper_bound(PB_DS_V2F(*it)) == it); + } + _GLIBCXX_DEBUG_ASSERT(calc_size == m_size); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_reverse_iterators() const +{ + size_type calc_size = 0; + for (const_reverse_iterator it = rbegin(); it != rend(); ++it) + { + ++calc_size; + const_node_pointer p_nd = + const_cast<PB_DS_CLASS_C_DEC* >(this)->find_imp(PB_DS_V2F(*it)); + _GLIBCXX_DEBUG_ASSERT(p_nd == it.m_p_nd); + } + _GLIBCXX_DEBUG_ASSERT(calc_size == m_size); +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +recursive_count_leafs(const_node_pointer p_nd) +{ + if (p_nd == NULL) + return (0); + if (p_nd->m_type == pat_trie_leaf_node_type) + return (1); + _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == pat_trie_internal_node_type); + size_type ret = 0; + for (typename internal_node::const_iterator it = + static_cast<const_internal_node_pointer>(p_nd)->begin(); + it != static_cast<const_internal_node_pointer>(p_nd)->end(); + ++it) + ret += recursive_count_leafs(*it); + return ret; +} + +#endif + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/erase_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/erase_fn_imps.hpp new file mode 100644 index 000000000000..0fba3a4e2859 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/erase_fn_imps.hpp @@ -0,0 +1,325 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file erase_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +erase(const_key_reference r_key) +{ + node_pointer p_nd = find_imp(r_key); + if (p_nd == NULL || p_nd->m_type == pat_trie_internal_node_type) + { + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key)); + return false; + } + + _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == pat_trie_leaf_node_type); + if (!synth_e_access_traits::equal_keys(PB_DS_V2F(reinterpret_cast<leaf_pointer>(p_nd)->value()), r_key)) + { + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key)); + return false; + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(r_key)); + erase_leaf(static_cast<leaf_pointer>(p_nd)); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return true; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +erase_fixup(internal_node_pointer p_nd) +{ + _GLIBCXX_DEBUG_ASSERT(std::distance(p_nd->begin(), p_nd->end()) >= 1); + if (std::distance(p_nd->begin(), p_nd->end()) == 1) + { + node_pointer p_parent = p_nd->m_p_parent; + if (p_parent == m_p_head) + m_p_head->m_p_parent =* p_nd->begin(); + else + { + _GLIBCXX_DEBUG_ASSERT(p_parent->m_type == pat_trie_internal_node_type); + node_pointer p_new_child =* p_nd->begin(); + static_cast<internal_node_pointer>(p_parent)->replace_child( + p_new_child, + pref_begin(p_new_child), + pref_end(p_new_child), + this); + } + (*p_nd->begin())->m_p_parent = p_nd->m_p_parent; + p_nd->~internal_node(); + s_internal_node_allocator.deallocate(p_nd, 1); + + if (p_parent == m_p_head) + return; + + _GLIBCXX_DEBUG_ASSERT(p_parent->m_type == pat_trie_internal_node_type); + p_nd = static_cast<internal_node_pointer>(p_parent); + } + + while (true) + { + _GLIBCXX_DEBUG_ASSERT(std::distance(p_nd->begin(), p_nd->end()) > 1); + p_nd->update_prefixes(this); + apply_update(p_nd, (node_update* )this); + _GLIBCXX_DEBUG_ONLY(p_nd->assert_valid(this);) + if (p_nd->m_p_parent->m_type == pat_trie_head_node_type) + return; + + _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_parent->m_type == + pat_trie_internal_node_type); + + p_nd = static_cast<internal_node_pointer>(p_nd->m_p_parent); + } +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +actual_erase_leaf(leaf_pointer p_l) +{ + _GLIBCXX_DEBUG_ASSERT(m_size > 0); + --m_size; + _GLIBCXX_DEBUG_ONLY(erase_existing(PB_DS_V2F(p_l->value()))); + p_l->~leaf(); + s_leaf_allocator.deallocate(p_l, 1); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +clear() +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + if (empty()) + return; + + clear_imp(m_p_head->m_p_parent); + m_size = 0; + initialize(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::clear();) + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +clear_imp(node_pointer p_nd) +{ + if (p_nd->m_type == pat_trie_internal_node_type) + { + _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == pat_trie_internal_node_type); + for (typename internal_node::iterator it = + static_cast<internal_node_pointer>(p_nd)->begin(); + it != static_cast<internal_node_pointer>(p_nd)->end(); + ++it) + { + node_pointer p_child =* it; + clear_imp(p_child); + } + s_internal_node_allocator.deallocate(static_cast<internal_node_pointer>(p_nd), 1); + return; + } + + _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == pat_trie_leaf_node_type); + static_cast<leaf_pointer>(p_nd)->~leaf(); + s_leaf_allocator.deallocate(static_cast<leaf_pointer>(p_nd), 1); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +erase(const_iterator it) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid()); + + if (it == end()) + return it; + + const_iterator ret_it = it; + ++ret_it; + _GLIBCXX_DEBUG_ASSERT(it.m_p_nd->m_type == pat_trie_leaf_node_type); + erase_leaf(static_cast<leaf_pointer>(it.m_p_nd)); + _GLIBCXX_DEBUG_ONLY(assert_valid()); + return ret_it; +} + +#ifdef PB_DS_DATA_TRUE_INDICATOR +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +erase(iterator it) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid()); + + if (it == end()) + return it; + iterator ret_it = it; + ++ret_it; + _GLIBCXX_DEBUG_ASSERT(it.m_p_nd->m_type == pat_trie_leaf_node_type); + erase_leaf(static_cast<leaf_pointer>(it.m_p_nd)); + _GLIBCXX_DEBUG_ONLY(assert_valid()); + return ret_it; +} +#endif // #ifdef PB_DS_DATA_TRUE_INDICATOR + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_reverse_iterator +PB_DS_CLASS_C_DEC:: +erase(const_reverse_iterator it) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid()); + + if (it.m_p_nd == m_p_head) + return it; + const_reverse_iterator ret_it = it; + ++ret_it; + + _GLIBCXX_DEBUG_ASSERT(it.m_p_nd->m_type == pat_trie_leaf_node_type); + erase_leaf(static_cast<leaf_pointer>(it.m_p_nd)); + _GLIBCXX_DEBUG_ONLY(assert_valid()); + return ret_it; +} + +#ifdef PB_DS_DATA_TRUE_INDICATOR +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::reverse_iterator +PB_DS_CLASS_C_DEC:: +erase(reverse_iterator it) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid()); + + if (it.m_p_nd == m_p_head) + return it; + reverse_iterator ret_it = it; + ++ret_it; + + _GLIBCXX_DEBUG_ASSERT(it.m_p_nd->m_type == pat_trie_leaf_node_type); + erase_leaf(static_cast<leaf_pointer>(it.m_p_nd)); + _GLIBCXX_DEBUG_ONLY(assert_valid()); + return ret_it; +} +#endif // #ifdef PB_DS_DATA_TRUE_INDICATOR + +PB_DS_CLASS_T_DEC +template<typename Pred> +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +erase_if(Pred pred) +{ + size_type num_ersd = 0; + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + iterator it = begin(); + while (it != end()) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + if (pred(*it)) + { + ++num_ersd; + it = erase(it); + } + else + ++it; + } + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return num_ersd; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +erase_leaf(leaf_pointer p_l) +{ + update_min_max_for_erased_leaf(p_l); + if (p_l->m_p_parent->m_type == pat_trie_head_node_type) + { + _GLIBCXX_DEBUG_ASSERT(size() == 1); + clear(); + return; + } + + _GLIBCXX_DEBUG_ASSERT(size() > 1); + _GLIBCXX_DEBUG_ASSERT(p_l->m_p_parent->m_type == + pat_trie_internal_node_type); + + internal_node_pointer p_parent = + static_cast<internal_node_pointer>(p_l->m_p_parent); + + p_parent->remove_child(p_l); + erase_fixup(p_parent); + actual_erase_leaf(p_l); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +update_min_max_for_erased_leaf(leaf_pointer p_l) +{ + if (m_size == 1) + { + m_p_head->m_p_min = m_p_head; + m_p_head->m_p_max = m_p_head; + return; + } + + if (p_l == static_cast<const_leaf_pointer>(m_p_head->m_p_min)) + { + iterator it(p_l); + ++it; + m_p_head->m_p_min = it.m_p_nd; + return; + } + + if (p_l == static_cast<const_leaf_pointer>(m_p_head->m_p_max)) + { + iterator it(p_l); + --it; + m_p_head->m_p_max = it.m_p_nd; + } +} diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/find_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/find_fn_imps.hpp new file mode 100644 index 000000000000..d9b3c4a94187 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/find_fn_imps.hpp @@ -0,0 +1,275 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file find_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::point_iterator +PB_DS_CLASS_C_DEC:: +find(const_key_reference r_key) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + node_pointer p_nd = find_imp(r_key); + + if (p_nd == NULL || p_nd->m_type != pat_trie_leaf_node_type) + { + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key);) + return end(); + } + + if (synth_e_access_traits::equal_keys(PB_DS_V2F(static_cast<leaf_pointer>(p_nd)->value()), r_key)) + { + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(r_key)); + return iterator(p_nd); + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key);) + return end(); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_point_iterator +PB_DS_CLASS_C_DEC:: +find(const_key_reference r_key) const +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + const_node_pointer p_nd = const_cast<PB_DS_CLASS_C_DEC* >(this)->find_imp(r_key); + + if (p_nd == NULL || p_nd->m_type != pat_trie_leaf_node_type) + { + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key);) + return end(); + } + + if (synth_e_access_traits::equal_keys(PB_DS_V2F(static_cast<const_leaf_pointer>(p_nd)->value()), r_key)) + { + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(r_key)); + return const_iterator(const_cast<node_pointer>(p_nd)); + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(r_key);) + return end(); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +find_imp(const_key_reference r_key) +{ + if (empty()) + return (NULL); + + typename synth_e_access_traits::const_iterator b_it = + synth_e_access_traits::begin(r_key); + typename synth_e_access_traits::const_iterator e_it = + synth_e_access_traits::end(r_key); + + node_pointer p_nd = m_p_head->m_p_parent; + _GLIBCXX_DEBUG_ASSERT(p_nd != NULL); + + while (p_nd->m_type != pat_trie_leaf_node_type) + { + _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == pat_trie_internal_node_type); + node_pointer p_next_nd = static_cast<internal_node_pointer>(p_nd)->get_child_node(b_it, e_it, this); + + if (p_next_nd == NULL) + return p_nd; + p_nd = p_next_nd; + } + return p_nd; +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +lower_bound_imp(const_key_reference r_key) +{ + if (empty()) + return (m_p_head); + + node_pointer p_nd = m_p_head->m_p_parent; + _GLIBCXX_DEBUG_ASSERT(p_nd != NULL); + + typename PB_DS_CLASS_C_DEC::const_e_iterator b_it = + synth_e_access_traits::begin(r_key); + + typename PB_DS_CLASS_C_DEC::const_e_iterator e_it = + synth_e_access_traits::end(r_key); + + size_type checked_ind = 0; + while (true) + { + if (p_nd->m_type == pat_trie_leaf_node_type) + { + if (!synth_e_access_traits::cmp_keys(PB_DS_V2F(static_cast<const_leaf_pointer>(p_nd)->value()), r_key)) + return p_nd; + iterator it(p_nd); + ++it; + return it.m_p_nd; + } + + _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == pat_trie_internal_node_type); + const size_type new_checked_ind = + static_cast<internal_node_pointer>(p_nd)->get_e_ind(); + + p_nd = + static_cast<internal_node_pointer>(p_nd)->get_lower_bound_child_node( b_it, e_it, checked_ind, this); + checked_ind = new_checked_ind; + } +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::point_iterator +PB_DS_CLASS_C_DEC:: +lower_bound(const_key_reference r_key) +{ return point_iterator(lower_bound_imp(r_key)); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_point_iterator +PB_DS_CLASS_C_DEC:: +lower_bound(const_key_reference r_key) const +{ + return const_point_iterator(const_cast<PB_DS_CLASS_C_DEC* >(this)->lower_bound_imp(r_key)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::point_iterator +PB_DS_CLASS_C_DEC:: +upper_bound(const_key_reference r_key) +{ + point_iterator l_bound_it = lower_bound(r_key); + + _GLIBCXX_DEBUG_ASSERT(l_bound_it == end() || + !synth_e_access_traits::cmp_keys(PB_DS_V2F(*l_bound_it), + r_key)); + + if (l_bound_it == end() || + synth_e_access_traits::cmp_keys(r_key, PB_DS_V2F(*l_bound_it))) + return l_bound_it; + + return ++l_bound_it; +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_point_iterator +PB_DS_CLASS_C_DEC:: +upper_bound(const_key_reference r_key) const +{ + const_point_iterator l_bound_it = lower_bound(r_key); + + _GLIBCXX_DEBUG_ASSERT(l_bound_it == end() || + !synth_e_access_traits::cmp_keys(PB_DS_V2F(*l_bound_it), + r_key)); + + if (l_bound_it == end() || + synth_e_access_traits::cmp_keys(r_key, PB_DS_V2F(*l_bound_it))) + return l_bound_it; + return ++l_bound_it; +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_e_iterator +PB_DS_CLASS_C_DEC:: +pref_begin(const_node_pointer p_nd) +{ + if (p_nd->m_type == pat_trie_leaf_node_type) + return (synth_e_access_traits::begin(PB_DS_V2F(static_cast<const_leaf_pointer>(p_nd)->value()))); + + _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == pat_trie_internal_node_type); + return static_cast<const_internal_node_pointer>(p_nd)->pref_b_it(); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_e_iterator +PB_DS_CLASS_C_DEC:: +pref_end(const_node_pointer p_nd) +{ + if (p_nd->m_type == pat_trie_leaf_node_type) + return (synth_e_access_traits::end(PB_DS_V2F(static_cast<const_leaf_pointer>(p_nd)->value()))); + + _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == pat_trie_internal_node_type); + return static_cast<const_internal_node_pointer>(p_nd)->pref_e_it(); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_leaf_pointer +PB_DS_CLASS_C_DEC:: +leftmost_descendant(const_node_pointer p_nd) +{ + if (p_nd->m_type == pat_trie_leaf_node_type) + return static_cast<const_leaf_pointer>(p_nd); + return static_cast<const_internal_node_pointer>(p_nd)->leftmost_descendant(); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::leaf_pointer +PB_DS_CLASS_C_DEC:: +leftmost_descendant(node_pointer p_nd) +{ + if (p_nd->m_type == pat_trie_leaf_node_type) + return static_cast<leaf_pointer>(p_nd); + return static_cast<internal_node_pointer>(p_nd)->leftmost_descendant(); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_leaf_pointer +PB_DS_CLASS_C_DEC:: +rightmost_descendant(const_node_pointer p_nd) +{ + if (p_nd->m_type == pat_trie_leaf_node_type) + return static_cast<const_leaf_pointer>(p_nd); + return static_cast<const_internal_node_pointer>(p_nd)->rightmost_descendant(); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::leaf_pointer +PB_DS_CLASS_C_DEC:: +rightmost_descendant(node_pointer p_nd) +{ + if (p_nd->m_type == pat_trie_leaf_node_type) + return static_cast<leaf_pointer>(p_nd); + return static_cast<internal_node_pointer>(p_nd)->rightmost_descendant(); +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/head.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/head.hpp new file mode 100644 index 000000000000..e8bee5273508 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/head.hpp @@ -0,0 +1,130 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file head.hpp + * Contains a leaf for a patricia tree. + */ + +#ifndef PB_DS_PAT_TRIE_IHEAD_HPP +#define PB_DS_PAT_TRIE_IHEAD_HPP + +#include <ext/pb_ds/detail/pat_trie_/node_base.hpp> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { +#define PB_DS_CLASS_T_DEC \ + template<typename Type_Traits, typename E_Access_Traits, \ + typename Metadata, typename Allocator> + +#define PB_DS_CLASS_C_DEC \ + pat_trie_head<Type_Traits, E_Access_Traits, Metadata, Allocator> + +#define PB_DS_BASE_C_DEC \ + pat_trie_node_base<Type_Traits, E_Access_Traits, Metadata, Allocator> + + template<typename Type_Traits, + typename E_Access_Traits, + typename Metadata, + typename Allocator> + struct pat_trie_head : public PB_DS_BASE_C_DEC + { + private: + typedef E_Access_Traits e_access_traits; + + typedef + typename Allocator::template rebind< + e_access_traits>::other::const_pointer + const_e_access_traits_pointer; + + typedef + typename Allocator::template rebind< + PB_DS_BASE_C_DEC>::other::pointer + node_pointer; + +#ifdef _GLIBCXX_DEBUG + typedef + typename PB_DS_BASE_C_DEC::subtree_debug_info + subtree_debug_info; +#endif + + public: + pat_trie_head(); + +#ifdef _GLIBCXX_DEBUG + virtual subtree_debug_info + assert_valid_imp(const_e_access_traits_pointer p_traits) const; +#endif + + public: + node_pointer m_p_min; + + node_pointer m_p_max; + }; + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + pat_trie_head() : PB_DS_BASE_C_DEC(pat_trie_head_node_type) + { } + +#ifdef _GLIBCXX_DEBUG + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::subtree_debug_info + PB_DS_CLASS_C_DEC:: + assert_valid_imp(const_e_access_traits_pointer /*p_traits*/) const + { + _GLIBCXX_DEBUG_ASSERT(false); + return subtree_debug_info(); + } +#endif + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_BASE_C_DEC + + } // namespace detail +} // namespace pb_ds + +#endif + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/info_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/info_fn_imps.hpp new file mode 100644 index 000000000000..7e20cd184f40 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/info_fn_imps.hpp @@ -0,0 +1,64 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file info_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +empty() const +{ return (m_size == 0); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +size() const +{ return m_size; } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +max_size() const +{ return s_internal_node_allocator.max_size(); } + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/insert_join_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/insert_join_fn_imps.hpp new file mode 100644 index 000000000000..4916ae34ff68 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/insert_join_fn_imps.hpp @@ -0,0 +1,471 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file insert_join_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +join(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();); + _GLIBCXX_DEBUG_ONLY(other.assert_valid();); + split_join_branch_bag bag; + if (!join_prep(other, bag)) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();); + _GLIBCXX_DEBUG_ONLY(other.assert_valid();); + return; + } + + m_p_head->m_p_parent = rec_join(m_p_head->m_p_parent, + other.m_p_head->m_p_parent, 0, bag); + + m_p_head->m_p_parent->m_p_parent = m_p_head; + m_size += other.m_size; + other.initialize(); + _GLIBCXX_DEBUG_ONLY(other.assert_valid();); + m_p_head->m_p_min = leftmost_descendant(m_p_head->m_p_parent); + m_p_head->m_p_max = rightmost_descendant(m_p_head->m_p_parent); + _GLIBCXX_DEBUG_ONLY(assert_valid();); +} + +PB_DS_CLASS_T_DEC +bool +PB_DS_CLASS_C_DEC:: +join_prep(PB_DS_CLASS_C_DEC& other, split_join_branch_bag& r_bag) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + if (other.m_size == 0) + return false; + + if (m_size == 0) + { + value_swap(other); + return false; + } + + const bool greater = synth_e_access_traits::cmp_keys(PB_DS_V2F(static_cast<const_leaf_pointer>( + m_p_head->m_p_max)->value()),PB_DS_V2F(static_cast<const_leaf_pointer>( + other.m_p_head->m_p_min)->value())); + + const bool lesser = synth_e_access_traits::cmp_keys(PB_DS_V2F(static_cast<const_leaf_pointer>( + other.m_p_head->m_p_max)->value()),PB_DS_V2F(static_cast<const_leaf_pointer>(m_p_head->m_p_min)->value())); + + if (!greater && !lesser) + __throw_join_error(); + + rec_join_prep(m_p_head->m_p_parent, other.m_p_head->m_p_parent, r_bag); + _GLIBCXX_DEBUG_ONLY(map_debug_base::join(other);) + return true; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +rec_join_prep(const_node_pointer p_l, const_node_pointer p_r, split_join_branch_bag& r_bag) +{ + if (p_l->m_type == pat_trie_leaf_node_type) + { + if (p_r->m_type == pat_trie_leaf_node_type) + { + rec_join_prep(static_cast<const_leaf_pointer>(p_l), + static_cast<const_leaf_pointer>(p_r), r_bag); + return; + } + + _GLIBCXX_DEBUG_ASSERT(p_r->m_type == pat_trie_internal_node_type); + rec_join_prep(static_cast<const_leaf_pointer>(p_l), + static_cast<const_internal_node_pointer>(p_r), r_bag); + return; + } + + _GLIBCXX_DEBUG_ASSERT(p_l->m_type == pat_trie_internal_node_type); + if (p_r->m_type == pat_trie_leaf_node_type) + { + rec_join_prep(static_cast<const_internal_node_pointer>(p_l), + static_cast<const_leaf_pointer>(p_r), r_bag); + return; + } + + _GLIBCXX_DEBUG_ASSERT(p_r->m_type == pat_trie_internal_node_type); + + rec_join_prep(static_cast<const_internal_node_pointer>(p_l), + static_cast<const_internal_node_pointer>(p_r), r_bag); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +rec_join_prep(const_leaf_pointer /*p_l*/, const_leaf_pointer /*p_r*/, + split_join_branch_bag& r_bag) +{ r_bag.add_branch(); } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +rec_join_prep(const_leaf_pointer /*p_l*/, const_internal_node_pointer /*p_r*/, + split_join_branch_bag& r_bag) +{ r_bag.add_branch(); } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +rec_join_prep(const_internal_node_pointer /*p_l*/, const_leaf_pointer /*p_r*/, + split_join_branch_bag& r_bag) +{ r_bag.add_branch(); } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +rec_join_prep(const_internal_node_pointer p_l, const_internal_node_pointer p_r, + split_join_branch_bag& r_bag) +{ + if (p_l->get_e_ind() == p_r->get_e_ind() && + synth_e_access_traits::equal_prefixes(p_l->pref_b_it(), p_l->pref_e_it(), + p_r->pref_b_it(), p_r->pref_e_it())) + { + for (typename internal_node::const_iterator it = p_r->begin(); + it != p_r->end(); ++ it) + { + const_node_pointer p_l_join_child = p_l->get_join_child(*it, this); + if (p_l_join_child != NULL) + rec_join_prep(p_l_join_child, * it, r_bag); + } + return; + } + + if (p_r->get_e_ind() < p_l->get_e_ind() && + p_r->should_be_mine(p_l->pref_b_it(), p_l->pref_e_it(), 0, this)) + { + const_node_pointer p_r_join_child = p_r->get_join_child(p_l, this); + if (p_r_join_child != NULL) + rec_join_prep(p_r_join_child, p_l, r_bag); + return; + } + + if (p_r->get_e_ind() < p_l->get_e_ind() && + p_r->should_be_mine(p_l->pref_b_it(), p_l->pref_e_it(), 0, this)) + { + const_node_pointer p_r_join_child = p_r->get_join_child(p_l, this); + if (p_r_join_child != NULL) + rec_join_prep(p_r_join_child, p_l, r_bag); + return; + } + r_bag.add_branch(); +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +rec_join(node_pointer p_l, node_pointer p_r, size_type checked_ind, split_join_branch_bag& r_bag) +{ + _GLIBCXX_DEBUG_ASSERT(p_r != NULL); + if (p_l == NULL) + { + apply_update(p_r, (node_update* )this); + return (p_r); + } + + if (p_l->m_type == pat_trie_leaf_node_type) + { + if (p_r->m_type == pat_trie_leaf_node_type) + { + node_pointer p_ret = rec_join(static_cast<leaf_pointer>(p_l), + static_cast<leaf_pointer>(p_r), r_bag); + apply_update(p_ret, (node_update* )this); + return p_ret; + } + + _GLIBCXX_DEBUG_ASSERT(p_r->m_type == pat_trie_internal_node_type); + node_pointer p_ret = rec_join(static_cast<leaf_pointer>(p_l), + static_cast<internal_node_pointer>(p_r), + checked_ind, r_bag); + apply_update(p_ret, (node_update* )this); + return p_ret; + } + + _GLIBCXX_DEBUG_ASSERT(p_l->m_type == pat_trie_internal_node_type); + if (p_r->m_type == pat_trie_leaf_node_type) + { + node_pointer p_ret = rec_join(static_cast<internal_node_pointer>(p_l), + static_cast<leaf_pointer>(p_r), + checked_ind, r_bag); + apply_update(p_ret, (node_update* )this); + return p_ret; + } + + _GLIBCXX_DEBUG_ASSERT(p_r->m_type == pat_trie_internal_node_type); + node_pointer p_ret = rec_join(static_cast<internal_node_pointer>(p_l), + static_cast<internal_node_pointer>(p_r), + r_bag); + + apply_update(p_ret, (node_update* )this); + return p_ret; +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +rec_join(leaf_pointer p_l, leaf_pointer p_r, split_join_branch_bag& r_bag) +{ + _GLIBCXX_DEBUG_ASSERT(p_r != NULL); + if (p_l == NULL) + return (p_r); + node_pointer p_ret = insert_branch(p_l, p_r, r_bag); + _GLIBCXX_DEBUG_ASSERT(recursive_count_leafs(p_ret) == 2); + return p_ret; +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +rec_join(leaf_pointer p_l, internal_node_pointer p_r, size_type checked_ind, + split_join_branch_bag& r_bag) +{ +#ifdef _GLIBCXX_DEBUG + const size_type lhs_leafs = recursive_count_leafs(p_l); + const size_type rhs_leafs = recursive_count_leafs(p_r); +#endif + + _GLIBCXX_DEBUG_ASSERT(p_r != NULL); + node_pointer p_ret = rec_join(p_r, p_l, checked_ind, r_bag); + _GLIBCXX_DEBUG_ASSERT(recursive_count_leafs(p_ret) == lhs_leafs + rhs_leafs); + return p_ret; +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +rec_join(internal_node_pointer p_l, leaf_pointer p_r, size_type checked_ind, split_join_branch_bag& r_bag) +{ + _GLIBCXX_DEBUG_ASSERT(p_l != NULL); + _GLIBCXX_DEBUG_ASSERT(p_r != NULL); + +#ifdef _GLIBCXX_DEBUG + const size_type lhs_leafs = recursive_count_leafs(p_l); + const size_type rhs_leafs = recursive_count_leafs(p_r); +#endif + + if (!p_l->should_be_mine(pref_begin(p_r), pref_end(p_r), checked_ind, this)) + { + node_pointer p_ret = insert_branch(p_l, p_r, r_bag); + _GLIBCXX_DEBUG_ONLY(p_ret->assert_valid(this);) + _GLIBCXX_DEBUG_ASSERT(recursive_count_leafs(p_ret) == + lhs_leafs + rhs_leafs); + return p_ret; + } + + node_pointer p_pot_child = p_l->add_child(p_r, pref_begin(p_r), + pref_end(p_r), this); + if (p_pot_child != p_r) + { + node_pointer p_new_child = rec_join(p_pot_child, p_r, p_l->get_e_ind(), + r_bag); + + p_l->replace_child(p_new_child, pref_begin(p_new_child), + pref_end(p_new_child), this); + } + + _GLIBCXX_DEBUG_ONLY(p_l->assert_valid(this)); + _GLIBCXX_DEBUG_ASSERT(recursive_count_leafs(p_l) == lhs_leafs + rhs_leafs); + return p_l; +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +rec_join(internal_node_pointer p_l, internal_node_pointer p_r, split_join_branch_bag& r_bag) +{ + _GLIBCXX_DEBUG_ASSERT(p_l != NULL); + _GLIBCXX_DEBUG_ASSERT(p_r != NULL); + +#ifdef _GLIBCXX_DEBUG + const size_type lhs_leafs = recursive_count_leafs(p_l); + const size_type rhs_leafs = recursive_count_leafs(p_r); +#endif + + if (p_l->get_e_ind() == p_r->get_e_ind() && + synth_e_access_traits::equal_prefixes(p_l->pref_b_it(), p_l->pref_e_it(), + p_r->pref_b_it(), p_r->pref_e_it())) + { + for (typename internal_node::iterator it = p_r->begin(); + it != p_r->end(); ++ it) + { + node_pointer p_new_child = rec_join(p_l->get_join_child(*it, this), + * it, 0, r_bag); + p_l->replace_child(p_new_child, pref_begin(p_new_child), + pref_end(p_new_child), this); + } + + p_r->~internal_node(); + s_internal_node_allocator.deallocate(p_r, 1); + _GLIBCXX_DEBUG_ONLY(p_l->assert_valid(this);) + _GLIBCXX_DEBUG_ASSERT(recursive_count_leafs(p_l) == lhs_leafs + rhs_leafs); + return p_l; + } + + if (p_l->get_e_ind() < p_r->get_e_ind() && + p_l->should_be_mine(p_r->pref_b_it(), p_r->pref_e_it(), 0, this)) + { + node_pointer p_new_child = rec_join(p_l->get_join_child(p_r, this), + p_r, 0, r_bag); + p_l->replace_child(p_new_child, pref_begin(p_new_child), + pref_end(p_new_child), this); + _GLIBCXX_DEBUG_ONLY(p_l->assert_valid(this);) + return p_l; + } + + if (p_r->get_e_ind() < p_l->get_e_ind() && + p_r->should_be_mine(p_l->pref_b_it(), p_l->pref_e_it(), 0, this)) + { + node_pointer p_new_child = rec_join(p_r->get_join_child(p_l, this), p_l, + 0, r_bag); + + p_r->replace_child(p_new_child, pref_begin(p_new_child), + pref_end(p_new_child), this); + + _GLIBCXX_DEBUG_ONLY(p_r->assert_valid(this);) + _GLIBCXX_DEBUG_ASSERT(recursive_count_leafs(p_r) == lhs_leafs + rhs_leafs); + return p_r; + } + + node_pointer p_ret = insert_branch(p_l, p_r, r_bag); + _GLIBCXX_DEBUG_ONLY(p_ret->assert_valid(this);) + _GLIBCXX_DEBUG_ASSERT(recursive_count_leafs(p_ret) == lhs_leafs + rhs_leafs); + return p_ret; +} + +PB_DS_CLASS_T_DEC +inline std::pair<typename PB_DS_CLASS_C_DEC::iterator, bool> +PB_DS_CLASS_C_DEC:: +insert(const_reference r_val) +{ + node_pointer p_lf = find_imp(PB_DS_V2F(r_val)); + if (p_lf != NULL && p_lf->m_type == pat_trie_leaf_node_type && + synth_e_access_traits::equal_keys(PB_DS_V2F(static_cast<leaf_pointer>(p_lf)->value()), PB_DS_V2F(r_val))) + { + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_exists(PB_DS_V2F(r_val))); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return std::make_pair(iterator(p_lf), false); + } + + _GLIBCXX_DEBUG_ONLY(map_debug_base::check_key_does_not_exist(PB_DS_V2F(r_val))); + + leaf_pointer p_new_lf = s_leaf_allocator.allocate(1); + cond_dealtor cond(p_new_lf); + + new (p_new_lf) leaf(r_val); + apply_update(p_new_lf, (node_update* )this); + cond.set_call_destructor(); + split_join_branch_bag bag; + bag.add_branch(); + m_p_head->m_p_parent = rec_join(m_p_head->m_p_parent, p_new_lf, 0, bag); + m_p_head->m_p_parent->m_p_parent = m_p_head; + cond.set_no_action_dtor(); + ++m_size; + update_min_max_for_inserted_leaf(p_new_lf); + _GLIBCXX_DEBUG_ONLY(map_debug_base::insert_new(PB_DS_V2F(r_val));) + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return std::make_pair(point_iterator(p_new_lf), true); +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +keys_diff_ind(typename e_access_traits::const_iterator b_l, typename e_access_traits::const_iterator e_l, typename e_access_traits::const_iterator b_r, typename e_access_traits::const_iterator e_r) +{ + size_type diff_pos = 0; + while (b_l != e_l) + { + if (b_r == e_r) + return (diff_pos); + if (e_access_traits::e_pos(*b_l) != e_access_traits::e_pos(*b_r)) + return (diff_pos); + ++b_l; + ++b_r; + ++diff_pos; + } + _GLIBCXX_DEBUG_ASSERT(b_r != e_r); + return diff_pos; +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::internal_node_pointer +PB_DS_CLASS_C_DEC:: +insert_branch(node_pointer p_l, node_pointer p_r, split_join_branch_bag& r_bag) +{ + typename synth_e_access_traits::const_iterator left_b_it = pref_begin(p_l); + typename synth_e_access_traits::const_iterator left_e_it = pref_end(p_l); + typename synth_e_access_traits::const_iterator right_b_it = pref_begin(p_r); + typename synth_e_access_traits::const_iterator right_e_it = pref_end(p_r); + + const size_type diff_ind = keys_diff_ind(left_b_it, left_e_it, + right_b_it, right_e_it); + + internal_node_pointer p_new_nd = r_bag.get_branch(); + new (p_new_nd) internal_node(diff_ind, left_b_it); + p_new_nd->add_child(p_l, left_b_it, left_e_it, this); + p_new_nd->add_child(p_r, right_b_it, right_e_it, this); + p_l->m_p_parent = p_new_nd; + p_r->m_p_parent = p_new_nd; + _GLIBCXX_DEBUG_ONLY(p_new_nd->assert_valid(this);) + return (p_new_nd); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +update_min_max_for_inserted_leaf(leaf_pointer p_new_lf) +{ + if (m_p_head->m_p_min == m_p_head || + synth_e_access_traits::cmp_keys(PB_DS_V2F(p_new_lf->value()), + PB_DS_V2F(static_cast<const_leaf_pointer>(m_p_head->m_p_min)->value()))) + m_p_head->m_p_min = p_new_lf; + + if (m_p_head->m_p_max == m_p_head || + synth_e_access_traits::cmp_keys(PB_DS_V2F(static_cast<const_leaf_pointer>(m_p_head->m_p_max)->value()), PB_DS_V2F(p_new_lf->value()))) + m_p_head->m_p_max = p_new_lf; +} diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/internal_node.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/internal_node.hpp new file mode 100644 index 000000000000..1061988c327e --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/internal_node.hpp @@ -0,0 +1,609 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file internal_node.hpp + * Contains an internal PB_DS_BASE_C_DEC for a patricia tree. + */ + +#ifndef PB_DS_PAT_TRIE_INTERNAL_NODE_HPP +#define PB_DS_PAT_TRIE_INTERNAL_NODE_HPP + +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { +#define PB_DS_CLASS_T_DEC \ + template<typename Type_Traits, typename E_Access_Traits, \ + typename Metadata, typename Allocator> + +#define PB_DS_CLASS_C_DEC \ + pat_trie_internal_node<Type_Traits, E_Access_Traits, Metadata, Allocator> + +#define PB_DS_BASE_C_DEC \ + pat_trie_node_base<Type_Traits, E_Access_Traits, Metadata, Allocator> + +#define PB_DS_LEAF_C_DEC \ + pat_trie_leaf<Type_Traits, E_Access_Traits, Metadata, Allocator> + +#define PB_DS_STATIC_ASSERT(UNIQUE, E) \ + typedef static_assert_dumclass<sizeof(static_assert<(bool)(E)>)> UNIQUE##static_assert_type + + template<typename Type_Traits, + typename E_Access_Traits, + typename Metadata, + typename Allocator> + struct pat_trie_internal_node : public PB_DS_BASE_C_DEC + { + private: + typedef PB_DS_BASE_C_DEC base_type; + typedef Type_Traits type_traits; + typedef typename type_traits::value_type value_type; + typedef typename Allocator::size_type size_type; + + typedef E_Access_Traits e_access_traits; + typedef typename e_access_traits::const_iterator const_e_iterator; + typedef typename Allocator::template rebind<e_access_traits>::other access_rebind; + typedef typename access_rebind::const_pointer const_e_access_traits_pointer; + + typedef typename Allocator::template rebind<base_type>::other base_rebind; + typedef typename base_rebind::pointer node_pointer; + typedef typename base_rebind::const_pointer const_node_pointer; + + typedef PB_DS_LEAF_C_DEC leaf; + typedef typename Allocator::template rebind<leaf>::other leaf_rebind; + typedef typename leaf_rebind::pointer leaf_pointer; + typedef typename leaf_rebind::const_pointer const_leaf_pointer; + + typedef typename Allocator::template rebind<pat_trie_internal_node>::other internal_node_rebind; + typedef typename internal_node_rebind::pointer internal_node_pointer; + typedef typename internal_node_rebind::const_pointer const_internal_node_pointer; + +#ifdef _GLIBCXX_DEBUG + typedef typename base_type::subtree_debug_info subtree_debug_info; + + virtual subtree_debug_info + assert_valid_imp(const_e_access_traits_pointer) const; +#endif + + inline size_type + get_pref_pos(const_e_iterator, const_e_iterator, + const_e_access_traits_pointer) const; + + public: + typedef typename Allocator::template rebind<node_pointer>::other node_pointer_rebind; + typedef typename node_pointer_rebind::pointer node_pointer_pointer; + typedef typename node_pointer_rebind::reference node_pointer_reference; + + enum + { + arr_size = E_Access_Traits::max_size + 1 + }; + PB_DS_STATIC_ASSERT(min_arr_size, arr_size >= 2); + +#include <ext/pb_ds/detail/pat_trie_/const_child_iterator.hpp> +#include <ext/pb_ds/detail/pat_trie_/child_iterator.hpp> + + pat_trie_internal_node(size_type, const const_e_iterator); + + void + update_prefixes(const_e_access_traits_pointer); + + const_iterator + begin() const; + + iterator + begin(); + + const_iterator + end() const; + + iterator + end(); + + inline node_pointer + get_child_node(const_e_iterator, const_e_iterator, + const_e_access_traits_pointer); + + inline const_node_pointer + get_child_node(const_e_iterator, const_e_iterator, + const_e_access_traits_pointer) const; + + inline iterator + get_child_it(const_e_iterator, const_e_iterator, + const_e_access_traits_pointer); + + inline node_pointer + get_lower_bound_child_node(const_e_iterator, const_e_iterator, + size_type, const_e_access_traits_pointer); + + inline node_pointer + add_child(node_pointer, const_e_iterator, const_e_iterator, + const_e_access_traits_pointer); + + inline const_node_pointer + get_join_child(const_node_pointer, const_e_access_traits_pointer) const; + + inline node_pointer + get_join_child(node_pointer, const_e_access_traits_pointer); + + void + remove_child(node_pointer p_nd); + + iterator + remove_child(iterator it); + + void + replace_child(node_pointer, const_e_iterator, const_e_iterator, + const_e_access_traits_pointer); + + inline const_e_iterator + pref_b_it() const; + + inline const_e_iterator + pref_e_it() const; + + inline size_type + get_e_ind() const; + + bool + should_be_mine(const_e_iterator, const_e_iterator, size_type, + const_e_access_traits_pointer) const; + + leaf_pointer + leftmost_descendant(); + + const_leaf_pointer + leftmost_descendant() const; + + leaf_pointer + rightmost_descendant(); + + const_leaf_pointer + rightmost_descendant() const; + +#ifdef _GLIBCXX_DEBUG + size_type + e_ind() const; +#endif + + private: + pat_trie_internal_node(const pat_trie_internal_node&); + + size_type + get_begin_pos() const; + + const size_type m_e_ind; + const_e_iterator m_pref_b_it; + const_e_iterator m_pref_e_it; + node_pointer m_a_p_children[arr_size]; + static leaf_rebind s_leaf_alloc; + static internal_node_rebind s_internal_node_alloc; + }; + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::leaf_rebind + PB_DS_CLASS_C_DEC::s_leaf_alloc; + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::internal_node_rebind + PB_DS_CLASS_C_DEC::s_internal_node_alloc; + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::size_type + PB_DS_CLASS_C_DEC:: + get_pref_pos(const_e_iterator b_it, const_e_iterator e_it, + const_e_access_traits_pointer p_traits) const + { + if (static_cast<size_t>(std::distance(b_it, e_it)) <= m_e_ind) + return 0; + std::advance(b_it, m_e_ind); + return 1 + p_traits->e_pos(*b_it); + } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + pat_trie_internal_node(size_type len, const const_e_iterator it) : + PB_DS_BASE_C_DEC(pat_trie_internal_node_type), + m_e_ind(len), m_pref_b_it(it), m_pref_e_it(it) + { + std::advance(m_pref_e_it, m_e_ind); + std::fill(m_a_p_children, m_a_p_children + arr_size, + static_cast<node_pointer>(NULL)); + } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + update_prefixes(const_e_access_traits_pointer p_traits) + { + node_pointer p_first = *begin(); + if (p_first->m_type == pat_trie_leaf_node_type) + { + const_leaf_pointer p = static_cast<const_leaf_pointer>(p_first); + m_pref_b_it = p_traits->begin(e_access_traits::extract_key(p->value())); + } + else + { + _GLIBCXX_DEBUG_ASSERT(p_first->m_type == pat_trie_internal_node_type); + m_pref_b_it = static_cast<internal_node_pointer>(p_first)->pref_b_it(); + } + m_pref_e_it = m_pref_b_it; + std::advance(m_pref_e_it, m_e_ind); + } + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::const_iterator + PB_DS_CLASS_C_DEC:: + begin() const + { + typedef node_pointer_pointer pointer_type; + pointer_type p = const_cast<pointer_type>(m_a_p_children); + return const_iterator(p + get_begin_pos(), p + arr_size); + } + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::iterator + PB_DS_CLASS_C_DEC:: + begin() + { + return iterator(m_a_p_children + get_begin_pos(), + m_a_p_children + arr_size); + } + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::const_iterator + PB_DS_CLASS_C_DEC:: + end() const + { + typedef node_pointer_pointer pointer_type; + pointer_type p = const_cast<pointer_type>(m_a_p_children) + arr_size; + return const_iterator(p, p); + } + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::iterator + PB_DS_CLASS_C_DEC:: + end() + { return iterator(m_a_p_children + arr_size, m_a_p_children + arr_size); } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::node_pointer + PB_DS_CLASS_C_DEC:: + get_child_node(const_e_iterator b_it, const_e_iterator e_it, + const_e_access_traits_pointer p_traits) + { + const size_type i = get_pref_pos(b_it, e_it, p_traits); + _GLIBCXX_DEBUG_ASSERT(i < arr_size); + return m_a_p_children[i]; + } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::iterator + PB_DS_CLASS_C_DEC:: + get_child_it(const_e_iterator b_it, const_e_iterator e_it, + const_e_access_traits_pointer p_traits) + { + const size_type i = get_pref_pos(b_it, e_it, p_traits); + _GLIBCXX_DEBUG_ASSERT(i < arr_size); + _GLIBCXX_DEBUG_ASSERT(m_a_p_children[i] != NULL); + return iterator(m_a_p_children + i, m_a_p_children + i); + } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::const_node_pointer + PB_DS_CLASS_C_DEC:: + get_child_node(const_e_iterator b_it, const_e_iterator e_it, + const_e_access_traits_pointer p_traits) const + { return const_cast<node_pointer>(get_child_node(b_it, e_it, p_traits)); } + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::node_pointer + PB_DS_CLASS_C_DEC:: + get_lower_bound_child_node(const_e_iterator b_it, const_e_iterator e_it, + size_type checked_ind, + const_e_access_traits_pointer p_traits) + { + if (!should_be_mine(b_it, e_it, checked_ind, p_traits)) + { + if (p_traits->cmp_prefixes(b_it, e_it, m_pref_b_it, m_pref_e_it, true)) + return leftmost_descendant(); + return rightmost_descendant(); + } + + size_type i = get_pref_pos(b_it, e_it, p_traits); + _GLIBCXX_DEBUG_ASSERT(i < arr_size); + + if (m_a_p_children[i] != NULL) + return m_a_p_children[i]; + + while (++i < arr_size) + if (m_a_p_children[i] != NULL) + { + if (m_a_p_children[i]->m_type == pat_trie_leaf_node_type) + return m_a_p_children[i]; + + _GLIBCXX_DEBUG_ASSERT(m_a_p_children[i]->m_type == pat_trie_internal_node_type); + + return static_cast<internal_node_pointer>(m_a_p_children[i])->leftmost_descendant(); + } + + return rightmost_descendant(); + } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::node_pointer + PB_DS_CLASS_C_DEC:: + add_child(node_pointer p_nd, const_e_iterator b_it, const_e_iterator e_it, + const_e_access_traits_pointer p_traits) + { + const size_type i = get_pref_pos(b_it, e_it, p_traits); + _GLIBCXX_DEBUG_ASSERT(i < arr_size); + if (m_a_p_children[i] == NULL) + { + m_a_p_children[i] = p_nd; + p_nd->m_p_parent = this; + return p_nd; + } + return m_a_p_children[i]; + } + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::const_node_pointer + PB_DS_CLASS_C_DEC:: + get_join_child(const_node_pointer p_nd, const_e_access_traits_pointer p_traits) const + { + node_pointer p = const_cast<node_pointer>(p_nd); + return const_cast<internal_node_pointer>(this)->get_join_child(p, p_traits); + } + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::node_pointer + PB_DS_CLASS_C_DEC:: + get_join_child(node_pointer p_nd, const_e_access_traits_pointer p_traits) + { + size_type i; + const_e_iterator b_it; + const_e_iterator e_it; + if (p_nd->m_type == pat_trie_leaf_node_type) + { + typename Type_Traits::const_key_reference r_key = + e_access_traits::extract_key(static_cast<const_leaf_pointer>(p_nd)->value()); + + b_it = p_traits->begin(r_key); + e_it = p_traits->end(r_key); + } + else + { + b_it = static_cast<internal_node_pointer>(p_nd)->pref_b_it(); + e_it = static_cast<internal_node_pointer>(p_nd)->pref_e_it(); + } + i = get_pref_pos(b_it, e_it, p_traits); + _GLIBCXX_DEBUG_ASSERT(i < arr_size); + return m_a_p_children[i]; + } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + remove_child(node_pointer p_nd) + { + size_type i = 0; + for (; i < arr_size; ++i) + if (m_a_p_children[i] == p_nd) + { + m_a_p_children[i] = NULL; + return; + } + _GLIBCXX_DEBUG_ASSERT(i != arr_size); + } + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::iterator + PB_DS_CLASS_C_DEC:: + remove_child(iterator it) + { + iterator ret = it; + ++ret; + * it.m_p_p_cur = NULL; + return ret; + } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + replace_child(node_pointer p_nd, const_e_iterator b_it, + const_e_iterator e_it, + const_e_access_traits_pointer p_traits) + { + const size_type i = get_pref_pos(b_it, e_it, p_traits); + _GLIBCXX_DEBUG_ASSERT(i < arr_size); + m_a_p_children[i] = p_nd; + p_nd->m_p_parent = this; + } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::const_e_iterator + PB_DS_CLASS_C_DEC:: + pref_b_it() const + { return m_pref_b_it; } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::const_e_iterator + PB_DS_CLASS_C_DEC:: + pref_e_it() const + { return m_pref_e_it; } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::size_type + PB_DS_CLASS_C_DEC:: + get_e_ind() const + { return m_e_ind; } + + PB_DS_CLASS_T_DEC + bool + PB_DS_CLASS_C_DEC:: + should_be_mine(const_e_iterator b_it, const_e_iterator e_it, + size_type checked_ind, + const_e_access_traits_pointer p_traits) const + { + if (m_e_ind == 0) + return true; + + const size_type num_es = std::distance(b_it, e_it); + if (num_es < m_e_ind) + return false; + + const_e_iterator key_b_it = b_it; + std::advance(key_b_it, checked_ind); + const_e_iterator key_e_it = b_it; + std::advance(key_e_it, m_e_ind); + + const_e_iterator value_b_it = m_pref_b_it; + std::advance(value_b_it, checked_ind); + const_e_iterator value_e_it = m_pref_b_it; + std::advance(value_e_it, m_e_ind); + + return p_traits->equal_prefixes(key_b_it, key_e_it, value_b_it, + value_e_it); + } + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::leaf_pointer + PB_DS_CLASS_C_DEC:: + leftmost_descendant() + { + node_pointer p_pot =* begin(); + if (p_pot->m_type == pat_trie_leaf_node_type) + return (static_cast<leaf_pointer>(p_pot)); + _GLIBCXX_DEBUG_ASSERT(p_pot->m_type == pat_trie_internal_node_type); + return static_cast<internal_node_pointer>(p_pot)->leftmost_descendant(); + } + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::const_leaf_pointer + PB_DS_CLASS_C_DEC:: + leftmost_descendant() const + { + return const_cast<internal_node_pointer>(this)->leftmost_descendant(); + } + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::leaf_pointer + PB_DS_CLASS_C_DEC:: + rightmost_descendant() + { + const size_type num_children = std::distance(begin(), end()); + _GLIBCXX_DEBUG_ASSERT(num_children >= 2); + + iterator it = begin(); + std::advance(it, num_children - 1); + node_pointer p_pot =* it; + if (p_pot->m_type == pat_trie_leaf_node_type) + return static_cast<leaf_pointer>(p_pot); + _GLIBCXX_DEBUG_ASSERT(p_pot->m_type == pat_trie_internal_node_type); + return static_cast<internal_node_pointer>(p_pot)->rightmost_descendant(); + } + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::const_leaf_pointer + PB_DS_CLASS_C_DEC:: + rightmost_descendant() const + { + return const_cast<internal_node_pointer>(this)->rightmost_descendant(); + } + +#ifdef _GLIBCXX_DEBUG + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::size_type + PB_DS_CLASS_C_DEC:: + e_ind() const + { return m_e_ind; } +#endif + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::size_type + PB_DS_CLASS_C_DEC:: + get_begin_pos() const + { + size_type i; + for (i = 0; i < arr_size && m_a_p_children[i] == NULL; ++i) + ; + return i; + } + +#ifdef _GLIBCXX_DEBUG + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::subtree_debug_info + PB_DS_CLASS_C_DEC:: + assert_valid_imp(const_e_access_traits_pointer p_traits) const + { + _GLIBCXX_DEBUG_ASSERT(base_type::m_type == pat_trie_internal_node_type); + _GLIBCXX_DEBUG_ASSERT(static_cast<size_type>(std::distance(pref_b_it(), pref_e_it())) == m_e_ind); + _GLIBCXX_DEBUG_ASSERT(std::distance(begin(), end()) >= 2); + + for (typename pat_trie_internal_node::const_iterator it = begin(); + it != end(); ++it) + { + const_node_pointer p_nd =* it; + _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_parent == this); + subtree_debug_info child_ret = p_nd->assert_valid_imp(p_traits); + + _GLIBCXX_DEBUG_ASSERT(static_cast<size_type>(std::distance(child_ret.first, child_ret.second)) >= m_e_ind); + _GLIBCXX_DEBUG_ASSERT(should_be_mine(child_ret.first, child_ret.second, 0, p_traits)); + _GLIBCXX_DEBUG_ASSERT(get_pref_pos(child_ret.first, child_ret.second, p_traits) == static_cast<size_type>(it.m_p_p_cur - m_a_p_children)); + } + return std::make_pair(pref_b_it(), pref_e_it()); + } +#endif + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_BASE_C_DEC +#undef PB_DS_LEAF_C_DEC +#undef PB_DS_STATIC_ASSERT + + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/iterators_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/iterators_fn_imps.hpp new file mode 100644 index 000000000000..ff117c514ab2 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/iterators_fn_imps.hpp @@ -0,0 +1,126 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file iterators_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +begin() +{ return iterator(m_p_head->m_p_min); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +begin() const +{ return const_iterator(m_p_head->m_p_min); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +end() +{ return iterator(m_p_head); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +end() const +{ return const_iterator(m_p_head); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_reverse_iterator +PB_DS_CLASS_C_DEC:: +rbegin() const +{ + if (empty()) + return rend(); + return --end(); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::reverse_iterator +PB_DS_CLASS_C_DEC:: +rbegin() +{ + if (empty()) + return rend(); + return --end(); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::reverse_iterator +PB_DS_CLASS_C_DEC:: +rend() +{ return reverse_iterator(m_p_head); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_reverse_iterator +PB_DS_CLASS_C_DEC:: +rend() const +{ return const_reverse_iterator(m_p_head); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_node_iterator +PB_DS_CLASS_C_DEC:: +node_begin() const +{ return const_node_iterator(m_p_head->m_p_parent, this); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_iterator +PB_DS_CLASS_C_DEC:: +node_begin() +{ return node_iterator(m_p_head->m_p_parent, this); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_node_iterator +PB_DS_CLASS_C_DEC:: +node_end() const +{ return const_node_iterator(NULL, this); } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_iterator +PB_DS_CLASS_C_DEC:: +node_end() +{ return node_iterator(NULL, this); } + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/leaf.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/leaf.hpp new file mode 100644 index 000000000000..08f3761deda1 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/leaf.hpp @@ -0,0 +1,177 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file leaf.hpp + * Contains a pat_trie_leaf for a patricia tree. + */ + +#ifndef PB_DS_PAT_TRIE_LEAF_HPP +#define PB_DS_PAT_TRIE_LEAF_HPP + +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_CLASS_T_DEC \ + template< \ + class Type_Traits, \ + class E_Access_Traits, \ + class Metadata, \ + class Allocator> + +#define PB_DS_CLASS_C_DEC \ + pat_trie_leaf< \ + Type_Traits, \ + E_Access_Traits, \ + Metadata, \ + Allocator> + +#define PB_DS_BASE_C_DEC \ + pat_trie_node_base< \ + Type_Traits, \ + E_Access_Traits, \ + Metadata, \ + Allocator> + +#define PB_DS_PAT_TRIE_SUBTREE_DEBUG_INFO_C_DEC \ + pat_trie_subtree_debug_info< \ + Type_Traits, \ + E_Access_Traits, \ + Allocator> + + template<typename Type_Traits, + class E_Access_Traits, + class Metadata, + class Allocator> + struct pat_trie_leaf : public PB_DS_BASE_C_DEC + { + private: + typedef typename Type_Traits::value_type value_type; + + typedef typename Type_Traits::const_reference const_reference; + + typedef typename Type_Traits::reference reference; + + typedef + typename Allocator::template rebind< + E_Access_Traits>::other::const_pointer + const_e_access_traits_pointer; + +#ifdef _GLIBCXX_DEBUG + typedef + typename PB_DS_BASE_C_DEC::subtree_debug_info + subtree_debug_info; +#endif + + typedef PB_DS_BASE_C_DEC base_type; + + public: + pat_trie_leaf(const_reference r_val); + + inline reference + value(); + + inline const_reference + value() const; + +#ifdef _GLIBCXX_DEBUG + virtual subtree_debug_info + assert_valid_imp(const_e_access_traits_pointer p_traits) const; + + virtual + ~pat_trie_leaf(); +#endif + + private: + pat_trie_leaf(const PB_DS_CLASS_C_DEC& other); + + value_type m_value; + }; + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + pat_trie_leaf(const_reference r_val) : + PB_DS_BASE_C_DEC(pat_trie_leaf_node_type), m_value(r_val) + { } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::reference + PB_DS_CLASS_C_DEC:: + value() + { return m_value; } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::const_reference + PB_DS_CLASS_C_DEC:: + value() const + { return m_value; } + +#ifdef _GLIBCXX_DEBUG + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::subtree_debug_info + PB_DS_CLASS_C_DEC:: + assert_valid_imp(const_e_access_traits_pointer p_traits) const + { + _GLIBCXX_DEBUG_ASSERT(base_type::m_type == pat_trie_leaf_node_type); + subtree_debug_info ret; + const_reference r_val = value(); + return std::make_pair(p_traits->begin(p_traits->extract_key(r_val)), + p_traits->end(p_traits->extract_key(r_val))); + } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + ~pat_trie_leaf() { } +#endif + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_BASE_C_DEC +#undef PB_DS_PAT_TRIE_SUBTREE_DEBUG_INFO_C_DEC + + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/node_base.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/node_base.hpp new file mode 100644 index 000000000000..753e66b28a5c --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/node_base.hpp @@ -0,0 +1,134 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file node_base.hpp + * Contains a pat_trie_node_base base for a patricia tree. + */ + +#ifndef PB_DS_PAT_TRIE_NODE_BASE_HPP +#define PB_DS_PAT_TRIE_NODE_BASE_HPP + +#include <ext/pb_ds/detail/pat_trie_/node_metadata_base.hpp> + +namespace pb_ds +{ + namespace detail + { +#define PB_DS_CLASS_T_DEC \ + template<typename Type_Traits, typename E_Access_Traits, \ + typename Metadata, typename Allocator> + +#define PB_DS_CLASS_C_DEC \ + pat_trie_node_base<Type_Traits, E_Access_Traits, Metadata, Allocator> + +#define PB_DS_PAT_TRIE_SUBTREE_DEBUG_INFO_C_DEC \ + pat_trie_subtree_debug_info<Type_Traits, E_Access_Traits, Allocator> + + enum pat_trie_node_type + { + pat_trie_internal_node_type, + pat_trie_leaf_node_type, + pat_trie_head_node_type + }; + + template<typename Type_Traits, + typename E_Access_Traits, + typename Metadata, + typename Allocator> + struct pat_trie_node_base : public pat_trie_node_metadata_base< + Metadata, + Allocator> + { + public: + typedef + typename Allocator::template rebind< + pat_trie_node_base>::other::pointer + node_pointer; + + typedef + typename Allocator::template rebind< + E_Access_Traits>::other::const_pointer + const_e_access_traits_pointer; + +#ifdef _GLIBCXX_DEBUG + typedef + std::pair< + typename E_Access_Traits::const_iterator, + typename E_Access_Traits::const_iterator> + subtree_debug_info; +#endif + + pat_trie_node_base(pat_trie_node_type type); + +#ifdef _GLIBCXX_DEBUG + void + assert_valid(const_e_access_traits_pointer p_traits) const; + + virtual subtree_debug_info + assert_valid_imp(const_e_access_traits_pointer p_traits) const = 0; +#endif + + node_pointer m_p_parent; + const pat_trie_node_type m_type; + }; + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + pat_trie_node_base(pat_trie_node_type type) : m_type(type) + { } + +#ifdef _GLIBCXX_DEBUG + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + assert_valid(const_e_access_traits_pointer p_traits) const + { assert_valid_imp(p_traits); } +#endif + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_PAT_TRIE_SUBTREE_DEBUG_INFO_C_DEC + + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/node_iterators.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/node_iterators.hpp new file mode 100644 index 000000000000..9c8a40c4fdce --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/node_iterators.hpp @@ -0,0 +1,344 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file node_iterators.hpp + * Contains an implementation class for pat_trie_. + */ + +#ifndef PB_DS_PAT_TRIE_NODE_ITERATORS_HPP +#define PB_DS_PAT_TRIE_NODE_ITERATORS_HPP + +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_PAT_TRIE_CONST_NODE_ITERATOR_C_DEC \ + pat_trie_const_node_it_< \ + Node, \ + Leaf, \ + Head, \ + Internal_Node, \ + Const_Iterator, \ + Iterator, \ + E_Access_Traits, \ + Allocator> + +#define PB_DS_PAT_TRIE_NODE_ITERATOR_C_DEC \ + pat_trie_node_it_< \ + Node, \ + Leaf, \ + Head, \ + Internal_Node, \ + Const_Iterator, \ + Iterator, \ + E_Access_Traits, \ + Allocator> + + // Const node iterator. + template<typename Node, + class Leaf, + class Head, + class Internal_Node, + class Const_Iterator, + class Iterator, + class E_Access_Traits, + class Allocator> + class pat_trie_const_node_it_ + { + protected: + typedef + typename Allocator::template rebind< + Node>::other::pointer + node_pointer; + + typedef + typename Allocator::template rebind< + Leaf>::other::const_pointer + const_leaf_pointer; + + typedef + typename Allocator::template rebind< + Leaf>::other::pointer + leaf_pointer; + + typedef + typename Allocator::template rebind< + Internal_Node>::other::pointer + internal_node_pointer; + + typedef + typename Allocator::template rebind< + Internal_Node>::other::const_pointer + const_internal_node_pointer; + + typedef + typename Allocator::template rebind< + E_Access_Traits>::other::const_pointer + const_e_access_traits_pointer; + + private: + inline typename E_Access_Traits::const_iterator + pref_begin() const + { + if (m_p_nd->m_type == pat_trie_leaf_node_type) + return (m_p_traits->begin( + m_p_traits->extract_key( + static_cast<const_leaf_pointer>(m_p_nd)->value()))); + + _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == pat_trie_internal_node_type); + + return (static_cast<const_internal_node_pointer>(m_p_nd)->pref_b_it()); + } + + inline typename E_Access_Traits::const_iterator + pref_end() const + { + if (m_p_nd->m_type == pat_trie_leaf_node_type) + return (m_p_traits->end( + m_p_traits->extract_key( + static_cast<const_leaf_pointer>(m_p_nd)->value()))); + + _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == pat_trie_internal_node_type); + + return (static_cast<const_internal_node_pointer>(m_p_nd)->pref_e_it()); + } + + public: + + // Size type. + typedef typename Allocator::size_type size_type; + + // Category. + typedef trivial_iterator_tag iterator_category; + + // Difference type. + typedef trivial_iterator_difference_type difference_type; + + // __Iterator's value type. + typedef Const_Iterator value_type; + + // __Iterator's reference type. + typedef value_type reference; + + // __Iterator's __const reference type. + typedef value_type const_reference; + + // Element access traits. + typedef E_Access_Traits e_access_traits; + + // A key's element __const iterator. + typedef typename e_access_traits::const_iterator const_e_iterator; + + // Metadata type. + typedef typename Node::metadata_type metadata_type; + + // Const metadata reference type. + typedef + typename Allocator::template rebind< + metadata_type>::other::const_reference + const_metadata_reference; + + // Default constructor. + /* + inline + pat_trie_const_node_it_() + */ + inline + pat_trie_const_node_it_(node_pointer p_nd = NULL, + const_e_access_traits_pointer p_traits = NULL) + : m_p_nd(const_cast<node_pointer>(p_nd)), m_p_traits(p_traits) + { } + + // Subtree valid prefix. + inline std::pair<const_e_iterator, const_e_iterator> + valid_prefix() const + { return std::make_pair(pref_begin(), pref_end()); } + + // Const access; returns the __const iterator* associated with + // the current leaf. + inline const_reference + operator*() const + { + _GLIBCXX_DEBUG_ASSERT(num_children() == 0); + return Const_Iterator(m_p_nd); + } + + // Metadata access. + inline const_metadata_reference + get_metadata() const + { return m_p_nd->get_metadata(); } + + // Returns the number of children in the corresponding node. + inline size_type + num_children() const + { + if (m_p_nd->m_type == pat_trie_leaf_node_type) + return 0; + _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == pat_trie_internal_node_type); + return std::distance(static_cast<internal_node_pointer>(m_p_nd)->begin(), static_cast<internal_node_pointer>(m_p_nd)->end()); + } + + // Returns a __const node __iterator to the corresponding node's + // i-th child. + PB_DS_PAT_TRIE_CONST_NODE_ITERATOR_C_DEC + get_child(size_type i) const + { + _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == pat_trie_internal_node_type); + typename Internal_Node::iterator it = + static_cast<internal_node_pointer>(m_p_nd)->begin(); + + std::advance(it, i); + return PB_DS_PAT_TRIE_CONST_NODE_ITERATOR_C_DEC(*it, m_p_traits); + } + + // Compares content to a different iterator object. + inline bool + operator==(const PB_DS_PAT_TRIE_CONST_NODE_ITERATOR_C_DEC& other) const + { return (m_p_nd == other.m_p_nd); } + + // Compares content (negatively) to a different iterator object. + inline bool + operator!=(const PB_DS_PAT_TRIE_CONST_NODE_ITERATOR_C_DEC& other) const + { return m_p_nd != other.m_p_nd; } + + private: + + friend class PB_DS_CLASS_C_DEC; + + public: + node_pointer m_p_nd; + + const_e_access_traits_pointer m_p_traits; + }; + + // Node iterator. + template<typename Node, + class Leaf, + class Head, + class Internal_Node, + class Const_Iterator, + class Iterator, + class E_Access_Traits, + class Allocator> + class pat_trie_node_it_ : + public PB_DS_PAT_TRIE_CONST_NODE_ITERATOR_C_DEC + + { + private: + typedef + typename Allocator::template rebind< + Node>::other::pointer + node_pointer; + + typedef Iterator iterator; + + typedef PB_DS_PAT_TRIE_CONST_NODE_ITERATOR_C_DEC base_type; + + typedef + typename base_type::const_e_access_traits_pointer + const_e_access_traits_pointer; + + typedef typename base_type::internal_node_pointer internal_node_pointer; + + public: + + // Size type. + typedef + typename PB_DS_PAT_TRIE_CONST_NODE_ITERATOR_C_DEC::size_type + size_type; + + // __Iterator's value type. + typedef Iterator value_type; + + // __Iterator's reference type. + typedef value_type reference; + + // __Iterator's __const reference type. + typedef value_type const_reference; + + // Default constructor. + /* + inline + pat_trie_node_it_() ; + */ + + inline + pat_trie_node_it_(node_pointer p_nd = NULL, const_e_access_traits_pointer p_traits = NULL) : base_type(p_nd, p_traits) + { } + + // Access; returns the iterator* associated with the current leaf. + inline reference + operator*() const + { + _GLIBCXX_DEBUG_ASSERT(base_type::num_children() == 0); + return Iterator(base_type::m_p_nd); + + } + + // Returns a node __iterator to the corresponding node's i-th child. + PB_DS_PAT_TRIE_NODE_ITERATOR_C_DEC + get_child(size_type i) const + { + _GLIBCXX_DEBUG_ASSERT(base_type::m_p_nd->m_type == pat_trie_internal_node_type); + + typename Internal_Node::iterator it = + static_cast<internal_node_pointer>(base_type::m_p_nd)->begin(); + + std::advance(it, i); + return PB_DS_PAT_TRIE_NODE_ITERATOR_C_DEC(*it, base_type::m_p_traits); + } + + private: + friend class PB_DS_CLASS_C_DEC; + }; + +#undef PB_DS_PAT_TRIE_CONST_NODE_ITERATOR_C_DEC +#undef PB_DS_PAT_TRIE_NODE_ITERATOR_C_DEC + + } // namespace detail +} // namespace pb_ds + +#endif + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/node_metadata_base.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/node_metadata_base.hpp new file mode 100644 index 000000000000..5434ff9d4080 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/node_metadata_base.hpp @@ -0,0 +1,92 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file node_metadata_base.hpp + * Contains an internal PB_DS_BASE_C_DEC for a patricia tree. + */ + +#ifndef PB_DS_PAT_TRIE_NODE_METADATA_BASE_HPP +#define PB_DS_PAT_TRIE_NODE_METADATA_BASE_HPP + +#include <ext/pb_ds/detail/basic_tree_policy/null_node_metadata.hpp> + +namespace pb_ds +{ + namespace detail + { + + template<typename Metadata, class Allocator> + struct pat_trie_node_metadata_base + { + public: + typedef Metadata metadata_type; + + typedef + typename Allocator::template rebind< + metadata_type>::other::const_reference + const_metadata_reference; + + public: + inline const_metadata_reference + get_metadata() const + { + return (m_metadata); + } + + public: + metadata_type m_metadata; + }; + + template<typename Allocator> + struct pat_trie_node_metadata_base< + null_node_metadata, + Allocator> + { + public: + typedef null_node_metadata metadata_type; + }; + + } // namespace detail +} // namespace pb_ds + +#endif // #ifndef PB_DS_PAT_TRIE_NODE_BASE_HPP + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/pat_trie_.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/pat_trie_.hpp new file mode 100644 index 000000000000..cb0a032cb1f5 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/pat_trie_.hpp @@ -0,0 +1,526 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file pat_trie_.hpp + * Contains an implementation class for a patricia tree. + */ + +/** + * This implementation loosely borrows ideas from: + * 1) "Fast Mergeable Integer Maps", Okasaki, Gill 1998 + * 2) "Ptset: Sets of integers implemented as Patricia trees", + * Jean-Christophe Filliatr, 2000 + **/ + +#include <ext/pb_ds/detail/pat_trie_/synth_e_access_traits.hpp> +#include <ext/pb_ds/detail/pat_trie_/node_base.hpp> +#include <ext/pb_ds/exception.hpp> +#include <ext/pb_ds/tag_and_trait.hpp> +#include <ext/pb_ds/detail/eq_fn/eq_by_less.hpp> +#include <ext/pb_ds/detail/types_traits.hpp> +#include <ext/pb_ds/tree_policy.hpp> +#include <ext/pb_ds/detail/cond_dealtor.hpp> +#include <ext/pb_ds/detail/type_utils.hpp> +#include <iterator> +#include <utility> +#include <algorithm> +#include <functional> +#include <assert.h> +#include <list> +#ifdef _GLIBCXX_DEBUG +#include <ext/pb_ds/detail/map_debug_base.hpp> +#endif +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { +#define PB_DS_CLASS_T_DEC \ + template<typename Key, typename Mapped, typename Node_And_It_Traits, \ + typename Allocator> + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_CLASS_NAME pat_trie_data_ +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#define PB_DS_CLASS_NAME pat_trie_no_data_ +#endif + +#define PB_DS_CLASS_C_DEC \ + PB_DS_CLASS_NAME<Key, Mapped, Node_And_It_Traits, Allocator> + +#define PB_DS_TYPES_TRAITS_C_DEC \ + types_traits<Key, Mapped, Allocator, false> + +#ifdef _GLIBCXX_DEBUG +#define PB_DS_MAP_DEBUG_BASE_C_DEC \ + map_debug_base<Key, eq_by_less<Key, \ + std::less<Key> >, typename Allocator::template rebind<Key>::other::const_reference> +#endif + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_V2F(X) (X).first +#define PB_DS_V2S(X) (X).second +#define PB_DS_EP2VP(X)& ((X)->m_value) +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#define PB_DS_V2F(X) (X) +#define PB_DS_V2S(X) Mapped_Data() +#define PB_DS_EP2VP(X)& ((X)->m_value.first) +#endif + +#define PB_DS_STATIC_ASSERT(UNIQUE, E) \ + typedef static_assert_dumclass<sizeof(static_assert<(bool)(E)>)> \ + UNIQUE##static_assert_type + + /** + * class description = PATRICIA trie implementation."> + **/ + template<typename Key, + typename Mapped, + typename Node_And_It_Traits, + typename Allocator> + class PB_DS_CLASS_NAME : +#ifdef _GLIBCXX_DEBUG + public PB_DS_MAP_DEBUG_BASE_C_DEC, +#endif + public Node_And_It_Traits::synth_e_access_traits, + public Node_And_It_Traits::node_update, + public PB_DS_TYPES_TRAITS_C_DEC + { + private: + typedef PB_DS_TYPES_TRAITS_C_DEC traits_base; + + typedef typename Node_And_It_Traits::synth_e_access_traits synth_e_access_traits; + typedef typename Allocator::template rebind<synth_e_access_traits>::other::const_pointer const_e_access_traits_pointer; + typedef typename synth_e_access_traits::const_iterator const_e_iterator; + + typedef typename Node_And_It_Traits::node node; + typedef typename Allocator::template rebind<node>::other::const_pointer const_node_pointer; + + typedef typename Allocator::template rebind<node>::other::pointer node_pointer; + + typedef typename Node_And_It_Traits::head head; + typedef typename Allocator::template rebind<head>::other head_allocator; + typedef typename head_allocator::pointer head_pointer; + + typedef typename Node_And_It_Traits::leaf leaf; + typedef typename Allocator::template rebind<leaf>::other leaf_allocator; + typedef typename leaf_allocator::const_pointer const_leaf_pointer; + typedef typename leaf_allocator::pointer leaf_pointer; + + typedef typename Node_And_It_Traits::internal_node internal_node; + typedef typename Allocator::template rebind<internal_node>::other internal_node_allocator; + typedef typename internal_node_allocator::const_pointer const_internal_node_pointer; + typedef typename internal_node_allocator::pointer internal_node_pointer; + +#include <ext/pb_ds/detail/pat_trie_/cond_dtor_entry_dealtor.hpp> + +#ifdef _GLIBCXX_DEBUG + typedef PB_DS_MAP_DEBUG_BASE_C_DEC map_debug_base; +#endif + +#include <ext/pb_ds/detail/pat_trie_/split_join_branch_bag.hpp> + + typedef typename Node_And_It_Traits::null_node_update_pointer null_node_update_pointer; + + public: + typedef pat_trie_tag container_category; + typedef Allocator allocator; + typedef typename Allocator::size_type size_type; + typedef typename Allocator::difference_type difference_type; + + typedef typename traits_base::key_type key_type; + typedef typename traits_base::key_pointer key_pointer; + typedef typename traits_base::const_key_pointer const_key_pointer; + typedef typename traits_base::key_reference key_reference; + typedef typename traits_base::const_key_reference const_key_reference; + typedef typename traits_base::mapped_type mapped_type; + typedef typename traits_base::mapped_pointer mapped_pointer; + typedef typename traits_base::const_mapped_pointer const_mapped_pointer; + typedef typename traits_base::mapped_reference mapped_reference; + typedef typename traits_base::const_mapped_reference const_mapped_reference; + typedef typename traits_base::value_type value_type; + typedef typename traits_base::pointer pointer; + typedef typename traits_base::const_pointer const_pointer; + typedef typename traits_base::reference reference; + typedef typename traits_base::const_reference const_reference; + + typedef typename Node_And_It_Traits::const_iterator const_point_iterator; + typedef typename Node_And_It_Traits::iterator point_iterator; + typedef const_point_iterator const_iterator; + typedef point_iterator iterator; + + typedef typename Node_And_It_Traits::const_reverse_iterator const_reverse_iterator; + typedef typename Node_And_It_Traits::reverse_iterator reverse_iterator; + typedef typename Node_And_It_Traits::const_node_iterator const_node_iterator; + typedef typename Node_And_It_Traits::node_iterator node_iterator; + typedef typename Node_And_It_Traits::e_access_traits e_access_traits; + typedef typename Node_And_It_Traits::node_update node_update; + + PB_DS_CLASS_NAME(); + + PB_DS_CLASS_NAME(const e_access_traits&); + + PB_DS_CLASS_NAME(const PB_DS_CLASS_C_DEC&); + + void + swap(PB_DS_CLASS_C_DEC&); + + ~PB_DS_CLASS_NAME(); + + inline bool + empty() const; + + inline size_type + size() const; + + inline size_type + max_size() const; + + e_access_traits& + get_e_access_traits(); + + const e_access_traits& + get_e_access_traits() const; + + node_update& + get_node_update(); + + const node_update& + get_node_update() const; + + inline std::pair<point_iterator, bool> + insert(const_reference); + + inline mapped_reference + operator[](const_key_reference r_key) + { +#ifdef PB_DS_DATA_TRUE_INDICATOR + return insert(std::make_pair(r_key, mapped_type())).first->second; +#else + insert(r_key); + return traits_base::s_null_mapped; +#endif + } + + inline point_iterator + find(const_key_reference); + + inline const_point_iterator + find(const_key_reference) const; + + inline point_iterator + lower_bound(const_key_reference); + + inline const_point_iterator + lower_bound(const_key_reference) const; + + inline point_iterator + upper_bound(const_key_reference); + + inline const_point_iterator + upper_bound(const_key_reference) const; + + void + clear(); + + inline bool + erase(const_key_reference); + + inline const_iterator + erase(const_iterator); + +#ifdef PB_DS_DATA_TRUE_INDICATOR + inline iterator + erase(iterator); +#endif + + inline const_reverse_iterator + erase(const_reverse_iterator); + +#ifdef PB_DS_DATA_TRUE_INDICATOR + inline reverse_iterator + erase(reverse_iterator); +#endif + + template<typename Pred> + inline size_type + erase_if(Pred); + + void + join(PB_DS_CLASS_C_DEC&); + + void + split(const_key_reference, PB_DS_CLASS_C_DEC&); + + inline iterator + begin(); + + inline const_iterator + begin() const; + + inline iterator + end(); + + inline const_iterator + end() const; + + inline reverse_iterator + rbegin(); + + inline const_reverse_iterator + rbegin() const; + + inline reverse_iterator + rend(); + + inline const_reverse_iterator + rend() const; + + inline const_node_iterator + node_begin() const; + + inline node_iterator + node_begin(); + + inline const_node_iterator + node_end() const; + + inline node_iterator + node_end(); + +#ifdef PB_DS_PAT_TRIE_TRACE_ + void + trace() const; +#endif + + protected: + + template<typename It> + void + copy_from_range(It, It); + + void + value_swap(PB_DS_CLASS_C_DEC&); + + node_pointer + recursive_copy_node(const_node_pointer); + + private: + + void + initialize(); + + inline void + apply_update(node_pointer, null_node_update_pointer); + + template<typename Node_Update_> + inline void + apply_update(node_pointer, Node_Update_*); + + bool + join_prep(PB_DS_CLASS_C_DEC&, split_join_branch_bag&); + + void + rec_join_prep(const_node_pointer, const_node_pointer, + split_join_branch_bag&); + + void + rec_join_prep(const_leaf_pointer, const_leaf_pointer, + split_join_branch_bag&); + + void + rec_join_prep(const_leaf_pointer, const_internal_node_pointer, + split_join_branch_bag&); + + void + rec_join_prep(const_internal_node_pointer, const_leaf_pointer, + split_join_branch_bag&); + + void + rec_join_prep(const_internal_node_pointer, const_internal_node_pointer, + split_join_branch_bag&); + + node_pointer + rec_join(node_pointer, node_pointer, size_type, split_join_branch_bag&); + + node_pointer + rec_join(leaf_pointer, leaf_pointer, split_join_branch_bag&); + + node_pointer + rec_join(leaf_pointer, internal_node_pointer, size_type, + split_join_branch_bag&); + + node_pointer + rec_join(internal_node_pointer, leaf_pointer, size_type, + split_join_branch_bag&); + + node_pointer + rec_join(internal_node_pointer, internal_node_pointer, + split_join_branch_bag&); + + size_type + keys_diff_ind(typename e_access_traits::const_iterator, typename e_access_traits::const_iterator, typename e_access_traits::const_iterator, typename e_access_traits::const_iterator); + + internal_node_pointer + insert_branch(node_pointer, node_pointer, split_join_branch_bag&); + + void + update_min_max_for_inserted_leaf(leaf_pointer); + + void + erase_leaf(leaf_pointer); + + inline void + actual_erase_leaf(leaf_pointer); + + void + clear_imp(node_pointer); + + void + erase_fixup(internal_node_pointer); + + void + update_min_max_for_erased_leaf(leaf_pointer); + + static inline const_e_iterator + pref_begin(const_node_pointer); + + static inline const_e_iterator + pref_end(const_node_pointer); + + inline node_pointer + find_imp(const_key_reference); + + inline node_pointer + lower_bound_imp(const_key_reference); + + inline node_pointer + upper_bound_imp(const_key_reference); + + inline static const_leaf_pointer + leftmost_descendant(const_node_pointer); + + inline static leaf_pointer + leftmost_descendant(node_pointer); + + inline static const_leaf_pointer + rightmost_descendant(const_node_pointer); + + inline static leaf_pointer + rightmost_descendant(node_pointer); + +#ifdef _GLIBCXX_DEBUG + void + assert_valid() const; + + void + assert_iterators() const; + + void + assert_reverse_iterators() const; + + static size_type + recursive_count_leafs(const_node_pointer); +#endif + +#ifdef PB_DS_PAT_TRIE_TRACE_ + static void + trace_node(const_node_pointer, size_type); + + template<typename Metadata_> + static void + trace_node_metadata(const_node_pointer, type_to_type<Metadata_>); + + static void + trace_node_metadata(const_node_pointer, type_to_type<null_node_metadata>); +#endif + + leaf_pointer + split_prep(const_key_reference, PB_DS_CLASS_C_DEC&, + split_join_branch_bag&); + + node_pointer + rec_split(node_pointer, const_e_iterator, const_e_iterator, + PB_DS_CLASS_C_DEC&, split_join_branch_bag&); + + void + split_insert_branch(size_type, const_e_iterator, + typename internal_node::iterator, + size_type, split_join_branch_bag&); + + static head_allocator s_head_allocator; + static internal_node_allocator s_internal_node_allocator; + static leaf_allocator s_leaf_allocator; + + head_pointer m_p_head; + size_type m_size; + }; + +#include <ext/pb_ds/detail/pat_trie_/constructors_destructor_fn_imps.hpp> +#include <ext/pb_ds/detail/pat_trie_/iterators_fn_imps.hpp> +#include <ext/pb_ds/detail/pat_trie_/insert_join_fn_imps.hpp> +#include <ext/pb_ds/detail/pat_trie_/erase_fn_imps.hpp> +#include <ext/pb_ds/detail/pat_trie_/find_fn_imps.hpp> +#include <ext/pb_ds/detail/pat_trie_/info_fn_imps.hpp> +#include <ext/pb_ds/detail/pat_trie_/policy_access_fn_imps.hpp> +#include <ext/pb_ds/detail/pat_trie_/split_fn_imps.hpp> +#include <ext/pb_ds/detail/pat_trie_/debug_fn_imps.hpp> +#include <ext/pb_ds/detail/pat_trie_/trace_fn_imps.hpp> +#include <ext/pb_ds/detail/pat_trie_/update_fn_imps.hpp> + +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_NAME +#undef PB_DS_TYPES_TRAITS_C_DEC +#undef PB_DS_MAP_DEBUG_BASE_C_DEC +#undef PB_DS_V2F +#undef PB_DS_EP2VP +#undef PB_DS_V2S +#undef PB_DS_STATIC_ASSERT + + } // namespace detail +} // namespace pb_ds diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/point_iterators.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/point_iterators.hpp new file mode 100644 index 000000000000..1a42dc562f2b --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/point_iterators.hpp @@ -0,0 +1,490 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file point_iterators.hpp + * Contains an implementation class for bin_search_tree_. + */ + +#ifndef PB_DS_PAT_TRIE_FIND_ITERATORS_HPP +#define PB_DS_PAT_TRIE_FIND_ITERATORS_HPP + +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_CONST_IT_C_DEC \ + pat_trie_const_it_< \ + Type_Traits, \ + Node, \ + Leaf, \ + Head, \ + Internal_Node, \ + Is_Forward_Iterator, \ + Allocator> + +#define PB_DS_CONST_ODIR_IT_C_DEC \ + pat_trie_const_it_< \ + Type_Traits, \ + Node, \ + Leaf, \ + Head, \ + Internal_Node, \ + !Is_Forward_Iterator, \ + Allocator> + +#define PB_DS_IT_C_DEC \ + pat_trie_it_< \ + Type_Traits, \ + Node, \ + Leaf, \ + Head, \ + Internal_Node, \ + Is_Forward_Iterator, \ + Allocator> + +#define PB_DS_ODIR_IT_C_DEC \ + pat_trie_it_< \ + Type_Traits, \ + Node, \ + Leaf, \ + Head, \ + Internal_Node, \ + !Is_Forward_Iterator, \ + Allocator> + + + // Const iterator. + template<typename Type_Traits, + class Node, + class Leaf, + class Head, + class Internal_Node, + bool Is_Forward_Iterator, + class Allocator> + class pat_trie_const_it_ + { + + private: + typedef + typename Allocator::template rebind< + Node>::other::pointer + node_pointer; + + typedef + typename Allocator::template rebind< + Leaf>::other::const_pointer + const_leaf_pointer; + + typedef + typename Allocator::template rebind< + Leaf>::other::pointer + leaf_pointer; + + typedef + typename Allocator::template rebind< + Head>::other::pointer + head_pointer; + + typedef + typename Allocator::template rebind< + Internal_Node>::other::pointer + internal_node_pointer; + + public: + + typedef std::bidirectional_iterator_tag iterator_category; + + typedef typename Allocator::difference_type difference_type; + + typedef typename Type_Traits::value_type value_type; + + typedef typename Type_Traits::pointer pointer; + + typedef typename Type_Traits::const_pointer const_pointer; + + typedef typename Type_Traits::reference reference; + + typedef typename Type_Traits::const_reference const_reference; + + public: + + inline + pat_trie_const_it_(node_pointer p_nd = NULL) : m_p_nd(p_nd) + { } + + inline + pat_trie_const_it_(const PB_DS_CONST_ODIR_IT_C_DEC& other) + : m_p_nd(other.m_p_nd) + { } + + inline + PB_DS_CONST_IT_C_DEC& + operator=(const PB_DS_CONST_IT_C_DEC& other) + { + m_p_nd = other.m_p_nd; + return *this; + } + + inline + PB_DS_CONST_IT_C_DEC& + operator=(const PB_DS_CONST_ODIR_IT_C_DEC& other) + { + m_p_nd = other.m_p_nd; + return *this; + } + + inline const_pointer + operator->() const + { + _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == pat_trie_leaf_node_type); + return &static_cast<leaf_pointer>(m_p_nd)->value(); + } + + inline const_reference + operator*() const + { + _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == pat_trie_leaf_node_type); + return static_cast<leaf_pointer>(m_p_nd)->value(); + } + + inline bool + operator==(const PB_DS_CONST_IT_C_DEC& other) const + { return (m_p_nd == other.m_p_nd); } + + inline bool + operator==(const PB_DS_CONST_ODIR_IT_C_DEC& other) const + { return (m_p_nd == other.m_p_nd); } + + inline bool + operator!=(const PB_DS_CONST_IT_C_DEC& other) const + { return (m_p_nd != other.m_p_nd); } + + inline bool + operator!=(const PB_DS_CONST_ODIR_IT_C_DEC& other) const + { return (m_p_nd != other.m_p_nd); } + + inline PB_DS_CONST_IT_C_DEC& + operator++() + { + inc(integral_constant<int,Is_Forward_Iterator>()); + return *this; + } + + inline PB_DS_CONST_IT_C_DEC + operator++(int) + { + PB_DS_CONST_IT_C_DEC ret_it(m_p_nd); + operator++(); + return ret_it; + } + + inline PB_DS_CONST_IT_C_DEC& + operator--() + { + dec(integral_constant<int,Is_Forward_Iterator>()); + return *this; + } + + inline PB_DS_CONST_IT_C_DEC + operator--(int) + { + PB_DS_CONST_IT_C_DEC ret_it(m_p_nd); + operator--(); + return ret_it; + } + + protected: + inline void + inc(false_type) + { dec(true_type()); } + + void + inc(true_type) + { + if (m_p_nd->m_type == pat_trie_head_node_type) + { + m_p_nd = static_cast<head_pointer>(m_p_nd)->m_p_min; + return; + } + + node_pointer p_y = m_p_nd->m_p_parent; + while (p_y->m_type != pat_trie_head_node_type && + get_larger_sibling(m_p_nd) == NULL) + { + m_p_nd = p_y; + p_y = p_y->m_p_parent; + } + + if (p_y->m_type == pat_trie_head_node_type) + { + m_p_nd = p_y; + return; + } + m_p_nd = leftmost_descendant(get_larger_sibling(m_p_nd)); + } + + inline void + dec(false_type) + { inc(true_type()); } + + void + dec(true_type) + { + if (m_p_nd->m_type == pat_trie_head_node_type) + { + m_p_nd = static_cast<head_pointer>(m_p_nd)->m_p_max; + return; + } + + node_pointer p_y = m_p_nd->m_p_parent; + while (p_y->m_type != pat_trie_head_node_type && + get_smaller_sibling(m_p_nd) == NULL) + { + m_p_nd = p_y; + p_y = p_y->m_p_parent; + } + + if (p_y->m_type == pat_trie_head_node_type) + { + m_p_nd = p_y; + return; + } + m_p_nd = rightmost_descendant(get_smaller_sibling(m_p_nd)); + } + + inline static node_pointer + get_larger_sibling(node_pointer p_nd) + { + internal_node_pointer p_parent = + static_cast<internal_node_pointer>(p_nd->m_p_parent); + + typename Internal_Node::iterator it = p_parent->begin(); + while (*it != p_nd) + ++it; + + typename Internal_Node::iterator next_it = it; + ++next_it; + return ((next_it == p_parent->end())? NULL :* next_it); + } + + inline static node_pointer + get_smaller_sibling(node_pointer p_nd) + { + internal_node_pointer p_parent = + static_cast<internal_node_pointer>(p_nd->m_p_parent); + + typename Internal_Node::iterator it = p_parent->begin(); + + if (*it == p_nd) + return (NULL); + typename Internal_Node::iterator prev_it; + do + { + prev_it = it; + ++it; + if (*it == p_nd) + return (*prev_it); + } + while (true); + + _GLIBCXX_DEBUG_ASSERT(false); + return (NULL); + } + + inline static leaf_pointer + leftmost_descendant(node_pointer p_nd) + { + if (p_nd->m_type == pat_trie_leaf_node_type) + return static_cast<leaf_pointer>(p_nd); + return static_cast<internal_node_pointer>(p_nd)->leftmost_descendant(); + } + + inline static leaf_pointer + rightmost_descendant(node_pointer p_nd) + { + if (p_nd->m_type == pat_trie_leaf_node_type) + return static_cast<leaf_pointer>(p_nd); + return static_cast<internal_node_pointer>(p_nd)->rightmost_descendant(); + } + + public: + node_pointer m_p_nd; + }; + + // Iterator. + template<typename Type_Traits, + class Node, + class Leaf, + class Head, + class Internal_Node, + bool Is_Forward_Iterator, + class Allocator> + class pat_trie_it_ : + public PB_DS_CONST_IT_C_DEC + + { + private: + typedef + typename Allocator::template rebind< + Node>::other::pointer + node_pointer; + + typedef + typename Allocator::template rebind< + Leaf>::other::const_pointer + const_leaf_pointer; + + typedef + typename Allocator::template rebind< + Leaf>::other::pointer + leaf_pointer; + + typedef + typename Allocator::template rebind< + Head>::other::pointer + head_pointer; + + typedef + typename Allocator::template rebind< + Internal_Node>::other::pointer + internal_node_pointer; + + public: + typedef typename Type_Traits::value_type value_type; + + typedef typename Type_Traits::const_pointer const_pointer; + + typedef typename Type_Traits::pointer pointer; + + typedef typename Type_Traits::const_reference const_reference; + + typedef typename Type_Traits::reference reference; + + inline + pat_trie_it_(node_pointer p_nd = NULL) : PB_DS_CONST_IT_C_DEC((node_pointer)p_nd) + { } + + inline + pat_trie_it_(const PB_DS_ODIR_IT_C_DEC& other) : PB_DS_CONST_IT_C_DEC(other.m_p_nd) + { } + + inline + PB_DS_IT_C_DEC& + operator=(const PB_DS_IT_C_DEC& other) + { + base_it_type::m_p_nd = other.m_p_nd; + return *this; + } + + inline + PB_DS_IT_C_DEC& + operator=(const PB_DS_ODIR_IT_C_DEC& other) + { + base_it_type::m_p_nd = other.m_p_nd; + return *this; + } + + inline pointer + operator->() const + { + _GLIBCXX_DEBUG_ASSERT(base_it_type::m_p_nd->m_type == pat_trie_leaf_node_type); + + return &static_cast<leaf_pointer>(base_it_type::m_p_nd)->value(); + } + + inline reference + operator*() const + { + _GLIBCXX_DEBUG_ASSERT(base_it_type::m_p_nd->m_type == pat_trie_leaf_node_type); + return static_cast<leaf_pointer>(base_it_type::m_p_nd)->value(); + } + + inline PB_DS_IT_C_DEC& + operator++() + { + PB_DS_CONST_IT_C_DEC:: + operator++(); + return *this; + } + + inline PB_DS_IT_C_DEC + operator++(int) + { + PB_DS_IT_C_DEC ret_it(base_it_type::m_p_nd); + operator++(); + return ret_it; + } + + inline PB_DS_IT_C_DEC& + operator--() + { + PB_DS_CONST_IT_C_DEC::operator--(); + return *this; + } + + inline PB_DS_IT_C_DEC + operator--(int) + { + PB_DS_IT_C_DEC ret_it(base_it_type::m_p_nd); + operator--(); + return ret_it; + } + + protected: + typedef PB_DS_CONST_IT_C_DEC base_it_type; + + friend class PB_DS_CLASS_C_DEC; + }; + +#undef PB_DS_CONST_IT_C_DEC +#undef PB_DS_CONST_ODIR_IT_C_DEC +#undef PB_DS_IT_C_DEC +#undef PB_DS_ODIR_IT_C_DEC + + } // namespace detail +} // namespace pb_ds + +#endif + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/policy_access_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/policy_access_fn_imps.hpp new file mode 100644 index 000000000000..7c6eb0f3de8e --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/policy_access_fn_imps.hpp @@ -0,0 +1,69 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file policy_access_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::e_access_traits& +PB_DS_CLASS_C_DEC:: +get_e_access_traits() +{ return *this; } + +PB_DS_CLASS_T_DEC +const typename PB_DS_CLASS_C_DEC::e_access_traits& +PB_DS_CLASS_C_DEC:: +get_e_access_traits() const +{ return *this; } + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::node_update& +PB_DS_CLASS_C_DEC:: +get_node_update() +{ return *this; } + +PB_DS_CLASS_T_DEC +const typename PB_DS_CLASS_C_DEC::node_update& +PB_DS_CLASS_C_DEC:: +get_node_update() const +{ return *this; } diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/r_erase_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/r_erase_fn_imps.hpp new file mode 100644 index 000000000000..63553ec92a4b --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/r_erase_fn_imps.hpp @@ -0,0 +1,109 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file r_erase_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +actual_erase_node(node_pointer p_z) +{ + _GLIBCXX_DEBUG_ASSERT(m_size > 0); + --m_size; + _GLIBCXX_DEBUG_ONLY(erase_existing(PB_DS_V2F(p_z->m_value))); + p_z->~node(); + s_node_allocator.deallocate(p_z, 1); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +update_min_max_for_erased_node(node_pointer p_z) +{ + if (m_size == 1) + { + m_p_head->m_p_left = m_p_head->m_p_right = m_p_head; + return; + } + + if (m_p_head->m_p_left == p_z) + { + iterator it(p_z); + ++it; + m_p_head->m_p_left = it.m_p_nd; + } + else if (m_p_head->m_p_right == p_z) + { + iterator it(p_z); + --it; + m_p_head->m_p_right = it.m_p_nd; + } +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +clear() +{ + _GLIBCXX_DEBUG_ONLY(assert_valid(true, true);) + clear_imp(m_p_head->m_p_parent); + m_size = 0; + initialize(); + _GLIBCXX_DEBUG_ONLY(map_debug_base::clear();) + _GLIBCXX_DEBUG_ONLY(assert_valid(true, true);) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +clear_imp(node_pointer p_nd) +{ + if (p_nd == NULL) + return; + clear_imp(p_nd->m_p_left); + clear_imp(p_nd->m_p_right); + p_nd->~Node(); + s_node_allocator.deallocate(p_nd, 1); +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/rotate_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/rotate_fn_imps.hpp new file mode 100644 index 000000000000..84e6fddc088f --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/rotate_fn_imps.hpp @@ -0,0 +1,156 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file rotate_fn_imps.hpp + * Contains imps for rotating nodes. + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +rotate_left(node_pointer p_x) +{ + node_pointer p_y = p_x->m_p_right; + p_x->m_p_right = p_y->m_p_left; + + if (p_y->m_p_left != NULL) + p_y->m_p_left->m_p_parent = p_x; + + p_y->m_p_parent = p_x->m_p_parent; + if (p_x == m_p_head->m_p_parent) + m_p_head->m_p_parent = p_y; + else if (p_x == p_x->m_p_parent->m_p_left) + p_x->m_p_parent->m_p_left = p_y; + else + p_x->m_p_parent->m_p_right = p_y; + + p_y->m_p_left = p_x; + p_x->m_p_parent = p_y; + + _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_x);) + _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_y);) + + apply_update(p_x, (Node_Update* )this); + apply_update(p_x->m_p_parent, (Node_Update* )this); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +rotate_right(node_pointer p_x) +{ + node_pointer p_y = p_x->m_p_left; + p_x->m_p_left = p_y->m_p_right; + + if (p_y->m_p_right != NULL) + p_y->m_p_right->m_p_parent = p_x; + + p_y->m_p_parent = p_x->m_p_parent; + if (p_x == m_p_head->m_p_parent) + m_p_head->m_p_parent = p_y; + else if (p_x == p_x->m_p_parent->m_p_right) + p_x->m_p_parent->m_p_right = p_y; + else + p_x->m_p_parent->m_p_left = p_y; + + p_y->m_p_right = p_x; + p_x->m_p_parent = p_y; + + _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_x);) + _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_y);) + + apply_update(p_x, (Node_Update* )this); + apply_update(p_x->m_p_parent, (Node_Update* )this); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +rotate_parent(node_pointer p_nd) +{ + node_pointer p_parent = p_nd->m_p_parent; + if (p_nd == p_parent->m_p_left) + rotate_right(p_parent); + else + rotate_left(p_parent); + _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_parent = p_nd); + _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_left == p_parent || p_nd->m_p_right == p_parent); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +apply_update(node_pointer /*p_nd*/, pb_ds::null_node_update* /*p_update*/) +{ } + +PB_DS_CLASS_T_DEC +template<typename Node_Update_> +inline void +PB_DS_CLASS_C_DEC:: +apply_update(node_pointer p_nd, Node_Update_* p_update) +{ + p_update->operator()(& PB_DS_V2F(p_nd->m_value),(p_nd->m_p_left == NULL) ? + NULL : + & PB_DS_V2F(p_nd->m_p_left->m_value),(p_nd->m_p_right == NULL) ? + NULL : + & PB_DS_V2F(p_nd->m_p_right->m_value)); +} + +PB_DS_CLASS_T_DEC +template<typename Node_Update_> +inline void +PB_DS_CLASS_C_DEC:: +update_to_top(node_pointer p_nd, Node_Update_* p_update) +{ + while (p_nd != m_p_head) + { + apply_update(p_nd, p_update); + p_nd = p_nd->m_p_parent; + } +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +update_to_top(node_pointer /*p_nd*/, pb_ds::null_node_update* /*p_update*/) +{ } + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/split_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/split_fn_imps.hpp new file mode 100644 index 000000000000..ed5d890f6f2c --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/split_fn_imps.hpp @@ -0,0 +1,260 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file split_fn_imps.hpp + * Contains an implementation class for bin_search_tree_. + */ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +split(const_key_reference r_key, PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();); + _GLIBCXX_DEBUG_ONLY(other.assert_valid();); + split_join_branch_bag bag; + leaf_pointer p_split_lf = split_prep(r_key, other, bag); + if (p_split_lf == NULL) + { + _GLIBCXX_DEBUG_ASSERT(bag.empty()); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + return; + } + + _GLIBCXX_DEBUG_ASSERT(!bag.empty()); + other.clear(); + m_p_head->m_p_parent = rec_split(m_p_head->m_p_parent, + pref_begin(p_split_lf), + pref_end(p_split_lf), + other, + bag); + + m_p_head->m_p_parent->m_p_parent = m_p_head; + + other.m_p_head->m_p_max = m_p_head->m_p_max; + m_p_head->m_p_max = rightmost_descendant(m_p_head->m_p_parent); + other.m_p_head->m_p_min = + other.leftmost_descendant(other.m_p_head->m_p_parent); + + other.m_size = std::distance(other.PB_DS_CLASS_C_DEC::begin(), + other.PB_DS_CLASS_C_DEC::end()); + m_size -= other.m_size; + _GLIBCXX_DEBUG_ONLY(assert_valid();); + _GLIBCXX_DEBUG_ONLY(other.assert_valid();); +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::leaf_pointer +PB_DS_CLASS_C_DEC:: +split_prep(const_key_reference r_key, PB_DS_CLASS_C_DEC& other, split_join_branch_bag& r_bag) +{ + _GLIBCXX_DEBUG_ASSERT(r_bag.empty()); + if (m_size == 0) + { + other.clear(); + _GLIBCXX_DEBUG_ONLY(assert_valid();); + _GLIBCXX_DEBUG_ONLY(other.assert_valid();); + return (NULL); + } + + if (synth_e_access_traits::cmp_keys(r_key, + PB_DS_V2F(static_cast<const_leaf_pointer>(m_p_head->m_p_min)->value()))) + { + other.clear(); + value_swap(other); + _GLIBCXX_DEBUG_ONLY(assert_valid();); + _GLIBCXX_DEBUG_ONLY(other.assert_valid();); + return (NULL); + } + + if (!synth_e_access_traits::cmp_keys(r_key, + PB_DS_V2F(static_cast<const_leaf_pointer>(m_p_head->m_p_max)->value()))) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();); + _GLIBCXX_DEBUG_ONLY(other.assert_valid();); + return (NULL); + } + + iterator it = lower_bound(r_key); + + if (!synth_e_access_traits::equal_keys(PB_DS_V2F(*it), r_key)) + --it; + + node_pointer p_nd = it.m_p_nd; + _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == pat_trie_leaf_node_type); + leaf_pointer p_ret_l = static_cast<leaf_pointer>(p_nd); + while (p_nd->m_type != pat_trie_head_node_type) + { + r_bag.add_branch(); + p_nd = p_nd->m_p_parent; + } + _GLIBCXX_DEBUG_ONLY(map_debug_base::split(r_key,(synth_e_access_traits& )(*this), other);) + + return (p_ret_l); +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +rec_split(node_pointer p_nd, const_e_iterator b_it, const_e_iterator e_it, PB_DS_CLASS_C_DEC& other, split_join_branch_bag& r_bag) +{ + if (p_nd->m_type == pat_trie_leaf_node_type) + { + _GLIBCXX_DEBUG_ASSERT(other.m_p_head->m_p_parent == NULL); + return (p_nd); + } + + _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == pat_trie_internal_node_type); + internal_node_pointer p_internal_nd = static_cast<internal_node_pointer>(p_nd); + + node_pointer p_child_ret = rec_split(p_internal_nd->get_child_node(b_it, e_it, this), b_it, e_it, other, r_bag); + + _GLIBCXX_DEBUG_ONLY(p_child_ret->assert_valid(this);) + p_internal_nd->replace_child(p_child_ret, b_it, e_it, this); + apply_update(p_internal_nd, (node_update* )this); + + typename internal_node::iterator child_it = + p_internal_nd->get_child_it(b_it, e_it, this); + + const size_type lhs_num_children = + std::distance(p_internal_nd->begin(), child_it) + 1; + + _GLIBCXX_DEBUG_ASSERT(lhs_num_children > 0); + + size_type rhs_num_children = + std::distance(p_internal_nd->begin(), p_internal_nd->end()) - + lhs_num_children; + + if (rhs_num_children == 0) + { + apply_update(p_internal_nd, (node_update* )this); + return (p_internal_nd); + } + + ++child_it; + other.split_insert_branch(p_internal_nd->get_e_ind(), + b_it, child_it, rhs_num_children, r_bag); + + child_it = p_internal_nd->get_child_it(b_it, e_it, this); + ++child_it; + while (rhs_num_children != 0) + { + child_it = p_internal_nd->remove_child(child_it); + --rhs_num_children; + } + + apply_update(p_internal_nd, (node_update* )this); + _GLIBCXX_DEBUG_ASSERT(std::distance(p_internal_nd->begin(), + p_internal_nd->end()) >= 1); + + if (std::distance(p_internal_nd->begin(), p_internal_nd->end()) > 1) + { + p_internal_nd->update_prefixes(this); + _GLIBCXX_DEBUG_ONLY(p_internal_nd->assert_valid(this);) + apply_update(p_internal_nd, (node_update* )this); + return (p_internal_nd); + } + + node_pointer p_ret =* p_internal_nd->begin(); + p_internal_nd->~internal_node(); + s_internal_node_allocator.deallocate(p_internal_nd, 1); + apply_update(p_ret, (node_update* )this); + return (p_ret); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +split_insert_branch(size_type e_ind, const_e_iterator b_it, typename internal_node::iterator child_b_it, size_type num_children, split_join_branch_bag& r_bag) +{ +#ifdef _GLIBCXX_DEBUG + if (m_p_head->m_p_parent != NULL) + m_p_head->m_p_parent->assert_valid(this); +#endif + + const size_type total_num_children =((m_p_head->m_p_parent == NULL)? 0 : 1) + num_children; + + if (total_num_children == 0) + { + _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_parent == NULL); + return; + } + + if (total_num_children == 1) + { + if (m_p_head->m_p_parent != NULL) + { + _GLIBCXX_DEBUG_ONLY(m_p_head->m_p_parent->assert_valid(this);) + return; + } + + _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_parent == NULL); + m_p_head->m_p_parent =* child_b_it; + m_p_head->m_p_parent->m_p_parent = m_p_head; + apply_update(m_p_head->m_p_parent, (node_update* )this); + _GLIBCXX_DEBUG_ONLY(m_p_head->m_p_parent->assert_valid(this);) + return; + } + + _GLIBCXX_DEBUG_ASSERT(total_num_children > 1); + internal_node_pointer p_new_root = r_bag.get_branch(); + new (p_new_root) internal_node(e_ind, b_it); + size_type num_inserted = 0; + while (num_inserted++ < num_children) + { + _GLIBCXX_DEBUG_ONLY((*child_b_it)->assert_valid(this);) + p_new_root->add_child(*child_b_it, pref_begin(*child_b_it), + pref_end(*child_b_it), this); + ++child_b_it; + } + + if (m_p_head->m_p_parent != NULL) + p_new_root->add_child(m_p_head->m_p_parent, + pref_begin(m_p_head->m_p_parent), + pref_end(m_p_head->m_p_parent), this); + + m_p_head->m_p_parent = p_new_root; + p_new_root->m_p_parent = m_p_head; + apply_update(m_p_head->m_p_parent, (node_update* )this); + _GLIBCXX_DEBUG_ONLY(m_p_head->m_p_parent->assert_valid(this);) +} diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/split_join_branch_bag.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/split_join_branch_bag.hpp new file mode 100644 index 000000000000..bf04cb4ab7cb --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/split_join_branch_bag.hpp @@ -0,0 +1,99 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file split_join_branch_bag.hpp + * Contains an implementation class for pat_trie_. + */ + +class split_join_branch_bag +{ +private: + typedef + std::list< + internal_node_pointer, + typename Allocator::template rebind< + internal_node_pointer>::other> + bag_t; + +public: + + void + add_branch() + { + internal_node_pointer p_nd = s_internal_node_allocator.allocate(1); + try + { + m_bag.push_back(p_nd); + } + catch(...) + { + s_internal_node_allocator.deallocate(p_nd, 1); + __throw_exception_again; + } + } + + internal_node_pointer + get_branch() + { + _GLIBCXX_DEBUG_ASSERT(!m_bag.empty()); + internal_node_pointer p_nd =* m_bag.begin(); + m_bag.pop_front(); + return p_nd; + } + + ~split_join_branch_bag() + { + while (!m_bag.empty()) + { + internal_node_pointer p_nd =* m_bag.begin(); + s_internal_node_allocator.deallocate(p_nd, 1); + m_bag.pop_front(); + } + } + + inline bool + empty() const + { return m_bag.empty(); } + +private: + bag_t m_bag; +}; diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/synth_e_access_traits.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/synth_e_access_traits.hpp new file mode 100644 index 000000000000..79cd72cba2bd --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/synth_e_access_traits.hpp @@ -0,0 +1,235 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file synth_e_access_traits.hpp + * Contains an implementation class for a patricia tree. + */ + +#ifndef PB_DS_SYNTH_E_ACCESS_TRAITS_HPP +#define PB_DS_SYNTH_E_ACCESS_TRAITS_HPP + +#include <ext/pb_ds/detail/type_utils.hpp> + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC \ + template<typename Type_Traits, bool Set, class E_Access_Traits> + +#define PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC \ + synth_e_access_traits< \ + Type_Traits, \ + Set, \ + E_Access_Traits> + + template<typename Type_Traits, bool Set, class E_Access_Traits> + struct synth_e_access_traits : public E_Access_Traits + { + + private: + typedef E_Access_Traits base_type; + + typedef Type_Traits type_traits; + + typedef typename type_traits::const_key_reference const_key_reference; + + typedef typename type_traits::const_reference const_reference; + + public: + synth_e_access_traits(); + + synth_e_access_traits(const E_Access_Traits& r_traits); + + inline bool + equal_prefixes(typename base_type::const_iterator b_l, typename base_type::const_iterator e_l, typename base_type::const_iterator b_r, typename base_type::const_iterator e_r, bool compare_after = true) const; + + bool + equal_keys(const_key_reference r_lhs_key, const_key_reference r_rhs_key) const; + + bool + cmp_prefixes(typename base_type::const_iterator b_l, typename base_type::const_iterator e_l, typename base_type::const_iterator b_r, typename base_type::const_iterator e_r, bool compare_after = false) const; + + bool + cmp_keys(const_key_reference r_lhs_key, const_key_reference r_rhs_key) const; + + inline static const_key_reference + extract_key(const_reference r_val); + +#ifdef _GLIBCXX_DEBUG + bool + operator()(const_key_reference r_lhs, const_key_reference r_rhs); +#endif + + private: + inline static const_key_reference + extract_key(const_reference r_val, true_type); + + inline static const_key_reference + extract_key(const_reference r_val, false_type); + + private: + static integral_constant<int,Set> s_set_ind; + }; + + PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC + integral_constant<int,Set> + PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC::s_set_ind; + + PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC + PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: + synth_e_access_traits() + { } + + PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC + PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: + synth_e_access_traits(const E_Access_Traits& r_traits) : + E_Access_Traits(r_traits) + { } + + PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC + inline bool + PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: + equal_prefixes(typename base_type::const_iterator b_l, typename base_type::const_iterator e_l, typename base_type::const_iterator b_r, typename base_type::const_iterator e_r, bool compare_after /*= false */) const + { + while (b_l != e_l) + { + if (b_r == e_r) + return (false); + if (base_type::e_pos(*b_l) != base_type::e_pos(*b_r)) + return (false); + ++b_l; + ++b_r; + } + return (!compare_after || b_r == e_r); + } + + PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC + bool + PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: + equal_keys(const_key_reference r_lhs_key, const_key_reference r_rhs_key) const + { + return (equal_prefixes(base_type::begin(r_lhs_key), + base_type::end(r_lhs_key), + base_type::begin(r_rhs_key), + base_type::end(r_rhs_key), + true)); + } + + PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC + bool + PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: + cmp_prefixes(typename base_type::const_iterator b_l, typename base_type::const_iterator e_l, typename base_type::const_iterator b_r, typename base_type::const_iterator e_r, bool compare_after /* = false*/) const + { + while (b_l != e_l) + { + if (b_r == e_r) + return (false); + const typename base_type::size_type l_pos = + base_type::e_pos(*b_l); + const typename base_type::size_type r_pos = + base_type::e_pos(*b_r); + if (l_pos != r_pos) + return (l_pos < r_pos); + ++b_l; + ++b_r; + } + + if (!compare_after) + return (false); + return (b_r != e_r); + } + + PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC + bool + PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: + cmp_keys(const_key_reference r_lhs_key, const_key_reference r_rhs_key) const + { + return (cmp_prefixes(base_type::begin(r_lhs_key), + base_type::end(r_lhs_key), + base_type::begin(r_rhs_key), + base_type::end(r_rhs_key), + true)); + } + + PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC + inline typename PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC::const_key_reference + PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: + extract_key(const_reference r_val) + { + return (extract_key(r_val, s_set_ind)); + } + + PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC + inline typename PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC::const_key_reference + PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: + extract_key(const_reference r_val, true_type) + { + return (r_val); + } + + PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC + inline typename PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC::const_key_reference + PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: + extract_key(const_reference r_val, false_type) + { + return (r_val.first); + } + +#ifdef _GLIBCXX_DEBUG + PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC + bool + PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: + operator()(const_key_reference r_lhs, const_key_reference r_rhs) + { + return (cmp_keys(r_lhs, r_rhs)); + } +#endif + +#undef PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC +#undef PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC + + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/trace_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/trace_fn_imps.hpp new file mode 100644 index 000000000000..cab28ca7707b --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/trace_fn_imps.hpp @@ -0,0 +1,119 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file trace_fn_imps.hpp + * Contains an implementation class for pat_trie_. + */ + +#ifdef PB_DS_PAT_TRIE_TRACE_ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +trace() const +{ + std::cerr << std::endl; + if (m_p_head->m_p_parent == NULL) + return; + trace_node(m_p_head->m_p_parent, 0); + std::cerr << std::endl; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +trace_node(const_node_pointer p_nd, size_type level) +{ + for (size_type i = 0; i < level; ++i) + std::cerr << ' '; + std::cerr << p_nd << " "; + std::cerr << ((p_nd->m_type == pat_trie_leaf_node_type) ? "l " : "i "); + + trace_node_metadata(p_nd, type_to_type<typename node::metadata_type>()); + typename e_access_traits::const_iterator el_it = pref_begin(p_nd); + while (el_it != pref_end(p_nd)) + { + std::cerr <<* el_it; + ++el_it; + } + + if (p_nd->m_type == pat_trie_leaf_node_type) + { + std::cerr << std::endl; + return; + } + + const_internal_node_pointer p_internal = + static_cast<const_internal_node_pointer>(p_nd); + + std::cerr << " " << + static_cast<unsigned long>(p_internal->get_e_ind()) << std::endl; + + const size_type num_children = std::distance(p_internal->begin(), + p_internal->end()); + + for (size_type child_i = 0; child_i < num_children; ++child_i) + { + typename internal_node::const_iterator child_it = + p_internal->begin(); + std::advance(child_it, num_children - child_i - 1); + trace_node(*child_it, level + 1); + } +} + +PB_DS_CLASS_T_DEC +template<typename Metadata_> +void +PB_DS_CLASS_C_DEC:: +trace_node_metadata(const_node_pointer p_nd, type_to_type<Metadata_>) +{ + std::cerr << "(" << static_cast<unsigned long>(p_nd->get_metadata()) << ") "; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +trace_node_metadata(const_node_pointer, type_to_type<null_node_metadata>) +{ } + +#endif + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/traits.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/traits.hpp new file mode 100644 index 000000000000..b10380937bc7 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/traits.hpp @@ -0,0 +1,356 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file traits.hpp + * Contains an implementation class for pat_trie_. + */ + +#ifndef PB_DS_PAT_TRIE_NODE_AND_IT_TRAITS_HPP +#define PB_DS_PAT_TRIE_NODE_AND_IT_TRAITS_HPP + +#include <ext/pb_ds/detail/pat_trie_/node_base.hpp> +#include <ext/pb_ds/detail/pat_trie_/head.hpp> +#include <ext/pb_ds/detail/pat_trie_/leaf.hpp> +#include <ext/pb_ds/detail/pat_trie_/internal_node.hpp> +#include <ext/pb_ds/detail/pat_trie_/point_iterators.hpp> +#include <ext/pb_ds/detail/pat_trie_/node_iterators.hpp> +#include <ext/pb_ds/detail/pat_trie_/synth_e_access_traits.hpp> + +namespace pb_ds +{ + namespace detail + { + + template<typename Key, + typename Mapped, + class E_Access_Traits, + template<typename Const_Node_Iterator, + class Node_Iterator, + class Cmp_Fn_, + class Allocator_> + class Node_Update, + class Allocator> + struct trie_traits< + Key, + Mapped, + E_Access_Traits, + Node_Update, + pat_trie_tag, + Allocator> + { + private: + typedef types_traits< Key, Mapped, Allocator, false> type_traits; + + public: + typedef + typename trie_node_metadata_selector< + Key, + Mapped, + E_Access_Traits, + Node_Update, + Allocator>::type + metadata_type; + + typedef E_Access_Traits e_access_traits; + + typedef + synth_e_access_traits< + type_traits, + false, + e_access_traits> + synth_e_access_traits; + + typedef + pat_trie_node_base< + type_traits, + synth_e_access_traits, + metadata_type, + Allocator> + node; + + typedef + pat_trie_leaf< + type_traits, + synth_e_access_traits, + metadata_type, + Allocator> + leaf; + + typedef + pat_trie_head< + type_traits, + synth_e_access_traits, + metadata_type, + Allocator> + head; + + typedef + pat_trie_internal_node< + type_traits, + synth_e_access_traits, + metadata_type, + Allocator> + internal_node; + + typedef + pat_trie_const_it_< + type_traits, + node, + leaf, + head, + internal_node, + true, + Allocator> + const_iterator; + + typedef + pat_trie_it_< + type_traits, + node, + leaf, + head, + internal_node, + true, + Allocator> + iterator; + + typedef + pat_trie_const_it_< + type_traits, + node, + leaf, + head, + internal_node, + false, + Allocator> + const_reverse_iterator; + + typedef + pat_trie_it_< + type_traits, + node, + leaf, + head, + internal_node, + false, + Allocator> + reverse_iterator; + + typedef + pat_trie_const_node_it_< + node, + leaf, + head, + internal_node, + const_iterator, + iterator, + synth_e_access_traits, + Allocator> + const_node_iterator; + + typedef + pat_trie_node_it_< + node, + leaf, + head, + internal_node, + const_iterator, + iterator, + synth_e_access_traits, + Allocator> + node_iterator; + + typedef + Node_Update< + const_node_iterator, + node_iterator, + E_Access_Traits, + Allocator> + node_update; + + typedef + pb_ds::null_trie_node_update< + const_node_iterator, + node_iterator, + E_Access_Traits, + Allocator>* + null_node_update_pointer; + }; + + template<typename Key, + class E_Access_Traits, + template<typename Const_Node_Iterator, + class Node_Iterator, + class Cmp_Fn_, + class Allocator_> + class Node_Update, + class Allocator> + struct trie_traits< + Key, + null_mapped_type, + E_Access_Traits, + Node_Update, + pat_trie_tag, + Allocator> + { + private: + typedef + types_traits< + Key, + null_mapped_type, + Allocator, + false> + type_traits; + + public: + typedef + typename trie_node_metadata_selector< + Key, + null_mapped_type, + E_Access_Traits, + Node_Update, + Allocator>::type + metadata_type; + + typedef E_Access_Traits e_access_traits; + + typedef + synth_e_access_traits< + type_traits, + true, + e_access_traits> + synth_e_access_traits; + + typedef + pat_trie_node_base< + type_traits, + synth_e_access_traits, + metadata_type, + Allocator> + node; + + typedef + pat_trie_leaf< + type_traits, + synth_e_access_traits, + metadata_type, + Allocator> + leaf; + + typedef + pat_trie_head< + type_traits, + synth_e_access_traits, + metadata_type, + Allocator> + head; + + typedef + pat_trie_internal_node< + type_traits, + synth_e_access_traits, + metadata_type, + Allocator> + internal_node; + + typedef + pat_trie_const_it_< + type_traits, + node, + leaf, + head, + internal_node, + true, + Allocator> + const_iterator; + + typedef const_iterator iterator; + + typedef + pat_trie_const_it_< + type_traits, + node, + leaf, + head, + internal_node, + false, + Allocator> + const_reverse_iterator; + + typedef const_reverse_iterator reverse_iterator; + + typedef + pat_trie_const_node_it_< + node, + leaf, + head, + internal_node, + const_iterator, + iterator, + synth_e_access_traits, + Allocator> + const_node_iterator; + + typedef const_node_iterator node_iterator; + + typedef + Node_Update< + const_node_iterator, + node_iterator, + E_Access_Traits, + Allocator> + node_update; + + typedef + pb_ds::null_trie_node_update< + const_node_iterator, + const_node_iterator, + E_Access_Traits, + Allocator>* + null_node_update_pointer; + }; + + } // namespace detail +} // namespace pb_ds + +#endif // #ifndef PB_DS_PAT_TRIE_NODE_AND_IT_TRAITS_HPP + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/update_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/update_fn_imps.hpp new file mode 100644 index 000000000000..445376e8c40d --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/pat_trie_/update_fn_imps.hpp @@ -0,0 +1,61 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file update_fn_imps.hpp + * Contains an implementation class for pat_trie_. + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +apply_update(node_pointer /*p_nd*/, null_node_update_pointer) +{ } + +PB_DS_CLASS_T_DEC +template<typename Node_Update_> +inline void +PB_DS_CLASS_C_DEC:: +apply_update(node_pointer p_nd, Node_Update_* /*p_update*/) +{ + Node_Update_::operator()(node_iterator(p_nd, this), + const_node_iterator(NULL, this)); +} diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/priority_queue_base_dispatch.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/priority_queue_base_dispatch.hpp new file mode 100644 index 000000000000..67a705213d54 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/priority_queue_base_dispatch.hpp @@ -0,0 +1,97 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file priority_queue_base_dispatch.hpp + * Contains an pqiative container dispatching base. + */ + +#ifndef PB_DS_PRIORITY_QUEUE_BASE_DS_DISPATCHER_HPP +#define PB_DS_PRIORITY_QUEUE_BASE_DS_DISPATCHER_HPP + +#include <ext/pb_ds/detail/pairing_heap_/pairing_heap_.hpp> +#include <ext/pb_ds/detail/binomial_heap_/binomial_heap_.hpp> +#include <ext/pb_ds/detail/rc_binomial_heap_/rc_binomial_heap_.hpp> +#include <ext/pb_ds/detail/binary_heap_/binary_heap_.hpp> +#include <ext/pb_ds/detail/thin_heap_/thin_heap_.hpp> + +namespace pb_ds +{ + namespace detail + { + + template<typename Value_Type, typename Cmp_Fn, typename Tag, typename Allocator> + struct priority_queue_base_dispatch; + + template<typename Value_Type, typename Cmp_Fn, typename Allocator> + struct priority_queue_base_dispatch<Value_Type, Cmp_Fn, pairing_heap_tag, Allocator> + { + typedef pairing_heap_< Value_Type, Cmp_Fn, Allocator> type; + }; + + template<typename Value_Type, typename Cmp_Fn, typename Allocator> + struct priority_queue_base_dispatch<Value_Type, Cmp_Fn, binomial_heap_tag, Allocator> + { + typedef binomial_heap_< Value_Type, Cmp_Fn, Allocator> type; + }; + + template<typename Value_Type, typename Cmp_Fn, typename Allocator> + struct priority_queue_base_dispatch<Value_Type, Cmp_Fn, rc_binomial_heap_tag, Allocator> + { + typedef rc_binomial_heap_< Value_Type, Cmp_Fn, Allocator> type; + }; + + template<typename Value_Type, typename Cmp_Fn, typename Allocator> + struct priority_queue_base_dispatch<Value_Type, Cmp_Fn, binary_heap_tag, Allocator> + { + typedef binary_heap_< Value_Type, Cmp_Fn, Allocator> type; + }; + + template<typename Value_Type, typename Cmp_Fn, typename Allocator> + struct priority_queue_base_dispatch<Value_Type, Cmp_Fn, thin_heap_tag, Allocator> + { + typedef thin_heap_< Value_Type, Cmp_Fn, Allocator> type; + }; + + } // namespace detail +} // namespace pb_ds + +#endif // #ifndef PB_DS_PRIORITY_QUEUE_BASE_DS_DISPATCHER_HPP diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/constructors_destructor_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/constructors_destructor_fn_imps.hpp new file mode 100644 index 000000000000..c4a1bb8b77a3 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/constructors_destructor_fn_imps.hpp @@ -0,0 +1,106 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructors_destructor_fn_imps.hpp + * Contains an implementation for rb_tree_. + */ + +PB_DS_CLASS_T_DEC +template<typename It> +void +PB_DS_CLASS_C_DEC:: +copy_from_range(It first_it, It last_it) +{ + while (first_it != last_it) + insert(*(first_it++)); +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME() +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const Cmp_Fn& r_cmp_fn) : + base_type(r_cmp_fn) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const Cmp_Fn& r_cmp_fn, const node_update& r_node_update) : + base_type(r_cmp_fn, r_node_update) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const PB_DS_CLASS_C_DEC& other) : + base_type(other) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + base_type::swap(other); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +initialize() +{ base_type::m_p_head->m_red = true; } diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/debug_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/debug_fn_imps.hpp new file mode 100644 index 000000000000..08107ec7755e --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/debug_fn_imps.hpp @@ -0,0 +1,84 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_fn_imps.hpp + * Contains an implementation for rb_tree_. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +assert_node_consistent(const node_pointer p_nd) const +{ + if (p_nd == NULL) + return 1; + + const size_type l_height = assert_node_consistent(p_nd->m_p_left); + const size_type r_height = assert_node_consistent(p_nd->m_p_right); + if (p_nd->m_red) + { + _GLIBCXX_DEBUG_ASSERT(is_effectively_black(p_nd->m_p_left)); + _GLIBCXX_DEBUG_ASSERT(is_effectively_black(p_nd->m_p_right)); + } + _GLIBCXX_DEBUG_ASSERT(l_height == r_height); + return (p_nd->m_red ? 0 : 1) + l_height; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_valid() const +{ + base_type::assert_valid(); + const node_pointer p_head = base_type::m_p_head; + _GLIBCXX_DEBUG_ASSERT(p_head->m_red); + if (p_head->m_p_parent != NULL) + { + _GLIBCXX_DEBUG_ASSERT(!p_head->m_p_parent->m_red); + assert_node_consistent(p_head->m_p_parent); + } +} + +#endif + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/erase_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/erase_fn_imps.hpp new file mode 100644 index 000000000000..77b49907a0ae --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/erase_fn_imps.hpp @@ -0,0 +1,295 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file erase_fn_imps.hpp + * Contains an implementation for rb_tree_. + */ + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +erase(const_key_reference r_key) +{ + point_iterator it = find(r_key); + if (it == base_type::end()) + return false; + erase(it); + return true; +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +erase(iterator it) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid()); + if (it == base_type::end()) + return it; + + iterator ret_it = it; + ++ret_it; + erase_node(it.m_p_nd); + _GLIBCXX_DEBUG_ONLY(assert_valid()); + return ret_it; +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::reverse_iterator +PB_DS_CLASS_C_DEC:: +erase(reverse_iterator it) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid()); + if (it.m_p_nd == base_type::m_p_head) + return it; + + reverse_iterator ret_it = it; + ++ret_it; + erase_node(it.m_p_nd); + _GLIBCXX_DEBUG_ONLY(assert_valid()); + return ret_it; +} + +PB_DS_CLASS_T_DEC +template<typename Pred> +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +erase_if(Pred pred) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + size_type num_ersd = 0; + iterator it = base_type::begin(); + while (it != base_type::end()) + { + if (pred(*it)) + { + ++num_ersd; + it = erase(it); + } + else + ++it; + } + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return num_ersd; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +erase_node(node_pointer p_nd) +{ + remove_node(p_nd); + base_type::actual_erase_node(p_nd); + _GLIBCXX_DEBUG_ONLY(assert_valid()); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +remove_node(node_pointer p_z) +{ + update_min_max_for_erased_node(p_z); + node_pointer p_y = p_z; + node_pointer p_x = NULL; + node_pointer p_new_x_parent = NULL; + + if (p_y->m_p_left == NULL) + p_x = p_y->m_p_right; + else if (p_y->m_p_right == NULL) + p_x = p_y->m_p_left; + else + { + p_y = p_y->m_p_right; + while (p_y->m_p_left != NULL) + p_y = p_y->m_p_left; + p_x = p_y->m_p_right; + } + + if (p_y == p_z) + { + p_new_x_parent = p_y->m_p_parent; + if (p_x != NULL) + p_x->m_p_parent = p_y->m_p_parent; + + if (base_type::m_p_head->m_p_parent == p_z) + base_type::m_p_head->m_p_parent = p_x; + else if (p_z->m_p_parent->m_p_left == p_z) + { + p_y->m_p_left = p_z->m_p_parent; + p_z->m_p_parent->m_p_left = p_x; + } + else + { + p_y->m_p_left = NULL; + p_z->m_p_parent->m_p_right = p_x; + } + } + else + { + p_z->m_p_left->m_p_parent = p_y; + p_y->m_p_left = p_z->m_p_left; + if (p_y != p_z->m_p_right) + { + p_new_x_parent = p_y->m_p_parent; + if (p_x != NULL) + p_x->m_p_parent = p_y->m_p_parent; + p_y->m_p_parent->m_p_left = p_x; + p_y->m_p_right = p_z->m_p_right; + p_z->m_p_right->m_p_parent = p_y; + } + else + p_new_x_parent = p_y; + + if (base_type::m_p_head->m_p_parent == p_z) + base_type::m_p_head->m_p_parent = p_y; + else if (p_z->m_p_parent->m_p_left == p_z) + p_z->m_p_parent->m_p_left = p_y; + else + p_z->m_p_parent->m_p_right = p_y; + + p_y->m_p_parent = p_z->m_p_parent; + std::swap(p_y->m_red, p_z->m_red); + p_y = p_z; + } + + update_to_top(p_new_x_parent, (node_update* )this); + + if (p_y->m_red) + return; + + remove_fixup(p_x, p_new_x_parent); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +remove_fixup(node_pointer p_x, node_pointer p_new_x_parent) +{ + _GLIBCXX_DEBUG_ASSERT(p_x == NULL || p_x->m_p_parent == p_new_x_parent); + + while (p_x != base_type::m_p_head->m_p_parent && is_effectively_black(p_x)) + if (p_x == p_new_x_parent->m_p_left) + { + node_pointer p_w = p_new_x_parent->m_p_right; + if (p_w->m_red) + { + p_w->m_red = false; + p_new_x_parent->m_red = true; + base_type::rotate_left(p_new_x_parent); + p_w = p_new_x_parent->m_p_right; + } + + if (is_effectively_black(p_w->m_p_left) + && is_effectively_black(p_w->m_p_right)) + { + p_w->m_red = true; + p_x = p_new_x_parent; + p_new_x_parent = p_new_x_parent->m_p_parent; + } + else + { + if (is_effectively_black(p_w->m_p_right)) + { + if (p_w->m_p_left != NULL) + p_w->m_p_left->m_red = false; + + p_w->m_red = true; + base_type::rotate_right(p_w); + p_w = p_new_x_parent->m_p_right; + } + + p_w->m_red = p_new_x_parent->m_red; + p_new_x_parent->m_red = false; + + if (p_w->m_p_right != NULL) + p_w->m_p_right->m_red = false; + + base_type::rotate_left(p_new_x_parent); + update_to_top(p_new_x_parent, (node_update* )this); + break; + } + } + else + { + node_pointer p_w = p_new_x_parent->m_p_left; + if (p_w->m_red == true) + { + p_w->m_red = false; + p_new_x_parent->m_red = true; + base_type::rotate_right(p_new_x_parent); + p_w = p_new_x_parent->m_p_left; + } + + if (is_effectively_black(p_w->m_p_right) + && is_effectively_black(p_w->m_p_left)) + { + p_w->m_red = true; + p_x = p_new_x_parent; + p_new_x_parent = p_new_x_parent->m_p_parent; + } + else + { + if (is_effectively_black(p_w->m_p_left)) + { + if (p_w->m_p_right != NULL) + p_w->m_p_right->m_red = false; + + p_w->m_red = true; + base_type::rotate_left(p_w); + p_w = p_new_x_parent->m_p_left; + } + + p_w->m_red = p_new_x_parent->m_red; + p_new_x_parent->m_red = false; + + if (p_w->m_p_left != NULL) + p_w->m_p_left->m_red = false; + + base_type::rotate_right(p_new_x_parent); + update_to_top(p_new_x_parent, (node_update* )this); + break; + } + } + + if (p_x != NULL) + p_x->m_red = false; +} diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/find_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/find_fn_imps.hpp new file mode 100644 index 000000000000..25938ae47a80 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/find_fn_imps.hpp @@ -0,0 +1,45 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file find_fn_imps.hpp + * Contains an implementation for rb_tree_. + */ diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/info_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/info_fn_imps.hpp new file mode 100644 index 000000000000..7b65baac4ffe --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/info_fn_imps.hpp @@ -0,0 +1,52 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file info_fn_imps.hpp + * Contains an implementation for rb_tree_. + */ + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +is_effectively_black(const node_pointer p_nd) +{ return (p_nd == NULL || !p_nd->m_red); } + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/insert_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/insert_fn_imps.hpp new file mode 100644 index 000000000000..3bc7ce1f3ef2 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/insert_fn_imps.hpp @@ -0,0 +1,121 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file insert_fn_imps.hpp + * Contains an implementation for rb_tree_. + */ + +PB_DS_CLASS_T_DEC +inline std::pair<typename PB_DS_CLASS_C_DEC::point_iterator, bool> +PB_DS_CLASS_C_DEC:: +insert(const_reference r_value) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + std::pair<point_iterator, bool> ins_pair = base_type::insert_leaf(r_value); + if (ins_pair.second == true) + { + ins_pair.first.m_p_nd->m_red = true; + _GLIBCXX_DEBUG_ONLY(this->structure_only_assert_valid();) + insert_fixup(ins_pair.first.m_p_nd); + } + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return ins_pair; +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +insert_fixup(node_pointer p_nd) +{ + _GLIBCXX_DEBUG_ASSERT(p_nd->m_red == true); + while (p_nd != base_type::m_p_head->m_p_parent && p_nd->m_p_parent->m_red) + { + if (p_nd->m_p_parent == p_nd->m_p_parent->m_p_parent->m_p_left) + { + node_pointer p_y = p_nd->m_p_parent->m_p_parent->m_p_right; + if (p_y != NULL && p_y->m_red) + { + p_nd->m_p_parent->m_red = false; + p_y->m_red = false; + p_nd->m_p_parent->m_p_parent->m_red = true; + p_nd = p_nd->m_p_parent->m_p_parent; + } + else + { + if (p_nd == p_nd->m_p_parent->m_p_right) + { + p_nd = p_nd->m_p_parent; + base_type::rotate_left(p_nd); + } + p_nd->m_p_parent->m_red = false; + p_nd->m_p_parent->m_p_parent->m_red = true; + base_type::rotate_right(p_nd->m_p_parent->m_p_parent); + } + } + else + { + node_pointer p_y = p_nd->m_p_parent->m_p_parent->m_p_left; + if (p_y != NULL && p_y->m_red) + { + p_nd->m_p_parent->m_red = false; + p_y->m_red = false; + p_nd->m_p_parent->m_p_parent->m_red = true; + p_nd = p_nd->m_p_parent->m_p_parent; + } + else + { + if (p_nd == p_nd->m_p_parent->m_p_left) + { + p_nd = p_nd->m_p_parent; + base_type::rotate_right(p_nd); + } + p_nd->m_p_parent->m_red = false; + p_nd->m_p_parent->m_p_parent->m_red = true; + base_type::rotate_left(p_nd->m_p_parent->m_p_parent); + } + } + } + + base_type::update_to_top(p_nd, (node_update* )this); + base_type::m_p_head->m_p_parent->m_red = false; +} diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/node.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/node.hpp new file mode 100644 index 000000000000..164f965a551a --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/node.hpp @@ -0,0 +1,144 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file node.hpp + * Contains an implementation for rb_tree_. + */ + +#ifndef PB_DS_RB_TREE_NODE_HPP +#define PB_DS_RB_TREE_NODE_HPP + +#include <ext/pb_ds/detail/basic_tree_policy/null_node_metadata.hpp> + +namespace pb_ds +{ + namespace detail + { + template<typename Value_Type, class Metadata, class Allocator> + struct rb_tree_node_ + { + public: + typedef Value_Type value_type; + typedef Metadata metadata_type; + + typedef + typename Allocator::template rebind< + rb_tree_node_< + Value_Type, + Metadata, + Allocator> >::other::pointer + node_pointer; + + typedef + typename Allocator::template rebind< + metadata_type>::other::reference + metadata_reference; + + typedef + typename Allocator::template rebind< + metadata_type>::other::const_reference + const_metadata_reference; + + inline bool + special() const + { return m_red; } + + inline const_metadata_reference + get_metadata() const + { return m_metadata; } + + inline metadata_reference + get_metadata() + { return m_metadata; } + +#ifdef PB_DS_BIN_SEARCH_TREE_TRACE_ + void + trace() const + { + std::cout << PB_DS_V2F(m_value) <<(m_red? " <r> " : " <b> ") + << "(" << m_metadata << ")"; + } +#endif + + node_pointer m_p_left; + node_pointer m_p_right; + node_pointer m_p_parent; + value_type m_value; + bool m_red; + metadata_type m_metadata; + }; + + template<typename Value_Type, class Allocator> + struct rb_tree_node_<Value_Type, null_node_metadata, Allocator> + { + public: + typedef Value_Type value_type; + typedef null_node_metadata metadata_type; + + typedef + typename Allocator::template rebind< + rb_tree_node_< + Value_Type, + null_node_metadata, + Allocator> >::other::pointer + node_pointer; + + inline bool + special() const + { return m_red; } + +#ifdef PB_DS_BIN_SEARCH_TREE_TRACE_ + void + trace() const + { std::cout << PB_DS_V2F(m_value) <<(m_red? " <r> " : " <b> "); } +#endif + + node_pointer m_p_left; + node_pointer m_p_right; + node_pointer m_p_parent; + value_type m_value; + bool m_red; + }; + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/rb_tree_.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/rb_tree_.hpp new file mode 100644 index 000000000000..d08b2db69ae8 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/rb_tree_.hpp @@ -0,0 +1,286 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file rb_tree_.hpp + * Contains an implementation for rb_tree_. + */ +/* + * This implementation uses an idea from the SGI STL (using a "header" node + * which is needed for efficient iteration). + */ + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#ifndef PB_DS_BIN_SEARCH_TREE_HPP__DATA_TRUE_INDICATOR +#define PB_DS_BIN_SEARCH_TREE_HPP__DATA_TRUE_INDICATOR +#include <ext/pb_ds/detail/bin_search_tree_/bin_search_tree_.hpp> +#endif +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#ifndef PB_DS_BIN_SEARCH_TREE_HPP__DATA_FALSE_INDICATOR +#define PB_DS_BIN_SEARCH_TREE_HPP__DATA_FALSE_INDICATOR +#include <ext/pb_ds/detail/bin_search_tree_/bin_search_tree_.hpp> +#endif +#endif + +#include <ext/pb_ds/detail/standard_policies.hpp> +#include <ext/pb_ds/detail/basic_types.hpp> +#include <utility> +#include <vector> +#include <assert.h> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { +#define PB_DS_CLASS_T_DEC \ + template<typename Key, typename Mapped, typename Cmp_Fn, \ + typename Node_And_It_Traits, typename Allocator> + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_CLASS_NAME rb_tree_data_ +#endif + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_BASE_CLASS_NAME bin_search_tree_data_ +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#define PB_DS_CLASS_NAME rb_tree_no_data_ +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#define PB_DS_BASE_CLASS_NAME bin_search_tree_no_data_ +#endif + +#define PB_DS_CLASS_C_DEC \ + PB_DS_CLASS_NAME<Key, Mapped, Cmp_Fn, Node_And_It_Traits, Allocator> + +#define PB_DS_BASE_C_DEC \ + PB_DS_BASE_CLASS_NAME<Key, Mapped, Cmp_Fn, Node_And_It_Traits, Allocator> + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_V2F(X) (X).first +#define PB_DS_V2S(X) (X).second +#define PB_DS_EP2VP(X)& ((X)->m_value) +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#define PB_DS_V2F(X) (X) +#define PB_DS_V2S(X) Mapped_Data() +#define PB_DS_EP2VP(X)& ((X)->m_value.first) +#endif + + template<typename Key, + typename Mapped, + typename Cmp_Fn, + typename Node_And_It_Traits, + typename Allocator> + class PB_DS_CLASS_NAME : public PB_DS_BASE_C_DEC + { + private: + typedef PB_DS_BASE_C_DEC base_type; + typedef typename base_type::node_pointer node_pointer; + + public: + typedef Cmp_Fn cmp_fn; + typedef Allocator allocator; + typedef typename Allocator::size_type size_type; + typedef typename Allocator::difference_type difference_type; + typedef typename base_type::key_type key_type; + typedef typename base_type::key_pointer key_pointer; + typedef typename base_type::const_key_pointer const_key_pointer; + typedef typename base_type::key_reference key_reference; + typedef typename base_type::const_key_reference const_key_reference; + typedef typename base_type::mapped_type mapped_type; + typedef typename base_type::mapped_pointer mapped_pointer; + typedef typename base_type::const_mapped_pointer const_mapped_pointer; + typedef typename base_type::mapped_reference mapped_reference; + typedef typename base_type::const_mapped_reference const_mapped_reference; + typedef typename base_type::value_type value_type; + typedef typename base_type::pointer pointer; + typedef typename base_type::const_pointer const_pointer; + typedef typename base_type::reference reference; + typedef typename base_type::const_reference const_reference; + typedef typename base_type::point_iterator point_iterator; + typedef typename base_type::const_iterator const_point_iterator; + typedef typename base_type::iterator iterator; + typedef typename base_type::const_iterator const_iterator; + typedef typename base_type::reverse_iterator reverse_iterator; + typedef typename base_type::const_reverse_iterator const_reverse_iterator; + typedef typename base_type::node_update node_update; + + + PB_DS_CLASS_NAME(); + + PB_DS_CLASS_NAME(const Cmp_Fn&); + + PB_DS_CLASS_NAME(const Cmp_Fn&, const node_update&); + + PB_DS_CLASS_NAME(const PB_DS_CLASS_C_DEC&); + + void + swap(PB_DS_CLASS_C_DEC&); + + template<typename It> + void + copy_from_range(It, It); + + inline std::pair<point_iterator, bool> + insert(const_reference); + + inline mapped_reference + operator[](const_key_reference r_key) + { +#ifdef PB_DS_DATA_TRUE_INDICATOR + _GLIBCXX_DEBUG_ONLY(assert_valid();) + std::pair<point_iterator, bool> ins_pair = + base_type::insert_leaf(value_type(r_key, mapped_type())); + + if (ins_pair.second == true) + { + ins_pair.first.m_p_nd->m_red = true; + _GLIBCXX_DEBUG_ONLY(this->structure_only_assert_valid();) + insert_fixup(ins_pair.first.m_p_nd); + } + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return ins_pair.first.m_p_nd->m_value.second; +#else + insert(r_key); + return base_type::s_null_mapped; +#endif + } + + inline bool + erase(const_key_reference); + + inline iterator + erase(iterator); + + inline reverse_iterator + erase(reverse_iterator); + + template<typename Pred> + inline size_type + erase_if(Pred); + + void + join(PB_DS_CLASS_C_DEC&); + + void + split(const_key_reference, PB_DS_CLASS_C_DEC&); + + protected: + + private: + +#ifdef _GLIBCXX_DEBUG + void + assert_valid() const; + + size_type + assert_node_consistent(const node_pointer) const; +#endif + + inline static bool + is_effectively_black(const node_pointer); + + void + initialize(); + + void + insert_fixup(node_pointer); + + void + erase_node(node_pointer); + + void + remove_node(node_pointer); + + void + remove_fixup(node_pointer, node_pointer); + + void + split_imp(node_pointer, PB_DS_CLASS_C_DEC&); + + inline node_pointer + split_min(); + + std::pair<node_pointer, node_pointer> + split_min_imp(); + + void + join_imp(node_pointer, node_pointer); + + std::pair<node_pointer, node_pointer> + find_join_pos_right(node_pointer, size_type, size_type); + + std::pair<node_pointer, node_pointer> + find_join_pos_left(node_pointer, size_type, size_type); + + inline size_type + black_height(node_pointer); + + void + split_at_node(node_pointer, PB_DS_CLASS_C_DEC&); + }; + +#include <ext/pb_ds/detail/rb_tree_map_/constructors_destructor_fn_imps.hpp> +#include <ext/pb_ds/detail/rb_tree_map_/insert_fn_imps.hpp> +#include <ext/pb_ds/detail/rb_tree_map_/erase_fn_imps.hpp> +#include <ext/pb_ds/detail/rb_tree_map_/debug_fn_imps.hpp> +#include <ext/pb_ds/detail/rb_tree_map_/split_join_fn_imps.hpp> +#include <ext/pb_ds/detail/rb_tree_map_/info_fn_imps.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_CLASS_NAME +#undef PB_DS_BASE_CLASS_NAME +#undef PB_DS_BASE_C_DEC +#undef PB_DS_V2F +#undef PB_DS_EP2VP +#undef PB_DS_V2S + + } // namespace detail +} // namespace pb_ds + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/split_join_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/split_join_fn_imps.hpp new file mode 100644 index 000000000000..94b5ac39ff18 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/split_join_fn_imps.hpp @@ -0,0 +1,319 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file split_join_fn_imps.hpp + * Contains an implementation for rb_tree_. + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +join(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.base_type::assert_valid();) + if (base_type::join_prep(other) == false) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + return; + } + + const node_pointer p_x = other.split_min(); + join_imp(p_x, other.m_p_head->m_p_parent); + base_type::join_finish(other); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(base_type::assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.base_type::assert_valid();) + } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +join_imp(node_pointer p_x, node_pointer p_r) +{ + _GLIBCXX_DEBUG_ASSERT(p_x != NULL); + if (p_r != NULL) + p_r->m_red = false; + + const size_type h = black_height(base_type::m_p_head->m_p_parent); + const size_type other_h = black_height(p_r); + node_pointer p_x_l; + node_pointer p_x_r; + std::pair<node_pointer, node_pointer> join_pos; + const bool right_join = h >= other_h; + if (right_join) + { + join_pos = find_join_pos_right(base_type::m_p_head->m_p_parent, + h, other_h); + p_x_l = join_pos.first; + p_x_r = p_r; + } + else + { + p_x_l = base_type::m_p_head->m_p_parent; + base_type::m_p_head->m_p_parent = p_r; + if (p_r != NULL) + p_r->m_p_parent = base_type::m_p_head; + + join_pos = find_join_pos_left(base_type::m_p_head->m_p_parent, + h, other_h); + p_x_r = join_pos.first; + } + + node_pointer p_parent = join_pos.second; + if (p_parent == base_type::m_p_head) + { + base_type::m_p_head->m_p_parent = p_x; + p_x->m_p_parent = base_type::m_p_head; + } + else + { + p_x->m_p_parent = p_parent; + if (right_join) + p_x->m_p_parent->m_p_right = p_x; + else + p_x->m_p_parent->m_p_left = p_x; + } + + p_x->m_p_left = p_x_l; + if (p_x_l != NULL) + p_x_l->m_p_parent = p_x; + + p_x->m_p_right = p_x_r; + if (p_x_r != NULL) + p_x_r->m_p_parent = p_x; + + p_x->m_red = true; + + base_type::initialize_min_max(); + _GLIBCXX_DEBUG_ONLY(base_type::structure_only_assert_valid();) + base_type::update_to_top(p_x, (node_update* )this); + insert_fixup(p_x); + _GLIBCXX_DEBUG_ONLY(base_type::structure_only_assert_valid()); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +split_min() +{ + node_pointer p_min = base_type::m_p_head->m_p_left; + +#ifdef _GLIBCXX_DEBUG + const node_pointer p_head = base_type::m_p_head; + _GLIBCXX_DEBUG_ASSERT(p_min != p_head); +#endif + + remove_node(p_min); + return p_min; +} + +PB_DS_CLASS_T_DEC +std::pair< + typename PB_DS_CLASS_C_DEC::node_pointer, + typename PB_DS_CLASS_C_DEC::node_pointer> +PB_DS_CLASS_C_DEC:: +find_join_pos_right(node_pointer p_l, size_type h_l, size_type h_r) +{ + _GLIBCXX_DEBUG_ASSERT(h_l >= h_r); + + if (base_type::m_p_head->m_p_parent == NULL) + return (std::make_pair((node_pointer)NULL, base_type::m_p_head)); + + node_pointer p_l_parent = base_type::m_p_head; + while (h_l > h_r) + { + if (p_l->m_red == false) + { + _GLIBCXX_DEBUG_ASSERT(h_l > 0); + --h_l; + } + + p_l_parent = p_l; + p_l = p_l->m_p_right; + } + + if (!is_effectively_black(p_l)) + { + p_l_parent = p_l; + p_l = p_l->m_p_right; + } + + _GLIBCXX_DEBUG_ASSERT(is_effectively_black(p_l)); + _GLIBCXX_DEBUG_ASSERT(black_height(p_l) == h_r); + _GLIBCXX_DEBUG_ASSERT(p_l == NULL || p_l->m_p_parent == p_l_parent); + return std::make_pair(p_l, p_l_parent); +} + +PB_DS_CLASS_T_DEC +std::pair< + typename PB_DS_CLASS_C_DEC::node_pointer, + typename PB_DS_CLASS_C_DEC::node_pointer> +PB_DS_CLASS_C_DEC:: +find_join_pos_left(node_pointer p_r, size_type h_l, size_type h_r) +{ + _GLIBCXX_DEBUG_ASSERT(h_r > h_l); + if (base_type::m_p_head->m_p_parent == NULL) + return (std::make_pair((node_pointer)NULL, + base_type::m_p_head)); + node_pointer p_r_parent = base_type::m_p_head; + while (h_r > h_l) + { + if (p_r->m_red == false) + { + _GLIBCXX_DEBUG_ASSERT(h_r > 0); + --h_r; + } + + p_r_parent = p_r; + p_r = p_r->m_p_left; + } + + if (!is_effectively_black(p_r)) + { + p_r_parent = p_r; + p_r = p_r->m_p_left; + } + + _GLIBCXX_DEBUG_ASSERT(is_effectively_black(p_r)); + _GLIBCXX_DEBUG_ASSERT(black_height(p_r) == h_l); + _GLIBCXX_DEBUG_ASSERT(p_r == NULL || p_r->m_p_parent == p_r_parent); + return std::make_pair(p_r, p_r_parent); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +black_height(node_pointer p_nd) +{ + size_type h = 1; + while (p_nd != NULL) + { + if (p_nd->m_red == false) + ++h; + p_nd = p_nd->m_p_left; + } + return h; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +split(const_key_reference r_key, PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid()); + _GLIBCXX_DEBUG_ONLY(base_type::assert_valid();) + + _GLIBCXX_DEBUG_ONLY(other.assert_valid()); + _GLIBCXX_DEBUG_ONLY(other.base_type::assert_valid();) + + if (base_type::split_prep(r_key, other) == false) + { + _GLIBCXX_DEBUG_ONLY(assert_valid()); + _GLIBCXX_DEBUG_ONLY(other.assert_valid()); + return; + } + + _GLIBCXX_DEBUG_ONLY(base_type::structure_only_assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.base_type::structure_only_assert_valid();) + node_pointer p_nd = upper_bound(r_key).m_p_nd; + do + { + node_pointer p_next_nd = p_nd->m_p_parent; + if (Cmp_Fn::operator()(r_key, PB_DS_V2F(p_nd->m_value))) + split_at_node(p_nd, other); + + _GLIBCXX_DEBUG_ONLY(base_type::structure_only_assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.base_type::structure_only_assert_valid();) + p_nd = p_next_nd; + } + while (p_nd != base_type::m_p_head); + + base_type::split_finish(other); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +split_at_node(node_pointer p_nd, PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ASSERT(p_nd != NULL); + + node_pointer p_l = p_nd->m_p_left; + node_pointer p_r = p_nd->m_p_right; + node_pointer p_parent = p_nd->m_p_parent; + if (p_parent == base_type::m_p_head) + { + base_type::m_p_head->m_p_parent = p_l; + if (p_l != NULL) + { + p_l->m_p_parent = base_type::m_p_head; + p_l->m_red = false; + } + } + else + { + if (p_parent->m_p_left == p_nd) + p_parent->m_p_left = p_l; + else + p_parent->m_p_right = p_l; + + if (p_l != NULL) + p_l->m_p_parent = p_parent; + + update_to_top(p_parent, (node_update* )this); + + if (!p_nd->m_red) + remove_fixup(p_l, p_parent); + } + + base_type::initialize_min_max(); + other.join_imp(p_nd, p_r); + _GLIBCXX_DEBUG_ONLY(base_type::structure_only_assert_valid()); + _GLIBCXX_DEBUG_ONLY(other.base_type::structure_only_assert_valid()); +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/traits.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/traits.hpp new file mode 100644 index 000000000000..67570d842048 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/rb_tree_map_/traits.hpp @@ -0,0 +1,130 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file traits.hpp + * Contains an implementation for rb_tree_. + */ + +#ifndef PB_DS_RB_TREE_NODE_AND_IT_TRAITS_HPP +#define PB_DS_RB_TREE_NODE_AND_IT_TRAITS_HPP + +#include <ext/pb_ds/detail/rb_tree_map_/node.hpp> + +namespace pb_ds +{ + namespace detail + { + template<typename Key, + typename Mapped, + typename Cmp_Fn, + template<typename Const_Node_Iterator, + class Node_Iterator, + class Cmp_Fn_, + class Allocator_> + class Node_Update, + typename Allocator> + struct tree_traits< + Key, + Mapped, + Cmp_Fn, + Node_Update, + rb_tree_tag, + Allocator> : public bin_search_tree_traits< + Key, + Mapped, + Cmp_Fn, + Node_Update, + rb_tree_node_< + typename types_traits< + Key, + Mapped, + Allocator, + false>::value_type, + typename tree_node_metadata_selector< + Key, + Mapped, + Cmp_Fn, + Node_Update, + Allocator>::type, + Allocator>, + Allocator> + { }; + + template<typename Key, + class Cmp_Fn, + template<typename Const_Node_Iterator, + class Node_Iterator, + class Cmp_Fn_, + class Allocator_> + class Node_Update, + class Allocator> + struct tree_traits< + Key, + null_mapped_type, + Cmp_Fn, + Node_Update, + rb_tree_tag, + Allocator> : public bin_search_tree_traits< + Key, + null_mapped_type, + Cmp_Fn, + Node_Update, + rb_tree_node_< + typename types_traits< + Key, + null_mapped_type, + Allocator, + false>::value_type, + typename tree_node_metadata_selector< + Key, + null_mapped_type, + Cmp_Fn, + Node_Update, + Allocator>::type, + Allocator>, + Allocator> + { }; + + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/constructors_destructor_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/constructors_destructor_fn_imps.hpp new file mode 100644 index 000000000000..8b439c805e9c --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/constructors_destructor_fn_imps.hpp @@ -0,0 +1,94 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructors_destructor_fn_imps.hpp + * Contains an implementation for rc_binomial_heap_. + */ + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +rc_binomial_heap_() +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +rc_binomial_heap_(const Cmp_Fn& r_cmp_fn) : + PB_DS_BASE_C_DEC(r_cmp_fn) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +rc_binomial_heap_(const PB_DS_CLASS_C_DEC& other) : + PB_DS_BASE_C_DEC(other) +{ + make_binomial_heap(); + + base_type::find_max(); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +~rc_binomial_heap_() +{ } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + + base_type::swap(other); + + m_rc.swap(other.m_rc); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + } + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/debug_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/debug_fn_imps.hpp new file mode 100644 index 000000000000..e621cb58ca90 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/debug_fn_imps.hpp @@ -0,0 +1,127 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_fn_imps.hpp + * Contains an implementation for rc_binomial_heap_. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_valid() const +{ + base_type::assert_valid(false); + if (!base_type::empty()) + { + _GLIBCXX_DEBUG_ASSERT(base_type::m_p_max != NULL); + base_type::assert_max(); + } + + m_rc.assert_valid(); + + if (m_rc.empty()) + { + base_type::assert_valid(true); + _GLIBCXX_DEBUG_ASSERT(next_2_pointer(base_type::m_p_root) == NULL); + return; + } + + const_node_pointer p_nd = next_2_pointer(base_type::m_p_root); + typename rc_t::const_iterator it = m_rc.end(); + --it; + + while (p_nd != NULL) + { + _GLIBCXX_DEBUG_ASSERT(*it == p_nd); + const_node_pointer p_next = p_nd->m_p_next_sibling; + _GLIBCXX_DEBUG_ASSERT(p_next != NULL); + _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata == p_next->m_metadata); + _GLIBCXX_DEBUG_ASSERT(p_next->m_p_next_sibling == NULL || + p_next->m_metadata < p_next->m_p_next_sibling->m_metadata); + + --it; + p_nd = next_2_pointer(next_after_0_pointer(p_nd)); + } + _GLIBCXX_DEBUG_ASSERT(it + 1 == m_rc.begin()); +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::const_node_pointer +PB_DS_CLASS_C_DEC:: +next_2_pointer(const_node_pointer p_nd) +{ + if (p_nd == NULL) + return NULL; + + node_pointer p_next = p_nd->m_p_next_sibling; + + if (p_next == NULL) + return NULL; + + if (p_nd->m_metadata == p_next->m_metadata) + return p_nd; + + return next_2_pointer(p_next); +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::const_node_pointer +PB_DS_CLASS_C_DEC:: +next_after_0_pointer(const_node_pointer p_nd) +{ + if (p_nd == NULL) + return NULL; + + node_pointer p_next = p_nd->m_p_next_sibling; + + if (p_next == NULL) + return NULL; + + if (p_nd->m_metadata < p_next->m_metadata) + return p_next; + + return next_after_0_pointer(p_next); +} + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/erase_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/erase_fn_imps.hpp new file mode 100644 index 000000000000..b38141cc6cb3 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/erase_fn_imps.hpp @@ -0,0 +1,113 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file erase_fn_imps.hpp + * Contains an implementation for rc_binomial_heap_. + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +pop() +{ + make_binomial_heap(); + _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); + base_type::pop(); + base_type::find_max(); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +clear() +{ + base_type::clear(); + m_rc.clear(); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +make_binomial_heap() +{ + node_pointer p_nd = base_type::m_p_root; + while (p_nd != NULL) + { + node_pointer p_next = p_nd->m_p_next_sibling; + if (p_next == NULL) + p_nd = p_next; + else if (p_nd->m_metadata == p_next->m_metadata) + p_nd = link_with_next_sibling(p_nd); + else if (p_nd->m_metadata < p_next->m_metadata) + p_nd = p_next; +#ifdef _GLIBCXX_DEBUG + else + _GLIBCXX_DEBUG_ASSERT(0); +#endif + } + + m_rc.clear(); +} + +PB_DS_CLASS_T_DEC +template<typename Pred> +typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +erase_if(Pred pred) +{ + make_binomial_heap(); + const size_type ersd = base_type::erase_if(pred); + base_type::find_max(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return ersd; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +erase(point_iterator it) +{ + make_binomial_heap(); + base_type::erase(it); + base_type::find_max(); +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/insert_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/insert_fn_imps.hpp new file mode 100644 index 000000000000..c0f0d01f7465 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/insert_fn_imps.hpp @@ -0,0 +1,160 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file insert_fn_imps.hpp + * Contains an implementation for rc_binomial_heap_. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::point_iterator +PB_DS_CLASS_C_DEC:: +push(const_reference r_val) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + make_0_exposed(); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + node_pointer p_nd = base_type::get_new_node_for_insert(r_val); + + p_nd->m_p_l_child = p_nd->m_p_prev_or_parent = NULL; + p_nd->m_metadata = 0; + + if (base_type::m_p_max == NULL || Cmp_Fn::operator()(base_type::m_p_max->m_value, r_val)) + base_type::m_p_max = p_nd; + + p_nd->m_p_next_sibling = base_type::m_p_root; + + if (base_type::m_p_root != NULL) + base_type::m_p_root->m_p_prev_or_parent = p_nd; + + base_type::m_p_root = p_nd; + + if (p_nd->m_p_next_sibling != NULL&& p_nd->m_p_next_sibling->m_metadata == 0) + m_rc.push(p_nd); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + return point_iterator(p_nd); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +modify(point_iterator it, const_reference r_new_val) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + make_binomial_heap(); + + base_type::modify(it, r_new_val); + + base_type::find_max(); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +link_with_next_sibling(node_pointer p_nd) +{ + node_pointer p_next = p_nd->m_p_next_sibling; + + _GLIBCXX_DEBUG_ASSERT(p_next != NULL); + _GLIBCXX_DEBUG_ASSERT(p_next->m_p_prev_or_parent == p_nd); + + if (Cmp_Fn::operator()(p_nd->m_value, p_next->m_value)) + { + p_next->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; + + if (p_next->m_p_prev_or_parent == NULL) + base_type::m_p_root = p_next; + else + p_next->m_p_prev_or_parent->m_p_next_sibling = p_next; + + if (base_type::m_p_max == p_nd) + base_type::m_p_max = p_next; + + base_type::make_child_of(p_nd, p_next); + + ++p_next->m_metadata; + + return p_next; + } + + p_nd->m_p_next_sibling = p_next->m_p_next_sibling; + + if (p_nd->m_p_next_sibling != NULL) + p_nd->m_p_next_sibling->m_p_prev_or_parent = p_nd; + + if (base_type::m_p_max == p_next) + base_type::m_p_max = p_nd; + + base_type::make_child_of(p_next, p_nd); + + ++p_nd->m_metadata; + + return p_nd; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +make_0_exposed() +{ + if (m_rc.empty()) + return; + + node_pointer p_nd = m_rc.top(); + + m_rc.pop(); + + _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_next_sibling != NULL); + _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata == p_nd->m_p_next_sibling->m_metadata); + + node_pointer p_res = link_with_next_sibling(p_nd); + + if (p_res->m_p_next_sibling != NULL&& p_res->m_metadata == p_res->m_p_next_sibling->m_metadata) + m_rc.push(p_res); +} diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/rc.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/rc.hpp new file mode 100644 index 000000000000..dc7869ca7a7d --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/rc.hpp @@ -0,0 +1,268 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file rc.hpp + * Contains a redundant (binary counter). + */ + +#ifndef PB_DS_RC_HPP +#define PB_DS_RC_HPP + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_CLASS_T_DEC \ + template<typename Node, class Allocator> + +#define PB_DS_CLASS_C_DEC \ + rc<Node, Allocator> + + template<typename Node, class Allocator> + class rc + { + private: + typedef Allocator allocator; + + typedef typename allocator::size_type size_type; + + typedef Node node; + + typedef + typename allocator::template rebind< + node>::other::pointer + node_pointer; + + typedef + typename allocator::template rebind< + node_pointer>::other::pointer + entry_pointer; + + typedef + typename allocator::template rebind< + node_pointer>::other::const_pointer + const_entry_pointer; + + enum + { + max_entries = sizeof(size_type) << 3 + }; + + public: + typedef node_pointer entry; + + typedef const_entry_pointer const_iterator; + + public: + rc(); + + rc(const PB_DS_CLASS_C_DEC& other); + + inline void + swap(PB_DS_CLASS_C_DEC& other); + + inline void + push(entry p_nd); + + inline node_pointer + top() const; + + inline void + pop(); + + inline bool + empty() const; + + inline size_type + size() const; + + void + clear(); + + const const_iterator + begin() const; + + const const_iterator + end() const; + +#ifdef _GLIBCXX_DEBUG + void + assert_valid() const; +#endif + +#ifdef PB_DS_RC_BINOMIAL_HEAP_TRACE_ + void + trace() const; +#endif + + private: + node_pointer m_a_entries[max_entries]; + + size_type m_over_top; + }; + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + rc() : m_over_top(0) + { _GLIBCXX_DEBUG_ONLY(assert_valid();) } + + PB_DS_CLASS_T_DEC + PB_DS_CLASS_C_DEC:: + rc(const PB_DS_CLASS_C_DEC& other) : m_over_top(0) + { _GLIBCXX_DEBUG_ONLY(assert_valid();) } + + PB_DS_CLASS_T_DEC + inline void + PB_DS_CLASS_C_DEC:: + swap(PB_DS_CLASS_C_DEC& other) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + + const size_type over_top = std::max(m_over_top, other.m_over_top); + + for (size_type i = 0; i < over_top; ++i) + std::swap(m_a_entries[i], other.m_a_entries[i]); + + std::swap(m_over_top, other.m_over_top); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + } + + PB_DS_CLASS_T_DEC + inline void + PB_DS_CLASS_C_DEC:: + push(entry p_nd) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ASSERT(m_over_top < max_entries); + m_a_entries[m_over_top++] = p_nd; + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + + PB_DS_CLASS_T_DEC + inline void + PB_DS_CLASS_C_DEC:: + pop() + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ASSERT(!empty()); + --m_over_top; + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::node_pointer + PB_DS_CLASS_C_DEC:: + top() const + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ASSERT(!empty()); + return *(m_a_entries + m_over_top - 1); + } + + PB_DS_CLASS_T_DEC + inline bool + PB_DS_CLASS_C_DEC:: + empty() const + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return m_over_top == 0; + } + + PB_DS_CLASS_T_DEC + inline typename PB_DS_CLASS_C_DEC::size_type + PB_DS_CLASS_C_DEC:: + size() const + { return m_over_top; } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + clear() + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + m_over_top = 0; + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + + PB_DS_CLASS_T_DEC + const typename PB_DS_CLASS_C_DEC::const_iterator + PB_DS_CLASS_C_DEC:: + begin() const + { return& m_a_entries[0]; } + + PB_DS_CLASS_T_DEC + const typename PB_DS_CLASS_C_DEC::const_iterator + PB_DS_CLASS_C_DEC:: + end() const + { return& m_a_entries[m_over_top]; } + +#ifdef _GLIBCXX_DEBUG + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + assert_valid() const + { _GLIBCXX_DEBUG_ASSERT(m_over_top < max_entries); } +#endif + +#ifdef PB_DS_RC_BINOMIAL_HEAP_TRACE_ + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + trace() const + { + std::cout << "rc" << std::endl; + for (size_type i = 0; i < m_over_top; ++i) + std::cerr << m_a_entries[i] << std::endl; + std::cout << std::endl; + } +#endif + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +} // namespace detail +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/rc_binomial_heap_.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/rc_binomial_heap_.hpp new file mode 100644 index 000000000000..42417ed82fe1 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/rc_binomial_heap_.hpp @@ -0,0 +1,204 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file rc_binomial_heap_.hpp + * Contains an implementation for rc_binomial_heap_. + */ + +/* + * Redundant-counter binomial heap. + */ + +#include <ext/pb_ds/detail/cond_dealtor.hpp> +#include <ext/pb_ds/detail/type_utils.hpp> +#include <ext/pb_ds/detail/binomial_heap_base_/binomial_heap_base_.hpp> +#include <ext/pb_ds/detail/rc_binomial_heap_/rc.hpp> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { +#define PB_DS_CLASS_T_DEC \ + template<typename Value_Type, class Cmp_Fn, class Allocator> + +#define PB_DS_CLASS_C_DEC \ + rc_binomial_heap_<Value_Type, Cmp_Fn, Allocator> + +#define PB_DS_BASE_C_DEC \ + binomial_heap_base_<Value_Type, Cmp_Fn, Allocator> + +#define PB_DS_RC_C_DEC \ + rc<typename PB_DS_BASE_C_DEC::node, Allocator> + + /** + * class description = "8y|\|0|\/|i41 h34p 74813"> + **/ + template<typename Value_Type, class Cmp_Fn, class Allocator> + class rc_binomial_heap_ : public PB_DS_BASE_C_DEC + { + + private: + typedef PB_DS_BASE_C_DEC base_type; + + typedef typename base_type::node_pointer node_pointer; + + typedef typename base_type::const_node_pointer const_node_pointer; + + typedef PB_DS_RC_C_DEC rc_t; + + public: + + typedef typename Allocator::size_type size_type; + + typedef typename Allocator::difference_type difference_type; + + typedef Value_Type value_type; + + typedef typename base_type::pointer pointer; + + typedef typename base_type::const_pointer const_pointer; + + typedef typename base_type::reference reference; + + typedef typename base_type::const_reference const_reference; + + typedef typename base_type::const_point_iterator const_point_iterator; + + typedef typename base_type::point_iterator point_iterator; + + typedef typename base_type::const_iterator const_iterator; + + typedef typename base_type::iterator iterator; + + typedef typename base_type::cmp_fn cmp_fn; + + typedef typename base_type::allocator allocator; + + public: + + rc_binomial_heap_(); + + rc_binomial_heap_(const Cmp_Fn& r_cmp_fn); + + rc_binomial_heap_(const PB_DS_CLASS_C_DEC& other); + + ~rc_binomial_heap_(); + + void + swap(PB_DS_CLASS_C_DEC& other); + + inline point_iterator + push(const_reference r_val); + + void + modify(point_iterator it, const_reference r_new_val); + + inline void + pop(); + + void + erase(point_iterator it); + + inline void + clear(); + + template<typename Pred> + size_type + erase_if(Pred pred); + + template<typename Pred> + void + split(Pred pred, PB_DS_CLASS_C_DEC& other); + + void + join(PB_DS_CLASS_C_DEC& other); + +#ifdef _GLIBCXX_DEBUG + void + assert_valid() const; +#endif + +#ifdef PB_DS_RC_BINOMIAL_HEAP_TRACE_ + void + trace() const; +#endif + + private: + + inline node_pointer + link_with_next_sibling(node_pointer p_nd); + + void + make_0_exposed(); + + void + make_binomial_heap(); + +#ifdef _GLIBCXX_DEBUG + static const_node_pointer + next_2_pointer(const_node_pointer p_nd); + + static const_node_pointer + next_after_0_pointer(const_node_pointer p_nd); +#endif + + private: + rc_t m_rc; + }; + +#include <ext/pb_ds/detail/rc_binomial_heap_/constructors_destructor_fn_imps.hpp> +#include <ext/pb_ds/detail/rc_binomial_heap_/debug_fn_imps.hpp> +#include <ext/pb_ds/detail/rc_binomial_heap_/erase_fn_imps.hpp> +#include <ext/pb_ds/detail/rc_binomial_heap_/trace_fn_imps.hpp> +#include <ext/pb_ds/detail/rc_binomial_heap_/insert_fn_imps.hpp> +#include <ext/pb_ds/detail/rc_binomial_heap_/split_join_fn_imps.hpp> + +#undef PB_DS_CLASS_C_DEC + +#undef PB_DS_CLASS_T_DEC + +#undef PB_DS_BASE_C_DEC + +#undef PB_DS_RC_C_DEC + } // namespace detail +} // namespace pb_ds diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/split_join_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/split_join_fn_imps.hpp new file mode 100644 index 000000000000..356732b4e0ae --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/split_join_fn_imps.hpp @@ -0,0 +1,87 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file split_join_fn_imps.hpp + * Contains an implementation for rc_binomial_heap_. + */ + +PB_DS_CLASS_T_DEC +template<typename Pred> +void +PB_DS_CLASS_C_DEC:: +split(Pred pred, PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + + make_binomial_heap(); + other.make_binomial_heap(); + + base_type::split(pred, other); + + base_type::find_max(); + other.find_max(); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +join(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + + make_binomial_heap(); + other.make_binomial_heap(); + + base_type::join(other); + + base_type::find_max(); + other.find_max(); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + } + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/trace_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/trace_fn_imps.hpp new file mode 100644 index 000000000000..48c2e526c4b9 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/rc_binomial_heap_/trace_fn_imps.hpp @@ -0,0 +1,59 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file trace_fn_imps.hpp + * Contains an implementation for rc_binomial_heap_. + */ + +#ifdef PB_DS_RC_BINOMIAL_HEAP_TRACE_ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +trace() const +{ + base_type::trace(); + + m_rc.trace(); +} + +#endif // #ifdef PB_DS_RC_BINOMIAL_HEAP_TRACE_ diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/resize_policy/cc_hash_max_collision_check_resize_trigger_imp.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/resize_policy/cc_hash_max_collision_check_resize_trigger_imp.hpp new file mode 100644 index 000000000000..c10f7b6cc593 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/resize_policy/cc_hash_max_collision_check_resize_trigger_imp.hpp @@ -0,0 +1,221 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file cc_hash_max_collision_check_resize_trigger_imp.hpp + * Contains a resize trigger implementation. + */ + +#define PB_DS_STATIC_ASSERT(UNIQUE, E) \ + typedef detail::static_assert_dumclass<sizeof(detail::static_assert<(bool)(E)>)> UNIQUE##static_assert_type + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +cc_hash_max_collision_check_resize_trigger(float load) : + m_load(load), + m_size(0), + m_num_col(0), + m_max_col(0), + m_resize_needed(false) +{ } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_find_search_start() +{ } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_find_search_collision() +{ } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_find_search_end() +{ } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_insert_search_start() +{ m_num_col = 0; } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_insert_search_collision() +{ ++m_num_col; } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_insert_search_end() +{ calc_resize_needed(); } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_erase_search_start() +{ } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_erase_search_collision() +{ } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_erase_search_end() +{ } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_inserted(size_type) +{ } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_erased(size_type) +{ m_resize_needed = true; } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +notify_cleared() +{ m_resize_needed = false; } + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +is_resize_needed() const +{ return m_resize_needed; } + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +is_grow_needed(size_type /*size*/, size_type /*num_used_e*/) const +{ return m_num_col >= m_max_col; } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +notify_resized(size_type new_size) +{ + m_size = new_size; + +#ifdef PB_DS_HT_MAP_RESIZE_TRACE_ + std::cerr << "chmccrt::notify_resized " + << static_cast<unsigned long>(new_size) << std::endl; +#endif + + calc_max_num_coll(); + calc_resize_needed(); + m_num_col = 0; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +calc_max_num_coll() +{ + // max_col <-- \sqrt{2 load \ln( 2 m \ln( m ) ) } + const double ln_arg = 2 * m_size * ::log(double(m_size)); + m_max_col = size_type(::ceil(::sqrt(2 * m_load * ::log(ln_arg)))); + +#ifdef PB_DS_HT_MAP_RESIZE_TRACE_ + std::cerr << "chmccrt::calc_max_num_coll " + << static_cast<unsigned long>(m_size) << " " + << static_cast<unsigned long>(m_max_col) << std::endl; +#endif +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +notify_externally_resized(size_type new_size) +{ notify_resized(new_size); } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ + std::swap(m_load, other.m_load); + std::swap(m_size, other.m_size); + std::swap(m_num_col, other.m_num_col); + std::swap(m_max_col, other.m_max_col); + std::swap(m_resize_needed, other.m_resize_needed); +} + +PB_DS_CLASS_T_DEC +inline float +PB_DS_CLASS_C_DEC:: +get_load() const +{ + PB_DS_STATIC_ASSERT(access, external_load_access); + return m_load; +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +calc_resize_needed() +{ m_resize_needed = m_resize_needed || m_num_col >= m_max_col; } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +set_load(float load) +{ + PB_DS_STATIC_ASSERT(access, external_load_access); + m_load = load; + calc_max_num_coll(); + calc_resize_needed(); +} + +#undef PB_DS_STATIC_ASSERT diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/resize_policy/hash_exponential_size_policy_imp.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/resize_policy/hash_exponential_size_policy_imp.hpp new file mode 100644 index 000000000000..51cfc457c7d6 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/resize_policy/hash_exponential_size_policy_imp.hpp @@ -0,0 +1,96 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file hash_exponential_size_policy_imp.hpp + * Contains a resize size policy implementation. + */ + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +hash_exponential_size_policy(size_type start_size, size_type grow_factor) : + m_start_size(start_size), + m_grow_factor(grow_factor) +{ } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ + std::swap(m_start_size, other.m_start_size); + std::swap(m_grow_factor, other.m_grow_factor); +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +get_nearest_larger_size(size_type size) const +{ + size_type ret = m_start_size; + while (ret <= size) + { + const size_type next_ret = ret* m_grow_factor; + if (next_ret < ret) + __throw_insert_error(); + ret = next_ret; + } + return ret; +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +get_nearest_smaller_size(size_type size) const +{ + size_type ret = m_start_size; + while (true) + { + const size_type next_ret = ret* m_grow_factor; + if (next_ret < ret) + __throw_resize_error(); + if (next_ret >= size) + return (ret); + ret = next_ret; + } + return ret; +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_imp.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_imp.hpp new file mode 100644 index 000000000000..f3c597f93408 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_imp.hpp @@ -0,0 +1,300 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file hash_load_check_resize_trigger_imp.hpp + * Contains a resize trigger implementation. + */ + +#define PB_DS_STATIC_ASSERT(UNIQUE, E) \ + typedef detail::static_assert_dumclass<sizeof(detail::static_assert<bool(E)>)> UNIQUE##static_assert_type + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +hash_load_check_resize_trigger(float load_min, float load_max) +: m_load_min(load_min), m_load_max(load_max), m_next_shrink_size(0), + m_next_grow_size(0), m_resize_needed(false) +{ _GLIBCXX_DEBUG_ONLY(assert_valid();) } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_find_search_start() +{ _GLIBCXX_DEBUG_ONLY(assert_valid();) } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_find_search_collision() +{ _GLIBCXX_DEBUG_ONLY(assert_valid();) } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_find_search_end() +{ _GLIBCXX_DEBUG_ONLY(assert_valid();) } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_insert_search_start() +{ _GLIBCXX_DEBUG_ONLY(assert_valid();) } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_insert_search_collision() +{ _GLIBCXX_DEBUG_ONLY(assert_valid();) } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_insert_search_end() +{ _GLIBCXX_DEBUG_ONLY(assert_valid();) } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_erase_search_start() +{ _GLIBCXX_DEBUG_ONLY(assert_valid();) } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_erase_search_collision() +{ _GLIBCXX_DEBUG_ONLY(assert_valid();) } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_erase_search_end() +{ _GLIBCXX_DEBUG_ONLY(assert_valid();) } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_inserted(size_type num_entries) +{ + m_resize_needed = (num_entries >= m_next_grow_size); + size_base::set_size(num_entries); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_erased(size_type num_entries) +{ + size_base::set_size(num_entries); + m_resize_needed = num_entries <= m_next_shrink_size; + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +is_resize_needed() const +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return m_resize_needed; +} + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +is_grow_needed(size_type /*size*/, size_type num_entries) const +{ + _GLIBCXX_DEBUG_ASSERT(m_resize_needed); + return num_entries >= m_next_grow_size; +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +~hash_load_check_resize_trigger() { } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +notify_resized(size_type new_size) +{ + m_resize_needed = false; + m_next_grow_size = size_type(m_load_max * new_size - 1); + m_next_shrink_size = size_type(m_load_min * new_size); + +#ifdef PB_DS_HT_MAP_RESIZE_TRACE_ + std::cerr << "hlcrt::notify_resized " << + static_cast<unsigned long>(new_size) << " " << + static_cast<unsigned long>(m_load_min) << " " << + static_cast<unsigned long>(m_load_max) << " " << + static_cast<unsigned long>(m_next_shrink_size) << " " << + static_cast<unsigned long>(m_next_grow_size) << " " << std::endl; +#endif + + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +notify_externally_resized(size_type new_size) +{ + m_resize_needed = false; + size_type new_grow_size = size_type(m_load_max * new_size - 1); + size_type new_shrink_size = size_type(m_load_min * new_size ); + if (new_grow_size >= m_next_grow_size) + { + _GLIBCXX_DEBUG_ASSERT(new_shrink_size > m_next_shrink_size); + m_next_grow_size = new_grow_size; + _GLIBCXX_DEBUG_ONLY(assert_valid();) + +#ifdef PB_DS_HT_MAP_RESIZE_TRACE_ + std::cerr << "hlcrt::notify_externally_resized1 " << + static_cast<unsigned long>(new_size) << " " << + static_cast<unsigned long>(m_load_min) << " " << + static_cast<unsigned long>(m_load_max) << " " << + static_cast<unsigned long>(m_next_shrink_size) << " " << + static_cast<unsigned long>(m_next_grow_size) << " " << std::endl; +#endif + return; + } + + _GLIBCXX_DEBUG_ASSERT(new_shrink_size <= m_next_shrink_size); + m_next_shrink_size = new_shrink_size; + +#ifdef PB_DS_HT_MAP_RESIZE_TRACE_ + std::cerr << "hlcrt::notify_externally_resized2 " << + static_cast<unsigned long>(new_size) << " " << + static_cast<unsigned long>(m_load_min) << " " << + static_cast<unsigned long>(m_load_max) << " " << + static_cast<unsigned long>(m_next_shrink_size) << " " << + static_cast<unsigned long>(m_next_grow_size) << " " << std::endl; +#endif + + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +notify_cleared() +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + size_base::set_size(0); + m_resize_needed = (0 < m_next_shrink_size); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + + size_base::swap(other); + std::swap(m_load_min, other.m_load_min); + std::swap(m_load_max, other.m_load_max); + std::swap(m_resize_needed, other.m_resize_needed); + std::swap(m_next_grow_size, other.m_next_grow_size); + std::swap(m_next_shrink_size, other.m_next_shrink_size); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) +} + +PB_DS_CLASS_T_DEC +inline std::pair<float, float> +PB_DS_CLASS_C_DEC:: +get_loads() const +{ + PB_DS_STATIC_ASSERT(access, external_load_access); + return std::make_pair(m_load_min, m_load_max); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +set_loads(std::pair<float, float> load_pair) +{ + PB_DS_STATIC_ASSERT(access, external_load_access); + const float old_load_min = m_load_min; + const float old_load_max = m_load_max; + const size_type old_next_shrink_size = m_next_shrink_size; + const size_type old_next_grow_size = m_next_grow_size; + const bool old_resize_needed = m_resize_needed; + + try + { + m_load_min = load_pair.first; + m_load_max = load_pair.second; + do_resize(static_cast<size_type>(size_base::get_size() / ((m_load_min + m_load_max) / 2))); + } + catch (...) + { + m_load_min = old_load_min; + m_load_max = old_load_max; + m_next_shrink_size = old_next_shrink_size; + m_next_grow_size = old_next_grow_size; + m_resize_needed = old_resize_needed; + __throw_exception_again; + } +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +do_resize(size_type) +{ abort(); } + +#ifdef _GLIBCXX_DEBUG +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_valid() const +{ + _GLIBCXX_DEBUG_ASSERT(m_load_max > m_load_min); + _GLIBCXX_DEBUG_ASSERT(m_next_grow_size >= m_next_shrink_size); +} +#endif + +#undef PB_DS_STATIC_ASSERT + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_size_base.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_size_base.hpp new file mode 100644 index 000000000000..436de797d6ff --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_size_base.hpp @@ -0,0 +1,100 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file hash_load_check_resize_trigger_size_base.hpp + * Contains an base holding size for some resize policies. + */ + +#ifndef PB_DS_HASH_LOAD_CHECK_RESIZE_TRIGGER_SIZE_BASE_HPP +#define PB_DS_HASH_LOAD_CHECK_RESIZE_TRIGGER_SIZE_BASE_HPP + +namespace pb_ds +{ + namespace detail + { + // Primary template. + template<typename Size_Type, bool Hold_Size> + class hash_load_check_resize_trigger_size_base; + + // Specializations. + template<typename Size_Type> + class hash_load_check_resize_trigger_size_base<Size_Type, true> + { + protected: + typedef Size_Type size_type; + + hash_load_check_resize_trigger_size_base(): m_size(0) + { } + + inline void + swap(hash_load_check_resize_trigger_size_base& other) + { std::swap(m_size, other.m_size); } + + inline void + set_size(size_type size) + { m_size = size; } + + inline size_type + get_size() const + { return m_size; } + + private: + size_type m_size; + }; + + template<typename Size_Type> + class hash_load_check_resize_trigger_size_base<Size_Type, false> + { + protected: + typedef Size_Type size_type; + + protected: + inline void + swap(hash_load_check_resize_trigger_size_base& other) { } + + inline void + set_size(size_type size) { } + }; + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/resize_policy/hash_prime_size_policy_imp.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/resize_policy/hash_prime_size_policy_imp.hpp new file mode 100644 index 000000000000..3328c9158ac2 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/resize_policy/hash_prime_size_policy_imp.hpp @@ -0,0 +1,165 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file hash_prime_size_policy_imp.hpp + * Contains a resize size policy implementation. + */ + +namespace detail +{ + enum + { + num_distinct_sizes_32_bit = 30, + num_distinct_sizes_64_bit = 62, + num_distinct_sizes = sizeof(std::size_t) != 8 ? + num_distinct_sizes_32_bit : num_distinct_sizes_64_bit, + }; + + // Originally taken from the SGI implementation; acknowledged in the docs. + // Further modified (for 64 bits) from tr1's hashtable. + static const std::size_t g_a_sizes[num_distinct_sizes_64_bit] = + { + /* 0 */ 5ul, + /* 1 */ 11ul, + /* 2 */ 23ul, + /* 3 */ 47ul, + /* 4 */ 97ul, + /* 5 */ 199ul, + /* 6 */ 409ul, + /* 7 */ 823ul, + /* 8 */ 1741ul, + /* 9 */ 3469ul, + /* 10 */ 6949ul, + /* 11 */ 14033ul, + /* 12 */ 28411ul, + /* 13 */ 57557ul, + /* 14 */ 116731ul, + /* 15 */ 236897ul, + /* 16 */ 480881ul, + /* 17 */ 976369ul, + /* 18 */ 1982627ul, + /* 19 */ 4026031ul, + /* 20 */ 8175383ul, + /* 21 */ 16601593ul, + /* 22 */ 33712729ul, + /* 23 */ 68460391ul, + /* 24 */ 139022417ul, + /* 25 */ 282312799ul, + /* 26 */ 573292817ul, + /* 27 */ 1164186217ul, + /* 28 */ 2364114217ul, + /* 29 */ 4294967291ul, + /* 30 */ (std::size_t)8589934583ull, + /* 31 */ (std::size_t)17179869143ull, + /* 32 */ (std::size_t)34359738337ull, + /* 33 */ (std::size_t)68719476731ull, + /* 34 */ (std::size_t)137438953447ull, + /* 35 */ (std::size_t)274877906899ull, + /* 36 */ (std::size_t)549755813881ull, + /* 37 */ (std::size_t)1099511627689ull, + /* 38 */ (std::size_t)2199023255531ull, + /* 39 */ (std::size_t)4398046511093ull, + /* 40 */ (std::size_t)8796093022151ull, + /* 41 */ (std::size_t)17592186044399ull, + /* 42 */ (std::size_t)35184372088777ull, + /* 43 */ (std::size_t)70368744177643ull, + /* 44 */ (std::size_t)140737488355213ull, + /* 45 */ (std::size_t)281474976710597ull, + /* 46 */ (std::size_t)562949953421231ull, + /* 47 */ (std::size_t)1125899906842597ull, + /* 48 */ (std::size_t)2251799813685119ull, + /* 49 */ (std::size_t)4503599627370449ull, + /* 50 */ (std::size_t)9007199254740881ull, + /* 51 */ (std::size_t)18014398509481951ull, + /* 52 */ (std::size_t)36028797018963913ull, + /* 53 */ (std::size_t)72057594037927931ull, + /* 54 */ (std::size_t)144115188075855859ull, + /* 55 */ (std::size_t)288230376151711717ull, + /* 56 */ (std::size_t)576460752303423433ull, + /* 57 */ (std::size_t)1152921504606846883ull, + /* 58 */ (std::size_t)2305843009213693951ull, + /* 59 */ (std::size_t)4611686018427387847ull, + /* 60 */ (std::size_t)9223372036854775783ull, + /* 61 */ (std::size_t)18446744073709551557ull, + }; + +} // namespace detail + +PB_DS_CLASS_T_DEC +inline +PB_DS_CLASS_C_DEC:: +hash_prime_size_policy(size_type n) : m_start_size(n) +{ m_start_size = get_nearest_larger_size(n); } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ std::swap(m_start_size, other.m_start_size); } + +PB_DS_CLASS_T_DEC +inline PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +get_nearest_larger_size(size_type n) const +{ + const std::size_t* const p_upper = std::upper_bound(detail::g_a_sizes, + detail::g_a_sizes + detail::num_distinct_sizes, n); + + if (p_upper == detail::g_a_sizes + detail::num_distinct_sizes) + __throw_resize_error(); + return *p_upper; +} + +PB_DS_CLASS_T_DEC +inline PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +get_nearest_smaller_size(size_type n) const +{ + const size_t* p_lower = std::lower_bound(detail::g_a_sizes, + detail::g_a_sizes + detail::num_distinct_sizes, n); + + if (*p_lower >= n && p_lower != detail::g_a_sizes) + --p_lower; + if (*p_lower < m_start_size) + return m_start_size; + return *p_lower; +} diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/resize_policy/hash_standard_resize_policy_imp.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/resize_policy/hash_standard_resize_policy_imp.hpp new file mode 100644 index 000000000000..b8489915c843 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/resize_policy/hash_standard_resize_policy_imp.hpp @@ -0,0 +1,260 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file hash_standard_resize_policy_imp.hpp + * Contains a resize policy implementation. + */ + +#define PB_DS_STATIC_ASSERT(UNIQUE, E) \ + typedef detail::static_assert_dumclass<sizeof(detail::static_assert<(bool)(E)>)> UNIQUE##static_assert_type + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +hash_standard_resize_policy() +: m_size(Size_Policy::get_nearest_larger_size(1)) +{ trigger_policy_base::notify_externally_resized(m_size); } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +hash_standard_resize_policy(const Size_Policy& r_size_policy) +: Size_Policy(r_size_policy), m_size(Size_Policy::get_nearest_larger_size(1)) +{ trigger_policy_base::notify_externally_resized(m_size); } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +hash_standard_resize_policy(const Size_Policy& r_size_policy, + const Trigger_Policy& r_trigger_policy) +: Size_Policy(r_size_policy), Trigger_Policy(r_trigger_policy), + m_size(Size_Policy::get_nearest_larger_size(1)) +{ trigger_policy_base::notify_externally_resized(m_size); } + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +~hash_standard_resize_policy() +{ } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ + trigger_policy_base::swap(other); + size_policy_base::swap(other); + std::swap(m_size, other.m_size); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_find_search_start() +{ trigger_policy_base::notify_find_search_start(); } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_find_search_collision() +{ trigger_policy_base::notify_find_search_collision(); } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_find_search_end() +{ trigger_policy_base::notify_find_search_end(); } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_insert_search_start() +{ trigger_policy_base::notify_insert_search_start(); } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_insert_search_collision() +{ trigger_policy_base::notify_insert_search_collision(); } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_insert_search_end() +{ trigger_policy_base::notify_insert_search_end(); } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_erase_search_start() +{ trigger_policy_base::notify_erase_search_start(); } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_erase_search_collision() +{ trigger_policy_base::notify_erase_search_collision(); } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_erase_search_end() +{ trigger_policy_base::notify_erase_search_end(); } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_inserted(size_type num_e) +{ trigger_policy_base::notify_inserted(num_e); } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +notify_erased(size_type num_e) +{ trigger_policy_base::notify_erased(num_e); } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +notify_cleared() +{ trigger_policy_base::notify_cleared(); } + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +is_resize_needed() const +{ return trigger_policy_base::is_resize_needed(); } + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +get_new_size(size_type size, size_type num_used_e) const +{ + if (trigger_policy_base::is_grow_needed(size, num_used_e)) + return size_policy_base::get_nearest_larger_size(size); + return size_policy_base::get_nearest_smaller_size(size); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +notify_resized(size_type new_size) +{ + trigger_policy_base::notify_resized(new_size); + m_size = new_size; +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +get_actual_size() const +{ + PB_DS_STATIC_ASSERT(access, external_size_access); + return m_size; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +resize(size_type new_size) +{ + PB_DS_STATIC_ASSERT(access, external_size_access); + size_type actual_size = size_policy_base::get_nearest_larger_size(1); + while (actual_size < new_size) + { + const size_type pot = size_policy_base::get_nearest_larger_size(actual_size); + + if (pot == actual_size && pot < new_size) + __throw_resize_error(); + actual_size = pot; + } + + if (actual_size > 0) + --actual_size; + + const size_type old_size = m_size; + try + { + do_resize(actual_size - 1); + } + catch(insert_error& ) + { + m_size = old_size; + __throw_resize_error(); + } + catch(...) + { + m_size = old_size; + __throw_exception_again; + } +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +do_resize(size_type) +{ + // Do nothing +} + +PB_DS_CLASS_T_DEC +Trigger_Policy& +PB_DS_CLASS_C_DEC:: +get_trigger_policy() +{ return *this; } + +PB_DS_CLASS_T_DEC +const Trigger_Policy& +PB_DS_CLASS_C_DEC:: +get_trigger_policy() const +{ return *this; } + +PB_DS_CLASS_T_DEC +Size_Policy& +PB_DS_CLASS_C_DEC:: +get_size_policy() +{ return *this; } + +PB_DS_CLASS_T_DEC +const Size_Policy& +PB_DS_CLASS_C_DEC:: +get_size_policy() const +{ return *this; } + +#undef PB_DS_STATIC_ASSERT + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/resize_policy/sample_resize_policy.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/resize_policy/sample_resize_policy.hpp new file mode 100644 index 000000000000..cf7b1fb727ce --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/resize_policy/sample_resize_policy.hpp @@ -0,0 +1,131 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file sample_resize_policy.hpp + * Contains a sample resize policy for hash tables. + */ + +#ifndef PB_DS_SAMPLE_RESIZE_POLICY_HPP +#define PB_DS_SAMPLE_RESIZE_POLICY_HPP + +// A sample resize policy. +class sample_resize_policy +{ +public: + + // Size type. + typedef size_t size_type; + + // Default constructor. + sample_resize_policy(); + + // Copy constructor. + sample_range_hashing(const sample_resize_policy& other); + + // Swaps content. + inline void + swap(sample_resize_policy& other); + +protected: + + // Notifies a search started. + inline void + notify_insert_search_start(); + + // Notifies a search encountered a collision. + inline void + notify_insert_search_collision(); + + // Notifies a search ended. + inline void + notify_insert_search_end(); + + // Notifies a search started. + inline void + notify_find_search_start(); + + // Notifies a search encountered a collision. + inline void + notify_find_search_collision(); + + // Notifies a search ended. + inline void + notify_find_search_end(); + + // Notifies a search started. + inline void + notify_erase_search_start(); + + // Notifies a search encountered a collision. + inline void + notify_erase_search_collision(); + + // Notifies a search ended. + inline void + notify_erase_search_end(); + + // Notifies an element was inserted. + inline void + notify_inserted(size_type num_e); + + // Notifies an element was erased. + inline void + notify_erased(size_type num_e); + + // Notifies the table was cleared. + void + notify_cleared(); + + // Notifies the table was resized to new_size. + void + notify_resized(size_type new_size); + + // Queries whether a resize is needed. + inline bool + is_resize_needed() const; + + // Queries what the new size should be. + size_type + get_new_size(size_type size, size_type num_used_e) const; +}; + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/resize_policy/sample_resize_trigger.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/resize_policy/sample_resize_trigger.hpp new file mode 100644 index 000000000000..db07fbbc7e0f --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/resize_policy/sample_resize_trigger.hpp @@ -0,0 +1,145 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file sample_resize_trigger.hpp + * Contains a sample resize trigger policy class. + */ + +#ifndef PB_DS_SAMPLE_RESIZE_TRIGGER_HPP +#define PB_DS_SAMPLE_RESIZE_TRIGGER_HPP + +// A sample resize trigger policy. +class sample_resize_trigger +{ +public: + + // Size type. + typedef size_t size_type; + + // Default constructor. + sample_resize_trigger(); + + // Copy constructor. + sample_range_hashing(const sample_resize_trigger& other); + + // Swaps content. + inline void + swap(sample_resize_trigger& other); + +protected: + + // Notifies a search started. + inline void + notify_insert_search_start(); + + // Notifies a search encountered a collision. + inline void + notify_insert_search_collision(); + + // Notifies a search ended. + inline void + notify_insert_search_end(); + + // Notifies a search started. + inline void + notify_find_search_start(); + + // Notifies a search encountered a collision. + inline void + notify_find_search_collision(); + + // Notifies a search ended. + inline void + notify_find_search_end(); + + // Notifies a search started. + inline void + notify_erase_search_start(); + + // Notifies a search encountered a collision. + inline void + notify_erase_search_collision(); + + // Notifies a search ended. + inline void + notify_erase_search_end(); + + // Notifies an element was inserted. the total number of entries in + // the table is num_entries. + inline void + notify_inserted(size_type num_entries); + + // Notifies an element was erased. + inline void + notify_erased(size_type num_entries); + + // Notifies the table was cleared. + void + notify_cleared(); + + // Notifies the table was resized as a result of this object's + // signifying that a resize is needed. + void + notify_resized(size_type new_size); + + // Notifies the table was resized externally. + void + notify_externally_resized(size_type new_size); + + // Queries whether a resize is needed. + inline bool + is_resize_needed() const; + + // Queries whether a grow is needed. + inline bool + is_grow_needed(size_type size, size_type num_entries) const; + +private: + + // Resizes to new_size. + virtual void + do_resize(size_type new_size); +}; + +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/resize_policy/sample_size_policy.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/resize_policy/sample_size_policy.hpp new file mode 100644 index 000000000000..b88e70363874 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/resize_policy/sample_size_policy.hpp @@ -0,0 +1,79 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file sample_size_policy.hpp + * Contains a sample size resize-policy. + */ + +#ifndef PB_DS_SAMPLE_SIZE_POLICY_HPP +#define PB_DS_SAMPLE_SIZE_POLICY_HPP + +// A sample size policy. +class sample_size_policy +{ +public: + + // Size type. + typedef size_t size_type; + + // Default constructor. + sample_size_policy(); + + // Copy constructor. + sample_range_hashing(const sample_size_policy& other); + + // Swaps content. + inline void + swap(sample_size_policy& other); + +protected: + + // Given a __size size, returns a __size that is larger. + inline size_type + get_nearest_larger_size(size_type size) const; + + // Given a __size size, returns a __size that is smaller. + inline size_type + get_nearest_smaller_size(size_type size) const; +}; + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/splay_tree_/constructors_destructor_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/splay_tree_/constructors_destructor_fn_imps.hpp new file mode 100644 index 000000000000..b05a67219c7e --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/splay_tree_/constructors_destructor_fn_imps.hpp @@ -0,0 +1,108 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructors_destructor_fn_imps.hpp + * Contains an implementation class for splay_tree_. + */ + +PB_DS_CLASS_T_DEC +template<typename It> +void +PB_DS_CLASS_C_DEC:: +copy_from_range(It first_it, It last_it) +{ + while (first_it != last_it) + insert(*(first_it++)); +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME() +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const Cmp_Fn& r_cmp_fn) : + base_type(r_cmp_fn) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const Cmp_Fn& r_cmp_fn, const node_update& r_node_update) : + base_type(r_cmp_fn, r_node_update) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +PB_DS_CLASS_NAME(const PB_DS_CLASS_C_DEC& other) : + base_type(other) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + base_type::swap(other); + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +initialize() +{ base_type::m_p_head->m_special = true; } diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/splay_tree_/debug_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/splay_tree_/debug_fn_imps.hpp new file mode 100644 index 000000000000..cf7aaa8eda9e --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/splay_tree_/debug_fn_imps.hpp @@ -0,0 +1,80 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_fn_imps.hpp + * Contains an implementation class for splay_tree_. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_valid() const +{ + base_type::assert_valid(); + const node_pointer p_head = base_type::m_p_head; + assert_special_imp(p_head); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_special_imp(const node_pointer p_nd) const +{ + if (p_nd == NULL) + return; + + if (p_nd == base_type::m_p_head) + { + _GLIBCXX_DEBUG_ASSERT(p_nd->m_special); + assert_special_imp(p_nd->m_p_parent); + return; + } + + _GLIBCXX_DEBUG_ASSERT(!p_nd->m_special); + assert_special_imp(p_nd->m_p_left); + assert_special_imp(p_nd->m_p_right); +} + +#endif + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/splay_tree_/erase_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/splay_tree_/erase_fn_imps.hpp new file mode 100644 index 000000000000..26288fb0b269 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/splay_tree_/erase_fn_imps.hpp @@ -0,0 +1,163 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file erase_fn_imps.hpp + * Contains an implementation class for splay_tree_. + */ + +PB_DS_CLASS_T_DEC +inline bool +PB_DS_CLASS_C_DEC:: +erase(const_key_reference r_key) +{ + point_iterator it = find(r_key); + if (it == base_type::end()) + return false; + erase(it); + return true; +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +erase(iterator it) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid()); + if (it == base_type::end()) + return it; + iterator ret_it = it; + ++ret_it; + erase_node(it.m_p_nd); + _GLIBCXX_DEBUG_ONLY(assert_valid()); + return ret_it; +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::reverse_iterator +PB_DS_CLASS_C_DEC:: +erase(reverse_iterator it) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid()); + if (it.m_p_nd == base_type::m_p_head) + return (it); + reverse_iterator ret_it = it; + ++ret_it; + erase_node(it.m_p_nd); + _GLIBCXX_DEBUG_ONLY(assert_valid()); + return ret_it; +} + +PB_DS_CLASS_T_DEC +template<typename Pred> +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +erase_if(Pred pred) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + size_type num_ersd = 0; + iterator it = base_type::begin(); + while (it != base_type::end()) + { + if (pred(*it)) + { + ++num_ersd; + it = erase(it); + } + else + ++it; + } + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return num_ersd; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +erase_node(node_pointer p_nd) +{ + _GLIBCXX_DEBUG_ASSERT(p_nd != NULL); + splay(p_nd); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ASSERT(p_nd == this->m_p_head->m_p_parent); + + node_pointer p_l = p_nd->m_p_left; + node_pointer p_r = p_nd->m_p_right; + + base_type::update_min_max_for_erased_node(p_nd); + base_type::actual_erase_node(p_nd); + if (p_r == NULL) + { + base_type::m_p_head->m_p_parent = p_l; + if (p_l != NULL) + p_l->m_p_parent = base_type::m_p_head; + _GLIBCXX_DEBUG_ONLY(assert_valid();) + return; + } + + node_pointer p_target_r = leftmost(p_r); + _GLIBCXX_DEBUG_ASSERT(p_target_r != NULL); + p_r->m_p_parent = base_type::m_p_head; + base_type::m_p_head->m_p_parent = p_r; + splay(p_target_r); + + _GLIBCXX_DEBUG_ONLY(p_target_r->m_p_left = NULL); + _GLIBCXX_DEBUG_ASSERT(p_target_r->m_p_parent == this->m_p_head); + _GLIBCXX_DEBUG_ASSERT(this->m_p_head->m_p_parent == p_target_r); + + p_target_r->m_p_left = p_l; + if (p_l != NULL) + p_l->m_p_parent = p_target_r; + _GLIBCXX_DEBUG_ONLY(assert_valid();) + apply_update(p_target_r, (node_update* )this); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +leftmost(node_pointer p_nd) +{ + _GLIBCXX_DEBUG_ASSERT(p_nd != NULL); + while (p_nd->m_p_left != NULL) + p_nd = p_nd->m_p_left; + return p_nd; +} diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/splay_tree_/find_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/splay_tree_/find_fn_imps.hpp new file mode 100644 index 000000000000..6fdb8f55e866 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/splay_tree_/find_fn_imps.hpp @@ -0,0 +1,105 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file find_fn_imps.hpp + * Contains an implementation class for splay_tree_. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::point_iterator +PB_DS_CLASS_C_DEC:: +find(const_key_reference r_key) +{ + node_pointer p_found = find_imp(r_key); + if (p_found != base_type::m_p_head) + splay(p_found); + return point_iterator(p_found); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_point_iterator +PB_DS_CLASS_C_DEC:: +find(const_key_reference r_key) const +{ + const node_pointer p_found = find_imp(r_key); + if (p_found != base_type::m_p_head) + const_cast<PB_DS_CLASS_C_DEC* >(this)->splay(p_found); + return point_iterator(p_found); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +find_imp(const_key_reference r_key) +{ + _GLIBCXX_DEBUG_ONLY(base_type::structure_only_assert_valid();) + node_pointer p_nd = base_type::m_p_head->m_p_parent; + while (p_nd != NULL) + if (!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), r_key)) + { + if (!Cmp_Fn::operator()(r_key, PB_DS_V2F(p_nd->m_value))) + return p_nd; + p_nd = p_nd->m_p_left; + } + else + p_nd = p_nd->m_p_right; + return base_type::m_p_head; +} + +PB_DS_CLASS_T_DEC +inline const typename PB_DS_CLASS_C_DEC::node_pointer +PB_DS_CLASS_C_DEC:: +find_imp(const_key_reference r_key) const +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + node_pointer p_nd = base_type::m_p_head->m_p_parent; + while (p_nd != NULL) + if (!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), r_key)) + { + if (!Cmp_Fn::operator()(r_key, PB_DS_V2F(p_nd->m_value))) + return p_nd; + p_nd = p_nd->m_p_left; + } + else + p_nd = p_nd->m_p_right; + return base_type::m_p_head; +} diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/splay_tree_/info_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/splay_tree_/info_fn_imps.hpp new file mode 100644 index 000000000000..0d0736298dc7 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/splay_tree_/info_fn_imps.hpp @@ -0,0 +1,45 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file info_fn_imps.hpp + * Contains an implementation. + */ diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/splay_tree_/insert_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/splay_tree_/insert_fn_imps.hpp new file mode 100644 index 000000000000..f4b9f95177ff --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/splay_tree_/insert_fn_imps.hpp @@ -0,0 +1,99 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file insert_fn_imps.hpp + * Contains an implementation class for splay_tree_. + */ + +PB_DS_CLASS_T_DEC +inline std::pair<typename PB_DS_CLASS_C_DEC::point_iterator, bool> +PB_DS_CLASS_C_DEC:: +insert(const_reference r_value) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + std::pair<point_iterator, bool> ins_pair = insert_leaf_imp(r_value); + ins_pair.first.m_p_nd->m_special = false; + _GLIBCXX_DEBUG_ONLY(assert_valid()); + splay(ins_pair.first.m_p_nd); + _GLIBCXX_DEBUG_ONLY(assert_valid()); + return ins_pair; +} + +PB_DS_CLASS_T_DEC +inline std::pair<typename PB_DS_CLASS_C_DEC::point_iterator, bool> +PB_DS_CLASS_C_DEC:: +insert_leaf_imp(const_reference r_value) +{ + _GLIBCXX_DEBUG_ONLY(base_type::structure_only_assert_valid();) + if (base_type::m_size == 0) + return std::make_pair(base_type::insert_imp_empty(r_value), true); + + node_pointer p_nd = base_type::m_p_head->m_p_parent; + node_pointer p_pot = base_type::m_p_head; + + while (p_nd != NULL) + if (!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), PB_DS_V2F(r_value))) + { + if (!Cmp_Fn::operator()(PB_DS_V2F(r_value), PB_DS_V2F(p_nd->m_value))) + { + return std::make_pair(point_iterator(p_nd), false); + } + p_pot = p_nd; + p_nd = p_nd->m_p_left; + } + else + p_nd = p_nd->m_p_right; + + if (p_pot == base_type::m_p_head) + return std::make_pair(base_type::insert_leaf_new(r_value, base_type::m_p_head->m_p_right, false), true); + + _GLIBCXX_DEBUG_ONLY(base_type::check_key_does_not_exist(PB_DS_V2F(r_value))); + + p_nd = p_pot->m_p_left; + if (p_nd == NULL) + return (std::make_pair(base_type::insert_leaf_new(r_value, p_pot, true), true)); + + while (p_nd->m_p_right != NULL) + p_nd = p_nd->m_p_right; + + return std::make_pair(insert_leaf_new(r_value, p_nd, false), true); +} diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/splay_tree_/node.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/splay_tree_/node.hpp new file mode 100644 index 000000000000..d23e93173235 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/splay_tree_/node.hpp @@ -0,0 +1,131 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file node.hpp + * Contains an implementation struct for splay_tree_'s node. + */ + +#ifndef PB_DS_SPLAY_TREE_NODE_HPP +#define PB_DS_SPLAY_TREE_NODE_HPP + +namespace pb_ds +{ + namespace detail + { + template<typename Value_Type, class Metadata, class Allocator> + struct splay_tree_node_ + { + public: + typedef Value_Type value_type; + typedef Metadata metadata_type; + + typedef + typename Allocator::template rebind< + splay_tree_node_<Value_Type, Metadata, Allocator> >::other::pointer + node_pointer; + + typedef + typename Allocator::template rebind<metadata_type>::other::reference + metadata_reference; + + typedef + typename Allocator::template rebind<metadata_type>::other::const_reference + const_metadata_reference; + +#ifdef PB_DS_BIN_SEARCH_TREE_TRACE_ + void + trace() const + { std::cout << PB_DS_V2F(m_value) << "(" << m_metadata << ")"; } +#endif + + inline bool + special() const + { return m_special; } + + inline const_metadata_reference + get_metadata() const + { return m_metadata; } + + inline metadata_reference + get_metadata() + { return m_metadata; } + + value_type m_value; + bool m_special; + node_pointer m_p_left; + node_pointer m_p_right; + node_pointer m_p_parent; + metadata_type m_metadata; + }; + + template<typename Value_Type, typename Allocator> + struct splay_tree_node_<Value_Type, null_node_metadata, Allocator> + { + public: + typedef Value_Type value_type; + typedef null_node_metadata metadata_type; + + typedef + typename Allocator::template rebind< + splay_tree_node_<Value_Type, null_node_metadata, Allocator> >::other::pointer + node_pointer; + + inline bool + special() const + { return m_special; } + +#ifdef PB_DS_BIN_SEARCH_TREE_TRACE_ + void + trace() const + { std::cout << PB_DS_V2F(m_value); } +#endif + + node_pointer m_p_left; + node_pointer m_p_right; + node_pointer m_p_parent; + value_type m_value; + bool m_special; + }; + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/splay_tree_/splay_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/splay_tree_/splay_fn_imps.hpp new file mode 100644 index 000000000000..62def3c13dac --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/splay_tree_/splay_fn_imps.hpp @@ -0,0 +1,289 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file splay_fn_imps.hpp + * Contains an implementation class for splay_tree_. + */ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +splay(node_pointer p_nd) +{ + while (p_nd->m_p_parent != base_type::m_p_head) + { +#ifdef _GLIBCXX_DEBUG + { + node_pointer p_head = base_type::m_p_head; + assert_special_imp(p_head); + } +#endif + + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_nd);) + + if (p_nd->m_p_parent->m_p_parent == base_type::m_p_head) + { + base_type::rotate_parent(p_nd); + _GLIBCXX_DEBUG_ASSERT(p_nd == this->m_p_head->m_p_parent); + } + else + { + const node_pointer p_parent = p_nd->m_p_parent; + const node_pointer p_grandparent = p_parent->m_p_parent; + +#ifdef _GLIBCXX_DEBUG + const size_type total = + base_type::recursive_count(p_grandparent); + _GLIBCXX_DEBUG_ASSERT(total >= 3); +#endif + + if (p_parent->m_p_left == p_nd && + p_grandparent->m_p_right == p_parent) + splay_zig_zag_left(p_nd, p_parent, p_grandparent); + else if (p_parent->m_p_right == p_nd && + p_grandparent->m_p_left == p_parent) + splay_zig_zag_right(p_nd, p_parent, p_grandparent); + else if (p_parent->m_p_left == p_nd && + p_grandparent->m_p_left == p_parent) + splay_zig_zig_left(p_nd, p_parent, p_grandparent); + else + splay_zig_zig_right(p_nd, p_parent, p_grandparent); + _GLIBCXX_DEBUG_ASSERT(total ==this->recursive_count(p_nd)); + } + + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_nd);) + } +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +splay_zig_zag_left(node_pointer p_nd, node_pointer p_parent, + node_pointer p_grandparent) +{ + _GLIBCXX_DEBUG_ASSERT(p_parent == p_nd->m_p_parent); + _GLIBCXX_DEBUG_ASSERT(p_grandparent == p_parent->m_p_parent); + + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_grandparent);) + + _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_left == p_nd && + p_grandparent->m_p_right == p_parent); + + splay_zz_start(p_nd, p_parent, p_grandparent); + + node_pointer p_b = p_nd->m_p_right; + node_pointer p_c = p_nd->m_p_left; + + p_nd->m_p_right = p_parent; + p_parent->m_p_parent = p_nd; + + p_nd->m_p_left = p_grandparent; + p_grandparent->m_p_parent = p_nd; + + p_parent->m_p_left = p_b; + if (p_b != NULL) + p_b->m_p_parent = p_parent; + + p_grandparent->m_p_right = p_c; + if (p_c != NULL) + p_c->m_p_parent = p_grandparent; + + splay_zz_end(p_nd, p_parent, p_grandparent); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +splay_zig_zag_right(node_pointer p_nd, node_pointer p_parent, + node_pointer p_grandparent) +{ + _GLIBCXX_DEBUG_ASSERT(p_parent == p_nd->m_p_parent); + _GLIBCXX_DEBUG_ASSERT(p_grandparent == p_parent->m_p_parent); + + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_grandparent);) + + _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_right == p_nd && + p_grandparent->m_p_left == p_parent); + + splay_zz_start(p_nd, p_parent, p_grandparent); + + node_pointer p_b = p_nd->m_p_left; + node_pointer p_c = p_nd->m_p_right; + + p_nd->m_p_left = p_parent; + p_parent->m_p_parent = p_nd; + + p_nd->m_p_right = p_grandparent; + p_grandparent->m_p_parent = p_nd; + + p_parent->m_p_right = p_b; + if (p_b != NULL) + p_b->m_p_parent = p_parent; + + p_grandparent->m_p_left = p_c; + if (p_c != NULL) + p_c->m_p_parent = p_grandparent; + + splay_zz_end(p_nd, p_parent, p_grandparent); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +splay_zig_zig_left(node_pointer p_nd, node_pointer p_parent, + node_pointer p_grandparent) +{ + _GLIBCXX_DEBUG_ASSERT(p_parent == p_nd->m_p_parent); + _GLIBCXX_DEBUG_ASSERT(p_grandparent == p_parent->m_p_parent); + + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_grandparent);) + + _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_left == p_nd && + p_nd->m_p_parent->m_p_parent->m_p_left == p_nd->m_p_parent); + + splay_zz_start(p_nd, p_parent, p_grandparent); + + node_pointer p_b = p_nd->m_p_right; + node_pointer p_c = p_parent->m_p_right; + + p_nd->m_p_right = p_parent; + p_parent->m_p_parent = p_nd; + + p_parent->m_p_right = p_grandparent; + p_grandparent->m_p_parent = p_parent; + + p_parent->m_p_left = p_b; + if (p_b != NULL) + p_b->m_p_parent = p_parent; + + p_grandparent->m_p_left = p_c; + if (p_c != NULL) + p_c->m_p_parent = p_grandparent; + + splay_zz_end(p_nd, p_parent, p_grandparent); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +splay_zig_zig_right(node_pointer p_nd, node_pointer p_parent, + node_pointer p_grandparent) +{ + _GLIBCXX_DEBUG_ASSERT(p_parent == p_nd->m_p_parent); + _GLIBCXX_DEBUG_ASSERT(p_grandparent == p_parent->m_p_parent); + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_grandparent);) + _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_right == p_nd && + p_nd->m_p_parent->m_p_parent->m_p_right == p_nd->m_p_parent); + + splay_zz_start(p_nd, p_parent, p_grandparent); + + node_pointer p_b = p_nd->m_p_left; + node_pointer p_c = p_parent->m_p_left; + + p_nd->m_p_left = p_parent; + p_parent->m_p_parent = p_nd; + + p_parent->m_p_left = p_grandparent; + p_grandparent->m_p_parent = p_parent; + + p_parent->m_p_right = p_b; + if (p_b != NULL) + p_b->m_p_parent = p_parent; + + p_grandparent->m_p_right = p_c; + if (p_c != NULL) + p_c->m_p_parent = p_grandparent; + + base_type::update_to_top(p_grandparent, (node_update* )this); + splay_zz_end(p_nd, p_parent, p_grandparent); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +splay_zz_start(node_pointer p_nd, +#ifdef _GLIBCXX_DEBUG + node_pointer p_parent, +#else + node_pointer /*p_parent*/, +#endif + node_pointer p_grandparent) +{ + _GLIBCXX_DEBUG_ASSERT(p_nd != NULL); + _GLIBCXX_DEBUG_ASSERT(p_parent != NULL); + _GLIBCXX_DEBUG_ASSERT(p_grandparent != NULL); + + const bool grandparent_head = p_grandparent->m_p_parent == base_type::m_p_head; + + if (grandparent_head) + { + base_type::m_p_head->m_p_parent = base_type::m_p_head->m_p_parent; + p_nd->m_p_parent = base_type::m_p_head; + return; + } + + node_pointer p_greatgrandparent = p_grandparent->m_p_parent; + + p_nd->m_p_parent = p_greatgrandparent; + + if (p_grandparent == p_greatgrandparent->m_p_left) + p_greatgrandparent->m_p_left = p_nd; + else + p_greatgrandparent->m_p_right = p_nd; +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +splay_zz_end(node_pointer p_nd, node_pointer p_parent, + node_pointer p_grandparent) +{ + if (p_nd->m_p_parent == base_type::m_p_head) + base_type::m_p_head->m_p_parent = p_nd; + + apply_update(p_grandparent, (node_update* )this); + apply_update(p_parent, (node_update* )this); + apply_update(p_nd, (node_update* )this); + + _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(p_nd);) +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/splay_tree_/splay_tree_.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/splay_tree_/splay_tree_.hpp new file mode 100644 index 000000000000..bf905255333e --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/splay_tree_/splay_tree_.hpp @@ -0,0 +1,304 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file splay_tree_.hpp + * Contains an implementation class for splay_tree_. + */ +/* + * This implementation uses an idea from the SGI STL (using a "header" node + * which is needed for efficient iteration). Following is the SGI STL + * copyright. + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + */ + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#ifndef PB_DS_BIN_SEARCH_TREE_HPP__DATA_TRUE_INDICATOR +#define PB_DS_BIN_SEARCH_TREE_HPP__DATA_TRUE_INDICATOR +#include <ext/pb_ds/detail/bin_search_tree_/bin_search_tree_.hpp> +#endif +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#ifndef PB_DS_BIN_SEARCH_TREE_HPP__DATA_FALSE_INDICATOR +#define PB_DS_BIN_SEARCH_TREE_HPP__DATA_FALSE_INDICATOR +#include <ext/pb_ds/detail/bin_search_tree_/bin_search_tree_.hpp> +#endif +#endif + +#include <utility> +#include <vector> +#include <assert.h> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { +#define PB_DS_CLASS_T_DEC \ + template<typename Key, typename Mapped, typename Cmp_Fn, \ + typename Node_And_It_Traits, typename Allocator> + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_CLASS_NAME splay_tree_data_ +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#define PB_DS_CLASS_NAME splay_tree_no_data_ +#endif + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_BASE_CLASS_NAME bin_search_tree_data_ +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#define PB_DS_BASE_CLASS_NAME bin_search_tree_no_data_ +#endif + +#define PB_DS_CLASS_C_DEC \ + PB_DS_CLASS_NAME<Key, Mapped, Cmp_Fn, Node_And_It_Traits, Allocator> + +#define PB_DS_BASE_C_DEC \ + PB_DS_BASE_CLASS_NAME<Key, Mapped, Cmp_Fn, Node_And_It_Traits, Allocator> + +#ifdef PB_DS_DATA_TRUE_INDICATOR +#define PB_DS_V2F(X) (X).first +#define PB_DS_V2S(X) (X).second +#define PB_DS_EP2VP(X)& ((X)->m_value) +#endif + +#ifdef PB_DS_DATA_FALSE_INDICATOR +#define PB_DS_V2F(X) (X) +#define PB_DS_V2S(X) Mapped_Data() +#define PB_DS_EP2VP(X)& ((X)->m_value.first) +#endif + + // $p14y 7r33 7481. + template<typename Key, typename Mapped, typename Cmp_Fn, + typename Node_And_It_Traits, typename Allocator> + class PB_DS_CLASS_NAME : public PB_DS_BASE_C_DEC + { + private: + typedef PB_DS_BASE_C_DEC base_type; + typedef typename base_type::node_pointer node_pointer; + + public: + typedef Allocator allocator; + typedef typename Allocator::size_type size_type; + typedef typename Allocator::difference_type difference_type; + typedef Cmp_Fn cmp_fn; + typedef typename base_type::key_type key_type; + typedef typename base_type::key_pointer key_pointer; + typedef typename base_type::const_key_pointer const_key_pointer; + typedef typename base_type::key_reference key_reference; + typedef typename base_type::const_key_reference const_key_reference; + typedef typename base_type::mapped_type mapped_type; + typedef typename base_type::mapped_pointer mapped_pointer; + typedef typename base_type::const_mapped_pointer const_mapped_pointer; + typedef typename base_type::mapped_reference mapped_reference; + typedef typename base_type::const_mapped_reference const_mapped_reference; + typedef typename base_type::value_type value_type; + typedef typename base_type::pointer pointer; + typedef typename base_type::const_pointer const_pointer; + typedef typename base_type::reference reference; + typedef typename base_type::const_reference const_reference; + typedef typename base_type::point_iterator point_iterator; + typedef typename base_type::const_iterator const_point_iterator; + typedef typename base_type::iterator iterator; + typedef typename base_type::const_iterator const_iterator; + typedef typename base_type::reverse_iterator reverse_iterator; + typedef typename base_type::const_reverse_iterator const_reverse_iterator; + typedef typename base_type::node_update node_update; + + PB_DS_CLASS_NAME(); + + PB_DS_CLASS_NAME(const Cmp_Fn&); + + PB_DS_CLASS_NAME(const Cmp_Fn&, const node_update&); + + PB_DS_CLASS_NAME(const PB_DS_CLASS_C_DEC&); + + void + swap(PB_DS_CLASS_C_DEC&); + + template<typename It> + void + copy_from_range(It, It); + + void + initialize(); + + inline std::pair<point_iterator, bool> + insert(const_reference r_value); + + inline mapped_reference + operator[](const_key_reference r_key) + { +#ifdef PB_DS_DATA_TRUE_INDICATOR + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) + std::pair<point_iterator, bool> ins_pair = + insert_leaf_imp(value_type(r_key, mapped_type())); + + ins_pair.first.m_p_nd->m_special = false; + _GLIBCXX_DEBUG_ONLY(base_type::assert_valid()); + splay(ins_pair.first.m_p_nd); + _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();) + return ins_pair.first.m_p_nd->m_value.second; +#else + insert(r_key); + return base_type::s_null_mapped; +#endif + } + + inline point_iterator + find(const_key_reference); + + inline const_point_iterator + find(const_key_reference) const; + + inline bool + erase(const_key_reference); + + inline iterator + erase(iterator it); + + inline reverse_iterator + erase(reverse_iterator); + + template<typename Pred> + inline size_type + erase_if(Pred); + + void + join(PB_DS_CLASS_C_DEC&); + + void + split(const_key_reference, PB_DS_CLASS_C_DEC&); + + private: + inline std::pair<point_iterator, bool> + insert_leaf_imp(const_reference); + + inline node_pointer + find_imp(const_key_reference); + + inline const node_pointer + find_imp(const_key_reference) const; + +#ifdef _GLIBCXX_DEBUG + void + assert_valid() const; + + void + assert_special_imp(const node_pointer) const; +#endif + + void + splay(node_pointer); + + inline void + splay_zig_zag_left(node_pointer, node_pointer, node_pointer); + + inline void + splay_zig_zag_right(node_pointer, node_pointer, node_pointer); + + inline void + splay_zig_zig_left(node_pointer, node_pointer, node_pointer); + + inline void + splay_zig_zig_right(node_pointer, node_pointer, node_pointer); + + inline void + splay_zz_start(node_pointer, node_pointer, node_pointer); + + inline void + splay_zz_end(node_pointer, node_pointer, node_pointer); + + inline node_pointer + leftmost(node_pointer); + + void + erase_node(node_pointer); + }; + +#include <ext/pb_ds/detail/splay_tree_/constructors_destructor_fn_imps.hpp> +#include <ext/pb_ds/detail/splay_tree_/insert_fn_imps.hpp> +#include <ext/pb_ds/detail/splay_tree_/splay_fn_imps.hpp> +#include <ext/pb_ds/detail/splay_tree_/erase_fn_imps.hpp> +#include <ext/pb_ds/detail/splay_tree_/find_fn_imps.hpp> +#include <ext/pb_ds/detail/splay_tree_/debug_fn_imps.hpp> +#include <ext/pb_ds/detail/splay_tree_/split_join_fn_imps.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_CLASS_NAME +#undef PB_DS_BASE_CLASS_NAME +#undef PB_DS_BASE_C_DEC +#undef PB_DS_V2F +#undef PB_DS_EP2VP +#undef PB_DS_V2S + } // namespace detail +} // namespace pb_ds + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/splay_tree_/split_join_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/splay_tree_/split_join_fn_imps.hpp new file mode 100644 index 000000000000..c752f71f938d --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/splay_tree_/split_join_fn_imps.hpp @@ -0,0 +1,118 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file split_join_fn_imps.hpp + * Contains an implementation class for splay_tree_. + */ + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +join(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + if (base_type::join_prep(other) == false) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + return; + } + + node_pointer p_target_r = other.leftmost(other.m_p_head); + _GLIBCXX_DEBUG_ASSERT(p_target_r != NULL); + other.splay(p_target_r); + + _GLIBCXX_DEBUG_ASSERT(p_target_r == other.m_p_head->m_p_parent); + _GLIBCXX_DEBUG_ASSERT(p_target_r->m_p_left == NULL); + + p_target_r->m_p_left = base_type::m_p_head->m_p_parent; + + _GLIBCXX_DEBUG_ASSERT(p_target_r->m_p_left != NULL); + p_target_r->m_p_left->m_p_parent = p_target_r; + + base_type::m_p_head->m_p_parent = p_target_r; + p_target_r->m_p_parent = base_type::m_p_head; + apply_update(p_target_r, (node_update* )this); + + base_type::join_finish(other); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +split(const_key_reference r_key, PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid()); + _GLIBCXX_DEBUG_ONLY(other.assert_valid()); + + if (base_type::split_prep(r_key, other) == false) + { + _GLIBCXX_DEBUG_ONLY(assert_valid()); + _GLIBCXX_DEBUG_ONLY(other.assert_valid()); + return; + } + + node_pointer p_upper_bound = upper_bound(r_key).m_p_nd; + _GLIBCXX_DEBUG_ASSERT(p_upper_bound != NULL); + + splay(p_upper_bound); + _GLIBCXX_DEBUG_ASSERT(p_upper_bound->m_p_parent == this->m_p_head); + + node_pointer p_new_root = p_upper_bound->m_p_left; + _GLIBCXX_DEBUG_ASSERT(p_new_root != NULL); + + base_type::m_p_head->m_p_parent = p_new_root; + p_new_root->m_p_parent = base_type::m_p_head; + other.m_p_head->m_p_parent = p_upper_bound; + p_upper_bound->m_p_parent = other.m_p_head; + p_upper_bound->m_p_left = NULL; + apply_update(p_upper_bound, (node_update* )this); + base_type::split_finish(other); + + _GLIBCXX_DEBUG_ONLY(assert_valid()); + _GLIBCXX_DEBUG_ONLY(other.assert_valid()); +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/splay_tree_/traits.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/splay_tree_/traits.hpp new file mode 100644 index 000000000000..a758ef9ddbab --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/splay_tree_/traits.hpp @@ -0,0 +1,119 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file traits.hpp + * Contains an implementation for splay_tree_. + */ + +#ifndef PB_DS_SPLAY_TREE_NODE_AND_IT_TRAITS_HPP +#define PB_DS_SPLAY_TREE_NODE_AND_IT_TRAITS_HPP + +#include <ext/pb_ds/detail/splay_tree_/node.hpp> + +namespace pb_ds +{ + namespace detail + { + + template<typename Key, + typename Mapped, + class Cmp_Fn, + template<typename Const_Node_Iterator, + class Node_Iterator, + class Cmp_Fn_, + class Allocator_> + class Node_Update, + class Allocator> + struct tree_traits< + Key, + Mapped, + Cmp_Fn, + Node_Update, + splay_tree_tag, + Allocator> : public bin_search_tree_traits< + Key, + Mapped, + Cmp_Fn, + Node_Update, + splay_tree_node_< + typename types_traits< + Key, + Mapped, + Allocator, + false>::value_type, + typename tree_node_metadata_selector< + Key, + Mapped, + Cmp_Fn, + Node_Update, + Allocator>::type, + Allocator>, + Allocator> + { }; + + template<typename Key, + class Cmp_Fn, + template<typename Const_Node_Iterator, + class Node_Iterator, + class Cmp_Fn_, + class Allocator_> + class Node_Update, + class Allocator> + struct tree_traits<Key, null_mapped_type, Cmp_Fn, Node_Update, + splay_tree_tag, Allocator> + : public bin_search_tree_traits<Key, null_mapped_type, Cmp_Fn, + Node_Update, + splay_tree_node_<typename types_traits<Key, null_mapped_type, Allocator, false>::value_type, + typename tree_node_metadata_selector< + Key, + null_mapped_type, + Cmp_Fn, + Node_Update, + Allocator>::type, + Allocator>, + Allocator> + { }; + + } // namespace detail +} // namespace pb_ds + +#endif // #ifndef PB_DS_SPLAY_TREE_NODE_AND_IT_TRAITS_HPP diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/standard_policies.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/standard_policies.hpp new file mode 100644 index 000000000000..000e3a475de9 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/standard_policies.hpp @@ -0,0 +1,163 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file standard_policies.hpp + * Contains standard policies for containers. + */ + +#ifndef PB_DS_STANDARD_POLICIES_HPP +#define PB_DS_STANDARD_POLICIES_HPP + +#include <memory> +#include <ext/pb_ds/hash_policy.hpp> +#include <ext/pb_ds/list_update_policy.hpp> +#include <ext/pb_ds/tree_policy.hpp> +#include <ext/pb_ds/detail/basic_tree_policy/null_node_metadata.hpp> +#include <ext/pb_ds/trie_policy.hpp> +#include <ext/pb_ds/tag_and_trait.hpp> +#include <ext/hash_map> + +namespace pb_ds +{ + namespace detail + { + template<typename Key> + struct default_hash_fn + { + typedef __gnu_cxx::hash< Key> type; + }; + + template<typename Key> + struct default_eq_fn + { + typedef std::equal_to< Key> type; + }; + + enum + { + default_store_hash = false + }; + + struct default_comb_hash_fn + { + typedef pb_ds::direct_mask_range_hashing<> type; + }; + + template<typename Comb_Hash_Fn> + struct default_resize_policy + { + private: + typedef typename Comb_Hash_Fn::size_type size_type; + + typedef + typename __conditional_type< + is_same< + pb_ds::direct_mask_range_hashing< + size_type>, + Comb_Hash_Fn>::value, + pb_ds::hash_exponential_size_policy< + size_type>, + pb_ds::hash_prime_size_policy>::__type + size_policy_type; + + public: + typedef + pb_ds::hash_standard_resize_policy< + size_policy_type, + pb_ds::hash_load_check_resize_trigger< + false, + size_type>, + false, + size_type> + type; + }; + + struct default_update_policy + { + typedef pb_ds::move_to_front_lu_policy<> type; + }; + + template<typename Comb_Probe_Fn> + struct default_probe_fn + { + private: + typedef typename Comb_Probe_Fn::size_type size_type; + + public: + typedef + typename __conditional_type< + is_same< + pb_ds::direct_mask_range_hashing<size_t>, + Comb_Probe_Fn>::value, + pb_ds::linear_probe_fn< + size_type>, + pb_ds::quadratic_probe_fn< + size_type> >::__type + type; + }; + + template<typename Key> + struct default_trie_e_access_traits; + + template<typename Char, class Char_Traits> + struct default_trie_e_access_traits< + std::basic_string< + Char, + Char_Traits, + std::allocator< + char> > > + { + typedef + pb_ds::string_trie_e_access_traits< + std::basic_string< + Char, + Char_Traits, + std::allocator< + char> > > + type; + }; + + } // namespace detail +} // namespace pb_ds + +#endif // #ifndef PB_DS_STANDARD_POLICIES_HPP + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/thin_heap_/constructors_destructor_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/thin_heap_/constructors_destructor_fn_imps.hpp new file mode 100644 index 000000000000..1b0c6e53644e --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/thin_heap_/constructors_destructor_fn_imps.hpp @@ -0,0 +1,112 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file constructors_destructor_fn_imps.hpp + * Contains an implementation for thin_heap_. + */ + +PB_DS_CLASS_T_DEC +template<typename It> +void +PB_DS_CLASS_C_DEC:: +copy_from_range(It first_it, It last_it) +{ + while (first_it != last_it) + push(*(first_it++)); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +thin_heap_() : + m_p_max(NULL) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +thin_heap_(const Cmp_Fn& r_cmp_fn) : + PB_DS_BASE_C_DEC(r_cmp_fn), + m_p_max(NULL) +{ + initialize(); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +thin_heap_(const PB_DS_CLASS_C_DEC& other) : + PB_DS_BASE_C_DEC(other) +{ + initialize(); + m_p_max = base_type::m_p_root; + for (node_pointer p_nd = base_type::m_p_root; p_nd != NULL; p_nd = p_nd->m_p_next_sibling) + if (Cmp_Fn::operator()(m_p_max->m_value, p_nd->m_value)) + m_p_max = p_nd; + + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +swap(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + base_type::swap(other); + std::swap(m_p_max, other.m_p_max); + _GLIBCXX_DEBUG_ONLY(assert_valid();) +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +~thin_heap_() +{ } + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +initialize() +{ std::fill(m_a_aux, m_a_aux + max_rank, static_cast<node_pointer>(NULL)); } + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/thin_heap_/debug_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/thin_heap_/debug_fn_imps.hpp new file mode 100644 index 000000000000..310907d88341 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/thin_heap_/debug_fn_imps.hpp @@ -0,0 +1,118 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file debug_fn_imps.hpp + * Contains an implementation for thin_heap_. + */ + +#ifdef _GLIBCXX_DEBUG + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_valid() const +{ + base_type::assert_valid(); + assert_node_consistent(base_type::m_p_root, true); + assert_max(); + assert_aux_null(); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_aux_null() const +{ + for (size_type i = 0; i < max_rank; ++i) + _GLIBCXX_DEBUG_ASSERT(m_a_aux[i] == NULL); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_max() const +{ + if (m_p_max == NULL) + { + _GLIBCXX_DEBUG_ASSERT(base_type::empty()); + return; + } + + _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); + _GLIBCXX_DEBUG_ASSERT(base_type::parent(m_p_max) == NULL); + _GLIBCXX_DEBUG_ASSERT(m_p_max->m_p_prev_or_parent == NULL); + for (const_iterator it = base_type::begin(); it != base_type::end(); ++it) + _GLIBCXX_DEBUG_ASSERT(!Cmp_Fn::operator()(m_p_max->m_value, it.m_p_nd->m_value)); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +assert_node_consistent(const_node_pointer p_nd, bool root) const +{ + base_type::assert_node_consistent(p_nd, root); + if (p_nd == NULL) + return; + + assert_node_consistent(p_nd->m_p_next_sibling, root); + assert_node_consistent(p_nd->m_p_l_child, false); + if (!root) + { + if (p_nd->m_metadata == 0) + _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_next_sibling == NULL); + else + _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata == p_nd->m_p_next_sibling->m_metadata + 1); + } + + if (p_nd->m_p_l_child != NULL) + _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_l_child->m_metadata + 1 == base_type::degree(p_nd)); + + const bool unmarked_valid =(p_nd->m_p_l_child == NULL&& p_nd->m_metadata == 0) ||(p_nd->m_p_l_child != NULL&& p_nd->m_metadata == p_nd->m_p_l_child->m_metadata + 1); + + const bool marked_valid =(p_nd->m_p_l_child == NULL&& p_nd->m_metadata == 1) ||(p_nd->m_p_l_child != NULL&& p_nd->m_metadata == p_nd->m_p_l_child->m_metadata + 2); + + _GLIBCXX_DEBUG_ASSERT(unmarked_valid || marked_valid); + if (root) + _GLIBCXX_DEBUG_ASSERT(unmarked_valid); +} + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/thin_heap_/erase_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/thin_heap_/erase_fn_imps.hpp new file mode 100644 index 000000000000..9f409df158a7 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/thin_heap_/erase_fn_imps.hpp @@ -0,0 +1,302 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file erase_fn_imps.hpp + * Contains an implementation for thin_heap_. + */ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +pop() +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); + + _GLIBCXX_DEBUG_ASSERT(m_p_max != NULL); + + node_pointer p_nd = m_p_max; + + remove_max_node(); + + base_type::actual_erase_node(p_nd); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +remove_max_node() +{ + to_aux_except_max(); + + make_from_aux(); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +to_aux_except_max() +{ + node_pointer p_add = base_type::m_p_root; + + while (p_add != m_p_max) + { + node_pointer p_next_add = p_add->m_p_next_sibling; + + add_to_aux(p_add); + + p_add = p_next_add; + } + + p_add = m_p_max->m_p_l_child; + + while (p_add != NULL) + { + node_pointer p_next_add = p_add->m_p_next_sibling; + + p_add->m_metadata = p_add->m_p_l_child == NULL? + 0 : + p_add->m_p_l_child->m_metadata + 1; + + add_to_aux(p_add); + + p_add = p_next_add; + } + + p_add = m_p_max->m_p_next_sibling; + + while (p_add != NULL) + { + node_pointer p_next_add = p_add->m_p_next_sibling; + + add_to_aux(p_add); + + p_add = p_next_add; + } +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +add_to_aux(node_pointer p_nd) +{ + size_type r = p_nd->m_metadata; + + while (m_a_aux[r] != NULL) + { + _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata < rank_bound()); + + if (Cmp_Fn::operator()(m_a_aux[r]->m_value, p_nd->m_value)) + make_child_of(m_a_aux[r], p_nd); + else + { + make_child_of(p_nd, m_a_aux[r]); + + p_nd = m_a_aux[r]; + } + + m_a_aux[r] = NULL; + + ++r; + } + + _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata < rank_bound()); + + m_a_aux[r] = p_nd; +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +make_child_of(node_pointer p_nd, node_pointer p_new_parent) +{ + _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata == p_new_parent->m_metadata); + _GLIBCXX_DEBUG_ASSERT(m_a_aux[p_nd->m_metadata] == p_nd || + m_a_aux[p_nd->m_metadata] == p_new_parent); + + ++p_new_parent->m_metadata; + + base_type::make_child_of(p_nd, p_new_parent); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +make_from_aux() +{ + base_type::m_p_root = m_p_max = NULL; + + const size_type rnk_bnd = rank_bound(); + + size_type i = 0; + + while (i < rnk_bnd) + { + if (m_a_aux[i] != NULL) + { + make_root_and_link(m_a_aux[i]); + + m_a_aux[i] = NULL; + } + + ++i; + } + + _GLIBCXX_DEBUG_ONLY(assert_aux_null();) + } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +remove_node(node_pointer p_nd) +{ + node_pointer p_parent = p_nd; + while (base_type::parent(p_parent) != NULL) + p_parent = base_type::parent(p_parent); + + base_type::bubble_to_top(p_nd); + + m_p_max = p_nd; + + node_pointer p_fix = base_type::m_p_root; + while (p_fix != NULL&& p_fix->m_p_next_sibling != p_parent) + p_fix = p_fix->m_p_next_sibling; + + if (p_fix != NULL) + p_fix->m_p_next_sibling = p_nd; + + remove_max_node(); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +clear() +{ + base_type::clear(); + + m_p_max = NULL; +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +erase(point_iterator it) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); + + node_pointer p_nd = it.m_p_nd; + + remove_node(p_nd); + + base_type::actual_erase_node(p_nd); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + +PB_DS_CLASS_T_DEC +template<typename Pred> +typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +erase_if(Pred pred) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + if (base_type::empty()) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + return 0; + } + + base_type::to_linked_list(); + + node_pointer p_out = base_type::prune(pred); + + size_type ersd = 0; + + while (p_out != NULL) + { + ++ersd; + + node_pointer p_next = p_out->m_p_next_sibling; + + base_type::actual_erase_node(p_out); + + p_out = p_next; + } + + node_pointer p_cur = base_type::m_p_root; + + m_p_max = base_type::m_p_root = NULL; + + while (p_cur != NULL) + { + node_pointer p_next = p_cur->m_p_next_sibling; + + make_root_and_link(p_cur); + + p_cur = p_next; + } + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + return ersd; +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +rank_bound() +{ + const std::size_t* const p_upper = + std::upper_bound( g_a_rank_bounds, g_a_rank_bounds + num_distinct_rank_bounds, base_type::m_size); + + if (p_upper == g_a_rank_bounds + num_distinct_rank_bounds) + return max_rank; + + return (p_upper - g_a_rank_bounds); +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/thin_heap_/find_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/thin_heap_/find_fn_imps.hpp new file mode 100644 index 000000000000..256bd1ceed3a --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/thin_heap_/find_fn_imps.hpp @@ -0,0 +1,57 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file find_fn_imps.hpp + * Contains an implementation for thin_heap_. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_reference +PB_DS_CLASS_C_DEC:: +top() const +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); + + _GLIBCXX_DEBUG_ASSERT(m_p_max != NULL); + return m_p_max->m_value; +} diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/thin_heap_/insert_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/thin_heap_/insert_fn_imps.hpp new file mode 100644 index 000000000000..451793fee056 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/thin_heap_/insert_fn_imps.hpp @@ -0,0 +1,332 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file insert_fn_imps.hpp + * Contains an implementation for thin_heap_. + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::point_iterator +PB_DS_CLASS_C_DEC:: +push(const_reference r_val) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + node_pointer p_nd = base_type::get_new_node_for_insert(r_val); + + p_nd->m_metadata = 0; + + p_nd->m_p_prev_or_parent = p_nd->m_p_l_child = NULL; + + if (base_type::m_p_root == NULL) + { + p_nd->m_p_next_sibling = NULL; + + m_p_max = base_type::m_p_root = p_nd; + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + return point_iterator(p_nd); + } + + p_nd->m_p_next_sibling = base_type::m_p_root; + + base_type::m_p_root->m_p_prev_or_parent = NULL; + + base_type::m_p_root = p_nd; + + update_max(p_nd); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + return point_iterator(p_nd); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +make_root(node_pointer p_nd) +{ + p_nd->m_metadata = + p_nd->m_p_l_child == NULL? + 0 : + 1 + p_nd->m_p_l_child->m_metadata; +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +make_root_and_link(node_pointer p_nd) +{ + make_root(p_nd); + + p_nd->m_p_prev_or_parent = NULL; + + p_nd->m_p_next_sibling = base_type::m_p_root; + + if (base_type::m_p_root != NULL) + base_type::m_p_root->m_p_prev_or_parent = NULL; + + base_type::m_p_root = p_nd; + + update_max(p_nd); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +fix(node_pointer p_y) +{ + while (true) + { + if (p_y->m_p_prev_or_parent == NULL) + { + fix_root(p_y); + + return; + } + else if (p_y->m_metadata == 1&& p_y->m_p_next_sibling == NULL) + { + if (p_y->m_p_l_child != NULL) + { + fix_sibling_rank_1_unmarked(p_y); + + return; + } + + fix_sibling_rank_1_marked(p_y); + + p_y = p_y->m_p_prev_or_parent; + } + else if (p_y->m_metadata > p_y->m_p_next_sibling->m_metadata + 1) + { + _GLIBCXX_DEBUG_ASSERT(p_y->m_p_l_child != NULL); + + if (p_y->m_metadata != p_y->m_p_l_child->m_metadata + 2) + { + fix_sibling_general_unmarked(p_y); + + return; + } + + fix_sibling_general_marked(p_y); + + p_y = p_y->m_p_prev_or_parent; + } + else if ((p_y->m_p_l_child == NULL&& + p_y->m_metadata == 2) ||(p_y->m_p_l_child != NULL&& + p_y->m_metadata == p_y->m_p_l_child->m_metadata + 3)) + { + node_pointer p_z = p_y->m_p_prev_or_parent; + + fix_child(p_y); + + p_y = p_z; + } + else + return; + } +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +fix_root(node_pointer p_y) +{ + _GLIBCXX_DEBUG_ASSERT(p_y->m_p_prev_or_parent == NULL); + + make_root(p_y); + + _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_y, true);) + } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +fix_sibling_rank_1_unmarked(node_pointer p_y) +{ + _GLIBCXX_DEBUG_ASSERT(p_y->m_p_prev_or_parent != NULL); + + _GLIBCXX_DEBUG_ONLY(node_pointer p_w = p_y->m_p_l_child;) + _GLIBCXX_DEBUG_ASSERT(p_w != NULL); + _GLIBCXX_DEBUG_ASSERT(p_w->m_p_next_sibling == NULL); + _GLIBCXX_DEBUG_ASSERT(p_y->m_p_next_sibling == NULL); + + p_y->m_p_next_sibling = p_y->m_p_l_child; + + p_y->m_p_next_sibling->m_p_prev_or_parent = p_y; + + p_y->m_p_l_child = NULL; + + _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_y, false);) + } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +fix_sibling_rank_1_marked(node_pointer p_y) +{ + _GLIBCXX_DEBUG_ASSERT(p_y->m_p_prev_or_parent != NULL); + _GLIBCXX_DEBUG_ASSERT(p_y->m_p_l_child == NULL); + + p_y->m_metadata = 0; + + _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_y, false);) + } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +fix_sibling_general_unmarked(node_pointer p_y) +{ + _GLIBCXX_DEBUG_ASSERT(p_y->m_p_prev_or_parent != NULL); + + node_pointer p_w = p_y->m_p_l_child; + _GLIBCXX_DEBUG_ASSERT(p_w != NULL); + _GLIBCXX_DEBUG_ASSERT(p_w->m_p_next_sibling != NULL); + + p_y->m_p_l_child = p_w->m_p_next_sibling; + p_w->m_p_next_sibling->m_p_prev_or_parent = p_y; + + p_w->m_p_next_sibling = p_y->m_p_next_sibling; + _GLIBCXX_DEBUG_ASSERT(p_w->m_p_next_sibling != NULL); + p_w->m_p_next_sibling->m_p_prev_or_parent = p_w; + + p_y->m_p_next_sibling = p_w; + p_w->m_p_prev_or_parent = p_y; + + _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_y, false);) + } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +fix_sibling_general_marked(node_pointer p_y) +{ + _GLIBCXX_DEBUG_ASSERT(p_y->m_p_prev_or_parent != NULL); + + --p_y->m_metadata; + + _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_y, false);) + } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +fix_child(node_pointer p_y) +{ + _GLIBCXX_DEBUG_ASSERT(p_y->m_p_prev_or_parent != NULL); + + if (p_y->m_p_next_sibling != NULL) + p_y->m_p_next_sibling->m_p_prev_or_parent = p_y->m_p_prev_or_parent; + + if (p_y->m_p_prev_or_parent->m_p_l_child == p_y) + p_y->m_p_prev_or_parent->m_p_l_child = p_y->m_p_next_sibling; + else + p_y->m_p_prev_or_parent->m_p_next_sibling = p_y->m_p_next_sibling; + + make_root_and_link(p_y); +} + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +modify(point_iterator it, const_reference r_new_val) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + node_pointer p_nd = it.m_p_nd; + + _GLIBCXX_DEBUG_ASSERT(p_nd != NULL); + + const bool smaller = Cmp_Fn::operator()(r_new_val, p_nd->m_value); + + p_nd->m_value = r_new_val; + + if (smaller) + { + remove_node(p_nd); + + p_nd->m_p_l_child = NULL; + + make_root_and_link(p_nd); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + return; + } + + if (p_nd->m_p_prev_or_parent == NULL) + { + update_max(p_nd); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + + return; + } + + node_pointer p_y = p_nd->m_p_prev_or_parent; + _GLIBCXX_DEBUG_ASSERT(p_y != NULL); + + if (p_nd->m_p_next_sibling != NULL) + p_nd->m_p_next_sibling->m_p_prev_or_parent = p_y; + + if (p_y->m_p_l_child == p_nd) + p_y->m_p_l_child = p_nd->m_p_next_sibling; + else + p_y->m_p_next_sibling = p_nd->m_p_next_sibling; + + fix(p_y); + + make_root_and_link(p_nd); + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +update_max(node_pointer p_nd) +{ + if (m_p_max == NULL || Cmp_Fn::operator()(m_p_max->m_value, p_nd->m_value)) + m_p_max = p_nd; +} + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/thin_heap_/split_join_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/thin_heap_/split_join_fn_imps.hpp new file mode 100644 index 000000000000..a24d0aac0098 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/thin_heap_/split_join_fn_imps.hpp @@ -0,0 +1,132 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file split_join_fn_imps.hpp + * Contains an implementation for thin_heap_. + */ + +PB_DS_CLASS_T_DEC +template<typename Pred> +void +PB_DS_CLASS_C_DEC:: +split(Pred pred, PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + + other.clear(); + + if (base_type::empty()) + { + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + + return; + } + + base_type::to_linked_list(); + + node_pointer p_out = base_type::prune(pred); + + while (p_out != NULL) + { + _GLIBCXX_DEBUG_ASSERT(base_type::m_size > 0); + --base_type::m_size; + + ++other.m_size; + + node_pointer p_next = p_out->m_p_next_sibling; + + other.make_root_and_link(p_out); + + p_out = p_next; + } + + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + + node_pointer p_cur = base_type::m_p_root; + + m_p_max = NULL; + + base_type::m_p_root = NULL; + + while (p_cur != NULL) + { + node_pointer p_next = p_cur->m_p_next_sibling; + + make_root_and_link(p_cur); + + p_cur = p_next; + } + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + } + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +join(PB_DS_CLASS_C_DEC& other) +{ + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + + node_pointer p_other = other.m_p_root; + + while (p_other != NULL) + { + node_pointer p_next = p_other->m_p_next_sibling; + + make_root_and_link(p_other); + + p_other = p_next; + } + + base_type::m_size += other.m_size; + + other.m_p_root = NULL; + other.m_size = 0; + other.m_p_max = NULL; + + _GLIBCXX_DEBUG_ONLY(assert_valid();) + _GLIBCXX_DEBUG_ONLY(other.assert_valid();) + } diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/thin_heap_/thin_heap_.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/thin_heap_/thin_heap_.hpp new file mode 100644 index 000000000000..6d1f4ba9ca87 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/thin_heap_/thin_heap_.hpp @@ -0,0 +1,357 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file thin_heap_.hpp + * Contains an implementation class for a thin heap. + */ + +#ifndef PB_DS_THIN_HEAP_HPP +#define PB_DS_THIN_HEAP_HPP + +/* + * Thin heaps. + * Tarjan and Kaplan. + */ + +#include <algorithm> +#include <ext/pb_ds/detail/cond_dealtor.hpp> +#include <ext/pb_ds/detail/type_utils.hpp> +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/left_child_next_sibling_heap_.hpp> +#include <ext/pb_ds/detail/left_child_next_sibling_heap_/null_metadata.hpp> +#include <debug/debug.h> + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_CLASS_T_DEC \ + template<typename Value_Type, class Cmp_Fn, class Allocator> + +#define PB_DS_CLASS_C_DEC \ + thin_heap_<Value_Type, Cmp_Fn, Allocator> + +#ifdef _GLIBCXX_DEBUG +#define PB_DS_BASE_C_DEC \ + left_child_next_sibling_heap_<Value_Type, Cmp_Fn, \ + typename Allocator::size_type, Allocator, true> +#else +#define PB_DS_BASE_C_DEC \ + left_child_next_sibling_heap_<Value_Type, Cmp_Fn, \ + typename Allocator::size_type, Allocator> +#endif + + /** + * class description = "t|-|i|\| h34p"> + **/ + template<typename Value_Type, class Cmp_Fn, class Allocator> + class thin_heap_ : public PB_DS_BASE_C_DEC + { + + private: + typedef PB_DS_BASE_C_DEC base_type; + + protected: + typedef typename base_type::node node; + + typedef typename base_type::node_pointer node_pointer; + + typedef typename base_type::const_node_pointer const_node_pointer; + + public: + + typedef typename Allocator::size_type size_type; + + typedef typename Allocator::difference_type difference_type; + + typedef Value_Type value_type; + + typedef + typename Allocator::template rebind< + value_type>::other::pointer + pointer; + + typedef + typename Allocator::template rebind< + value_type>::other::const_pointer + const_pointer; + + typedef + typename Allocator::template rebind< + value_type>::other::reference + reference; + + typedef + typename Allocator::template rebind< + value_type>::other::const_reference + const_reference; + + typedef + typename PB_DS_BASE_C_DEC::const_point_iterator + const_point_iterator; + + typedef typename PB_DS_BASE_C_DEC::point_iterator point_iterator; + + typedef typename PB_DS_BASE_C_DEC::const_iterator const_iterator; + + typedef typename PB_DS_BASE_C_DEC::iterator iterator; + + typedef Cmp_Fn cmp_fn; + + typedef Allocator allocator; + + public: + + inline point_iterator + push(const_reference r_val); + + void + modify(point_iterator it, const_reference r_new_val); + + inline const_reference + top() const; + + void + pop(); + + void + erase(point_iterator it); + + inline void + clear(); + + template<typename Pred> + size_type + erase_if(Pred pred); + + template<typename Pred> + void + split(Pred pred, PB_DS_CLASS_C_DEC& other); + + void + join(PB_DS_CLASS_C_DEC& other); + + protected: + + thin_heap_(); + + thin_heap_(const Cmp_Fn& r_cmp_fn); + + thin_heap_(const PB_DS_CLASS_C_DEC& other); + + void + swap(PB_DS_CLASS_C_DEC& other); + + ~thin_heap_(); + + template<typename It> + void + copy_from_range(It first_it, It last_it); + +#ifdef _GLIBCXX_DEBUG + void + assert_valid() const; + + void + assert_max() const; +#endif + +#ifdef PB_DS_THIN_HEAP_TRACE_ + void + trace() const; +#endif + + private: + enum + { + max_rank = (sizeof(size_type) << 4) + 2 + }; + + private: + + void + initialize(); + + inline void + update_max(node_pointer p_nd); + + inline void + fix(node_pointer p_nd); + + inline void + fix_root(node_pointer p_y); + + inline void + fix_sibling_rank_1_unmarked(node_pointer p_y); + + inline void + fix_sibling_rank_1_marked(node_pointer p_y); + + inline void + fix_sibling_general_unmarked(node_pointer p_y); + + inline void + fix_sibling_general_marked(node_pointer p_y); + + inline void + fix_child(node_pointer p_y); + + inline static void + make_root(node_pointer p_nd); + + inline void + make_root_and_link(node_pointer p_nd); + + inline void + remove_max_node(); + + void + to_aux_except_max(); + + inline void + add_to_aux(node_pointer p_nd); + + inline void + make_from_aux(); + + inline size_type + rank_bound(); + + inline void + make_child_of(node_pointer p_nd, node_pointer p_new_parent); + + inline void + remove_node(node_pointer p_nd); + + inline node_pointer + join(node_pointer p_lhs, node_pointer p_rhs) const; + +#ifdef _GLIBCXX_DEBUG + void + assert_node_consistent(const_node_pointer p_nd, bool root) const; + + void + assert_aux_null() const; +#endif + + private: + node_pointer m_p_max; + + node_pointer m_a_aux[max_rank]; + }; + + enum + { + num_distinct_rank_bounds = 48 + }; + + // Taken from the SGI implementation; acknowledged in the docs. + static const std::size_t g_a_rank_bounds[num_distinct_rank_bounds] = + { + /* Dealing cards... */ + /* 0 */ 0ul, + /* 1 */ 1ul, + /* 2 */ 1ul, + /* 3 */ 2ul, + /* 4 */ 4ul, + /* 5 */ 6ul, + /* 6 */ 11ul, + /* 7 */ 17ul, + /* 8 */ 29ul, + /* 9 */ 46ul, + /* 10 */ 76ul, + /* 11 */ 122ul, + /* 12 */ 199ul, + /* 13 */ 321ul, + /* 14 */ 521ul, + /* 15 */ 842ul, + /* 16 */ 1364ul, + /* 17 */ 2206ul, + /* 18 */ 3571ul, + /* 19 */ 5777ul, + /* 20 */ 9349ul, + /* 21 */ 15126ul, + /* 22 */ 24476ul, + /* 23 */ 39602ul, + /* 24 */ 64079ul, + /* 25 */ 103681ul, + /* 26 */ 167761ul, + /* 27 */ 271442ul, + /* 28 */ 439204ul, + /* 29 */ 710646ul, + /* 30 */ 1149851ul, + /* 31 */ 1860497ul, + /* 32 */ 3010349ul, + /* 33 */ 4870846ul, + /* 34 */ 7881196ul, + /* 35 */ 12752042ul, + /* 36 */ 20633239ul, + /* 37 */ 33385282ul, + /* 38 */ 54018521ul, + /* 39 */ 87403803ul, + /* 40 */ 141422324ul, + /* 41 */ 228826127ul, + /* 42 */ 370248451ul, + /* 43 */ 599074578ul, + /* 44 */ 969323029ul, + /* 45 */ 1568397607ul, + /* 46 */ 2537720636ul, + /* 47 */ 4106118243ul + /* Pot's good, let's play */ + }; + +#include <ext/pb_ds/detail/thin_heap_/constructors_destructor_fn_imps.hpp> +#include <ext/pb_ds/detail/thin_heap_/debug_fn_imps.hpp> +#include <ext/pb_ds/detail/thin_heap_/trace_fn_imps.hpp> +#include <ext/pb_ds/detail/thin_heap_/find_fn_imps.hpp> +#include <ext/pb_ds/detail/thin_heap_/insert_fn_imps.hpp> +#include <ext/pb_ds/detail/thin_heap_/erase_fn_imps.hpp> +#include <ext/pb_ds/detail/thin_heap_/split_join_fn_imps.hpp> + +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_BASE_C_DEC + + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/thin_heap_/trace_fn_imps.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/thin_heap_/trace_fn_imps.hpp new file mode 100644 index 000000000000..a4f9c8784ff3 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/thin_heap_/trace_fn_imps.hpp @@ -0,0 +1,61 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file trace_fn_imps.hpp + * Contains an implementation class for left_child_next_sibling_heap_. + */ + +#ifdef PB_DS_THIN_HEAP_TRACE_ + +PB_DS_CLASS_T_DEC +void +PB_DS_CLASS_C_DEC:: +trace() const +{ + std::cerr << std::endl; + + std::cerr << "m_p_max " << m_p_max << std::endl; + + base_type::trace(); +} + +#endif // #ifdef PB_DS_THIN_HEAP_TRACE_ diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/tree_policy/node_metadata_selector.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/tree_policy/node_metadata_selector.hpp new file mode 100644 index 000000000000..3fd7dc9ac881 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/tree_policy/node_metadata_selector.hpp @@ -0,0 +1,122 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file node_metadata_selector.hpp + * Contains an implementation class for trees. + */ + +#ifndef PB_DS_TREE_NODE_METADATA_SELECTOR_HPP +#define PB_DS_TREE_NODE_METADATA_SELECTOR_HPP + +#include <ext/pb_ds/detail/basic_tree_policy/null_node_metadata.hpp> +#include <ext/pb_ds/detail/types_traits.hpp> + +namespace pb_ds +{ + namespace detail + { + + template<typename Node_Update, bool Null> + struct tree_metadata_helper + { + typedef typename Node_Update::metadata_type type; + }; + + template<typename Node_Update> + struct tree_metadata_helper< + Node_Update, + true> + { + typedef null_node_metadata type; + }; + + template<typename Key, + typename Data, + class Cmp_Fn, + template<typename Const_Node_Iterator, + class Const_Iterator, + class Cmp_Fn_, + class Allocator_> + class Node_Update, + class Allocator> + struct tree_node_metadata_selector + { + private: + typedef + dumconst_node_iterator< + Key, + Data, + Allocator> + dumconst_node_it; + + enum + { + null_update = + is_same< + Node_Update< + dumconst_node_it, + dumconst_node_it, + Cmp_Fn, + Allocator>, + null_tree_node_update< + dumconst_node_it, + dumconst_node_it, + Cmp_Fn, + Allocator> >::value + }; + + public: + typedef + typename tree_metadata_helper< + Node_Update< + dumconst_node_it, + dumconst_node_it, + Cmp_Fn, + Allocator>, + null_update>::type + type; + }; + + } // namespace detail +} // namespace pb_ds + +#endif // #ifndef PB_DS_TREE_NODE_METADATA_SELECTOR_HPP diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/tree_policy/null_node_update_imp.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/tree_policy/null_node_update_imp.hpp new file mode 100644 index 000000000000..d9c596798c18 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/tree_policy/null_node_update_imp.hpp @@ -0,0 +1,56 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file null_node_update_imp.hpp + * Contains an implementation of null_node_update. + */ + +PB_DS_CLASS_T_DEC +template<typename Const_Node_Iterator_, + typename Node_Iterator_, + class Cmp_Fn_, + typename Allocator_> +inline void +PB_DS_CLASS_C_DEC:: +swap(null_tree_node_update< Const_Node_Iterator_, Node_Iterator_, Cmp_Fn_, Allocator_>& /*other*/) +{ } + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/tree_policy/order_statistics_imp.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/tree_policy/order_statistics_imp.hpp new file mode 100644 index 000000000000..85f4d166a56a --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/tree_policy/order_statistics_imp.hpp @@ -0,0 +1,147 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file order_statistics_imp.hpp + * Contains forward declarations for order_statistics_key + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +find_by_order(size_type order) +{ + node_iterator it = node_begin(); + + node_iterator end_it = node_end(); + + while (it != end_it) + { + node_iterator l_it = it.get_l_child(); + + const size_type o = (l_it == end_it)? + 0 : + l_it.get_metadata(); + + if (order == o) + return (*it); + else if (order < o) + it = l_it; + else + { + order -= o + 1; + + it = it.get_r_child(); + } + } + + return (PB_DS_BASE_C_DEC::end_iterator()); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +find_by_order(size_type order) const +{ + return (const_cast<PB_DS_CLASS_C_DEC* >(this)->find_by_order(order)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +order_of_key(const_key_reference r_key) const +{ + const_node_iterator it = node_begin(); + + const_node_iterator end_it = node_end(); + + const cmp_fn& r_cmp_fn = + const_cast<PB_DS_CLASS_C_DEC* >(this)->get_cmp_fn(); + + size_type ord = 0; + + while (it != end_it) + { + const_node_iterator l_it = it.get_l_child(); + + if (r_cmp_fn(r_key, extract_key(*(*it)))) + it = l_it; + else if (r_cmp_fn(extract_key(*(*it)), r_key)) + { + + ord += (l_it == end_it)? + 1 : + 1 + l_it.get_metadata(); + + it = it.get_r_child(); + } + else + { + ord += (l_it == end_it)? + 0 : + l_it.get_metadata(); + + it = end_it; + } + } + + return (ord); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +operator()(node_iterator node_it, const_node_iterator end_nd_it) const +{ + node_iterator l_child_it = node_it.get_l_child(); + const size_type l_rank =(l_child_it == end_nd_it)? 0 : l_child_it.get_metadata(); + + node_iterator r_child_it = node_it.get_r_child(); + const size_type r_rank =(r_child_it == end_nd_it)? 0 : r_child_it.get_metadata(); + + const_cast<metadata_reference>(node_it.get_metadata())= + 1 + l_rank + r_rank; +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +~tree_order_statistics_node_update() +{ } diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/tree_policy/sample_tree_node_update.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/tree_policy/sample_tree_node_update.hpp new file mode 100644 index 000000000000..5b7d7c51aace --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/tree_policy/sample_tree_node_update.hpp @@ -0,0 +1,78 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file sample_tree_node_update.hpp + * Contains a samle node update functor. + */ + +#ifndef PB_DS_SAMPLE_TREE_NODE_UPDATOR_HPP +#define PB_DS_SAMPLE_TREE_NODE_UPDATOR_HPP + +// A sample node updator. +template<typename Const_Node_Iterator, + + class Node_Iterator, + + class Cmp_Fn, + + class Allocator + > +class sample_tree_node_update +{ + +public: + + // Metadata type. + typedef size_t metadata_type; + +protected: + + // Default constructor. + sample_tree_node_update(); + + // Updates the rank of a node through a node_iterator node_it; end_nd_it is the end node iterator. + inline void + operator()(node_iterator node_it, const_node_iterator end_nd_it) const; + +}; + +#endif // #ifndef PB_DS_SAMPLE_TREE_NODE_UPDATOR_HPP diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/tree_trace_base.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/tree_trace_base.hpp new file mode 100644 index 000000000000..791f2fc6f2d2 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/tree_trace_base.hpp @@ -0,0 +1,215 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file tree_trace_base.hpp + * Contains tree-related policies. + */ + +#ifndef PB_DS_TREE_TRACE_BASE_HPP +#define PB_DS_TREE_TRACE_BASE_HPP + +#ifdef PB_DS_TREE_TRACE + +#include <ext/pb_ds/detail/basic_tree_policy/basic_tree_policy_base.hpp> +#include <ext/pb_ds/detail/basic_tree_policy/null_node_metadata.hpp> + +namespace pb_ds +{ + + namespace detail + { + +#ifdef PB_DS_TREE_TRACE + +#define PB_DS_CLASS_T_DEC \ + template< \ + class Const_Node_Iterator, \ + class Node_Iterator, \ + class Cmp_Fn, \ + bool Node_Based, \ + class Allocator> + +#define PB_DS_CLASS_C_DEC \ + tree_trace_base< \ + Const_Node_Iterator, \ + Node_Iterator, \ + Cmp_Fn, \ + Node_Based, \ + Allocator> + +#define PB_DS_BASE_C_DEC \ + basic_tree_policy_base< \ + Const_Node_Iterator, \ + Node_Iterator, \ + Allocator> + + template<typename Const_Node_Iterator, + class Node_Iterator, + class Cmp_Fn, + bool Node_Based, + class Allocator> + class tree_trace_base : private PB_DS_BASE_C_DEC + { + public: + void + trace() const; + + private: + typedef PB_DS_BASE_C_DEC base_type; + + typedef Const_Node_Iterator const_node_iterator; + + typedef typename Allocator::size_type size_type; + + private: + void + trace_node(const_node_iterator nd_it, size_type level) const; + + virtual bool + empty() const = 0; + + virtual const_node_iterator + node_begin() const = 0; + + virtual const_node_iterator + node_end() const = 0; + + static void + print_node_pointer(Const_Node_Iterator nd_it, integral_constant<int,true>); + + static void + print_node_pointer(Const_Node_Iterator nd_it, integral_constant<int,false>); + + template<typename Metadata_> + static void + trace_it_metadata(Const_Node_Iterator nd_it, type_to_type<Metadata_>); + + static void + trace_it_metadata(Const_Node_Iterator, type_to_type<null_node_metadata>); + }; + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + trace() const + { + if (empty()) + return; + + trace_node(node_begin(), 0); + } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + trace_node(const_node_iterator nd_it, size_type level) const + { + if (nd_it.get_r_child() != node_end()) + trace_node(nd_it.get_r_child(), level + 1); + + for (size_type i = 0; i < level; ++i) + std::cerr << ' '; + + print_node_pointer(nd_it, integral_constant<int,Node_Based>()); + std::cerr << base_type::extract_key(*(*nd_it)); + + typedef + type_to_type< + typename const_node_iterator::metadata_type> + m_type_ind_t; + + trace_it_metadata(nd_it, m_type_ind_t()); + + std::cerr << std::endl; + + if (nd_it.get_l_child() != node_end()) + trace_node(nd_it.get_l_child(), level + 1); + } + + PB_DS_CLASS_T_DEC + template<typename Metadata_> + void + PB_DS_CLASS_C_DEC:: + trace_it_metadata(Const_Node_Iterator nd_it, type_to_type<Metadata_>) + { + std::cerr << " (" << + static_cast<unsigned long>(nd_it.get_metadata()) << ") "; + } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + trace_it_metadata(Const_Node_Iterator, type_to_type<null_node_metadata>) + { } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + print_node_pointer(Const_Node_Iterator nd_it, integral_constant<int,true>) + { + std::cerr << nd_it.m_p_nd << " "; + } + + PB_DS_CLASS_T_DEC + void + PB_DS_CLASS_C_DEC:: + print_node_pointer(Const_Node_Iterator nd_it, integral_constant<int,false>) + { + std::cerr <<* nd_it << " "; + } + +#undef PB_DS_CLASS_T_DEC + +#undef PB_DS_CLASS_C_DEC + +#undef PB_DS_BASE_C_DEC + +#endif // #ifdef PB_DS_TREE_TRACE + + } // namespace detail + +} // namespace pb_ds + +#endif // #ifdef PB_DS_TREE_TRACE + +#endif // #ifndef PB_DS_TREE_TRACE_BASE_HPP + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/trie_policy/node_metadata_selector.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/trie_policy/node_metadata_selector.hpp new file mode 100644 index 000000000000..ed9e1aac6e00 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/trie_policy/node_metadata_selector.hpp @@ -0,0 +1,122 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file node_metadata_selector.hpp + * Contains an implementation class for tries. + */ + +#ifndef PB_DS_TRIE_NODE_METADATA_SELECTOR_HPP +#define PB_DS_TRIE_NODE_METADATA_SELECTOR_HPP + +#include <ext/pb_ds/detail/basic_tree_policy/null_node_metadata.hpp> +#include <ext/pb_ds/detail/types_traits.hpp> + +namespace pb_ds +{ + namespace detail + { + + template<typename Node_Update, bool Null> + struct trie_metadata_helper + { + typedef typename Node_Update::metadata_type type; + }; + + template<typename Node_Update> + struct trie_metadata_helper< + Node_Update, + true> + { + typedef null_node_metadata type; + }; + + template<typename Key, + typename Data, + class Cmp_Fn, + template<typename Const_Node_Iterator, + class Const_Iterator, + class Cmp_Fn_, + class Allocator_> + class Node_Update, + class Allocator> + struct trie_node_metadata_selector + { + private: + typedef + dumconst_node_iterator< + Key, + Data, + Allocator> + dumconst_node_it; + + enum + { + null_update = + is_same< + Node_Update< + dumconst_node_it, + dumconst_node_it, + Cmp_Fn, + Allocator>, + null_trie_node_update< + dumconst_node_it, + dumconst_node_it, + Cmp_Fn, + Allocator> >::value + }; + + public: + typedef + typename trie_metadata_helper< + Node_Update< + dumconst_node_it, + dumconst_node_it, + Cmp_Fn, + Allocator>, + null_update>::type + type; + }; + + } // namespace detail +} // namespace pb_ds + +#endif // #ifndef PB_DS_TRIE_NODE_METADATA_SELECTOR_HPP diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/trie_policy/null_node_update_imp.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/trie_policy/null_node_update_imp.hpp new file mode 100644 index 000000000000..cb0b57fa7608 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/trie_policy/null_node_update_imp.hpp @@ -0,0 +1,56 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file null_node_update_imp.hpp + * Contains an implementation of null_node_update. + */ + +PB_DS_CLASS_T_DEC +template<typename Const_Node_Iterator_, + typename Node_Iterator_, + class E_Access_Traits_, + typename Allocator_> +inline void +PB_DS_CLASS_C_DEC:: +swap(null_trie_node_update< Const_Node_Iterator_, Node_Iterator_, E_Access_Traits_, Allocator_>& /*other*/) +{ } + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/trie_policy/order_statistics_imp.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/trie_policy/order_statistics_imp.hpp new file mode 100644 index 000000000000..9351217ed1dd --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/trie_policy/order_statistics_imp.hpp @@ -0,0 +1,189 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file order_statistics_imp.hpp + * Contains forward declarations for order_statistics_key + */ + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::iterator +PB_DS_CLASS_C_DEC:: +find_by_order(size_type order) +{ + if (empty()) + return (end()); + + ++order; + + node_iterator nd_it = node_begin(); + + node_iterator end_nd_it = node_end(); + + while (true) + { + if (order > nd_it.get_metadata()) + return (++base_type::rightmost_it(nd_it)); + + const size_type num_children = nd_it.num_children(); + + if (num_children == 0) + return (*nd_it); + + for (size_type i = 0; i < num_children; ++i) + { + node_iterator child_nd_it = nd_it.get_child(i); + + if (order <= child_nd_it.get_metadata()) + { + i = num_children; + + nd_it = child_nd_it; + } + else + order -= child_nd_it.get_metadata(); + } + } +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +find_by_order(size_type order) const +{ + return (const_cast<PB_DS_CLASS_C_DEC* >(this)->find_by_order(order)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +order_of_key(const_key_reference r_key) const +{ + const E_Access_Traits& r_traits = + const_cast<PB_DS_CLASS_C_DEC* >(this)->get_e_access_traits(); + + return (order_of_prefix( + r_traits.begin(r_key), + r_traits.end(r_key))); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +order_of_prefix(typename e_access_traits::const_iterator b, typename e_access_traits::const_iterator e) const +{ + if (empty()) + return (0); + + const E_Access_Traits& r_traits = + const_cast<PB_DS_CLASS_C_DEC* >(this)->get_e_access_traits(); + + const_node_iterator nd_it = node_begin(); + + const_node_iterator end_nd_it = node_end(); + + size_type ord = 0; + + while (true) + { + const size_type num_children = nd_it.num_children(); + + if (num_children == 0) + { + const_key_reference r_key = + base_type::extract_key(*(*nd_it)); + + typename e_access_traits::const_iterator key_b = + r_traits.begin(r_key); + + typename e_access_traits::const_iterator key_e = + r_traits.end(r_key); + + return ((base_type::less( key_b, key_e, b, e, r_traits))? + ord + 1 : + ord); + } + + const_node_iterator next_nd_it = end_nd_it; + + size_type i = num_children - 1; + + do + { + const_node_iterator child_nd_it = nd_it.get_child(i); + + if (next_nd_it != end_nd_it) + ord += child_nd_it.get_metadata(); + else if (!base_type::less( + b, e, + child_nd_it.valid_prefix().first, + child_nd_it.valid_prefix().second, + r_traits)) + next_nd_it = child_nd_it; + } + while (i-- > 0); + + if (next_nd_it == end_nd_it) + return (ord); + + nd_it = next_nd_it; + } +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +operator()(node_iterator nd_it, const_node_iterator /*end_nd_it*/) const +{ + const size_type num_children = nd_it.num_children(); + + size_type children_rank = 0; + + for (size_type i = 0; i < num_children; ++i) + children_rank += nd_it.get_child(i).get_metadata(); + + const_cast<size_type& >(nd_it.get_metadata()) =(num_children == 0)? 1 : children_rank; +} + +PB_DS_CLASS_T_DEC +PB_DS_CLASS_C_DEC:: +~trie_order_statistics_node_update() +{ } diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/trie_policy/prefix_search_node_update_imp.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/trie_policy/prefix_search_node_update_imp.hpp new file mode 100644 index 000000000000..c74290ebf04c --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/trie_policy/prefix_search_node_update_imp.hpp @@ -0,0 +1,157 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file prefix_search_node_update_imp.hpp + * Contains an implementation of prefix_search_node_update. + */ + +PB_DS_CLASS_T_DEC +std::pair< + typename PB_DS_CLASS_C_DEC::const_iterator, + typename PB_DS_CLASS_C_DEC::const_iterator> +PB_DS_CLASS_C_DEC:: +prefix_range(const_key_reference r_key) const +{ + const e_access_traits& r_traits = get_e_access_traits(); + + return (prefix_range( + r_traits.begin(r_key), + r_traits.end(r_key))); +} + +PB_DS_CLASS_T_DEC +std::pair< + typename PB_DS_CLASS_C_DEC::iterator, + typename PB_DS_CLASS_C_DEC::iterator> +PB_DS_CLASS_C_DEC:: +prefix_range(const_key_reference r_key) +{ + return (prefix_range( + get_e_access_traits().begin(r_key), + get_e_access_traits().end(r_key))); +} + +PB_DS_CLASS_T_DEC +std::pair< + typename PB_DS_CLASS_C_DEC::const_iterator, + typename PB_DS_CLASS_C_DEC::const_iterator> +PB_DS_CLASS_C_DEC:: +prefix_range(typename e_access_traits::const_iterator b, typename e_access_traits::const_iterator e) const +{ + const std::pair<iterator, iterator> non_const_ret = + const_cast<PB_DS_CLASS_C_DEC* >(this)->prefix_range(b, e); + + return (std::make_pair( + const_iterator(non_const_ret.first), + const_iterator(non_const_ret.second))); +} + +PB_DS_CLASS_T_DEC +std::pair< + typename PB_DS_CLASS_C_DEC::iterator, + typename PB_DS_CLASS_C_DEC::iterator> +PB_DS_CLASS_C_DEC:: +prefix_range(typename e_access_traits::const_iterator b, typename e_access_traits::const_iterator e) +{ + Node_Iterator nd_it = node_begin(); + Node_Iterator end_nd_it = node_end(); + + const e_access_traits& r_traits = + get_e_access_traits(); + + const size_type given_range_length = std::distance(b, e); + + while (true) + { + if (nd_it == end_nd_it) + return (std::make_pair(end(), end())); + + const size_type common_range_length = + PB_DS_BASE_C_DEC::common_prefix_len(nd_it, b, e, r_traits); + + if (common_range_length >= given_range_length) + { + iterator ret_b = leftmost_it(nd_it); + + iterator ret_e = rightmost_it(nd_it); + + return (std::make_pair(ret_b, ++ret_e)); + } + + nd_it = next_child(nd_it, b, e, end_nd_it, r_traits); + } +} + +PB_DS_CLASS_T_DEC +typename PB_DS_CLASS_C_DEC::node_iterator +PB_DS_CLASS_C_DEC:: +next_child(node_iterator nd_it, typename e_access_traits::const_iterator b, typename e_access_traits::const_iterator e, node_iterator end_nd_it, const e_access_traits& r_traits) +{ + const size_type num_children = nd_it.num_children(); + + node_iterator ret = end_nd_it; + + size_type max_length = 0; + + for (size_type i = 0; i < num_children; ++i) + { + node_iterator pot = nd_it.get_child(i); + + const size_type common_range_length = + PB_DS_BASE_C_DEC::common_prefix_len( pot, b, e, r_traits); + + if (common_range_length > max_length) + { + ret = pot; + + max_length = common_range_length; + } + } + + return (ret); +} + +PB_DS_CLASS_T_DEC +inline void +PB_DS_CLASS_C_DEC:: +operator()(node_iterator /*nd_it*/, const_node_iterator /*end_nd_it*/) const +{ } diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/trie_policy/sample_trie_e_access_traits.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/trie_policy/sample_trie_e_access_traits.hpp new file mode 100644 index 000000000000..954f47995c53 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/trie_policy/sample_trie_e_access_traits.hpp @@ -0,0 +1,95 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file sample_trie_e_access_traits.hpp + * Contains a sample probe policy. + */ + +#ifndef PB_DS_SAMPLE_TRIE_E_ACCESS_TRAITS_HPP +#define PB_DS_SAMPLE_TRIE_E_ACCESS_TRAITS_HPP + +// A sample trie element-access traits. +class sample_trie_e_access_traits +{ + +public: + + // Size type. + typedef size_t size_type; + + // Key type. + typedef std::string key_type; + + // Const key reference type. + typedef + typename Allocator::template rebind< + key_type>::other::const_reference + const_key_reference; + + // Element const iterator type. + typedef std::string::const_iterator const_iterator; + + // Element type. + typedef char e_type; + + enum + { + max_size = 4 + }; + +public: + + // Returns a const_iterator to the first element of r_key. + inline static const_iterator + begin(const_key_reference r_key); + + // Returns a const_iterator to the after-last element of r_key. + inline static const_iterator + end(const_key_reference r_key); + + // Maps an element to a position. + inline static size_type + e_pos(e_type e); + +}; + +#endif // #ifndef PB_DS_SAMPLE_TRIE_E_ACCESS_TRAITS_HPP diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/trie_policy/sample_trie_node_update.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/trie_policy/sample_trie_node_update.hpp new file mode 100644 index 000000000000..8a884c410b5b --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/trie_policy/sample_trie_node_update.hpp @@ -0,0 +1,78 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file sample_trie_node_update.hpp + * Contains a samle node update functor. + */ + +#ifndef PB_DS_SAMPLE_TRIE_NODE_UPDATOR_HPP +#define PB_DS_SAMPLE_TRIE_NODE_UPDATOR_HPP + +// A sample node updator. +template<typename Const_Node_Iterator, + + class Node_Iterator, + + class E_Access_Traits, + + class Allocator + > +class sample_trie_node_update +{ + +public: + + // Metadata type. + typedef size_t metadata_type; + +protected: + + // Default constructor. + sample_trie_node_update(); + + // Updates the rank of a node through a node_iterator node_it; end_nd_it is the end node iterator. + inline void + operator()(node_iterator node_it, const_node_iterator end_nd_it) const; + +}; + +#endif // #ifndef PB_DS_SAMPLE_TRIE_NODE_UPDATOR_HPP diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/trie_policy/string_trie_e_access_traits_imp.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/trie_policy/string_trie_e_access_traits_imp.hpp new file mode 100644 index 000000000000..c2fe1c6ca438 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/trie_policy/string_trie_e_access_traits_imp.hpp @@ -0,0 +1,105 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file string_trie_e_access_traits_imp.hpp + * Contains a policy for extracting character positions from + * a string for a vector-based PATRICIA tree + */ + +PB_DS_CLASS_T_DEC +detail::integral_constant<int, Reverse> PB_DS_CLASS_C_DEC::s_rev_ind; + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::size_type +PB_DS_CLASS_C_DEC:: +e_pos(e_type e) +{ + return (static_cast<size_type>(e - min_e_val)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +begin(const_key_reference r_key) +{ + return (begin_imp(r_key, s_rev_ind)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +end(const_key_reference r_key) +{ + return (end_imp(r_key, s_rev_ind)); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +begin_imp(const_key_reference r_key, detail::false_type) +{ + return (r_key.begin()); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +begin_imp(const_key_reference r_key, detail::true_type) +{ + return (r_key.rbegin()); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +end_imp(const_key_reference r_key, detail::false_type) +{ + return (r_key.end()); +} + +PB_DS_CLASS_T_DEC +inline typename PB_DS_CLASS_C_DEC::const_iterator +PB_DS_CLASS_C_DEC:: +end_imp(const_key_reference r_key, detail::true_type) +{ + return (r_key.rend()); +} diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/trie_policy/trie_policy_base.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/trie_policy/trie_policy_base.hpp new file mode 100644 index 000000000000..a8506ce68156 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/trie_policy/trie_policy_base.hpp @@ -0,0 +1,255 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file trie_policy_base.hpp + * Contains an implementation of trie_policy_base. + */ + +#ifndef PB_DS_TRIE_POLICY_BASE_HPP +#define PB_DS_TRIE_POLICY_BASE_HPP + +#include <ext/pb_ds/detail/basic_tree_policy/basic_tree_policy_base.hpp> + +namespace pb_ds +{ + namespace detail + { + +#define PB_DS_CLASS_T_DEC \ + template< \ + class Const_Node_Iterator, \ + class Node_Iterator, \ + class E_Access_Traits, \ + typename Allocator> + +#define PB_DS_CLASS_C_DEC \ + trie_policy_base< \ + Const_Node_Iterator, \ + Node_Iterator, \ + E_Access_Traits, \ + Allocator> + +#define PB_DS_BASE_C_DEC \ + basic_tree_policy_base< \ + Const_Node_Iterator, \ + Node_Iterator, \ + Allocator> + + template<typename Const_Node_Iterator, + class Node_Iterator, + class E_Access_Traits, + class Allocator> + class trie_policy_base : public PB_DS_BASE_C_DEC + { + + public: + + typedef E_Access_Traits e_access_traits; + + typedef Allocator allocator; + + typedef typename allocator::size_type size_type; + + typedef null_node_metadata metadata_type; + + typedef Const_Node_Iterator const_node_iterator; + + typedef Node_Iterator node_iterator; + + typedef typename const_node_iterator::value_type const_iterator; + + typedef typename node_iterator::value_type iterator; + + public: + + typedef typename PB_DS_BASE_C_DEC::key_type key_type; + + typedef + typename PB_DS_BASE_C_DEC::const_key_reference + const_key_reference; + + protected: + + virtual const_iterator + end() const = 0; + + virtual iterator + end() = 0; + + virtual const_node_iterator + node_begin() const = 0; + + virtual node_iterator + node_begin() = 0; + + virtual const_node_iterator + node_end() const = 0; + + virtual node_iterator + node_end() = 0; + + virtual const e_access_traits& + get_e_access_traits() const = 0; + + private: + typedef + std::pair< + typename e_access_traits::const_iterator, + typename e_access_traits::const_iterator> + prefix_range_t; + + typedef PB_DS_BASE_C_DEC base_type; + + protected: + static size_type + common_prefix_len(node_iterator nd_it, typename e_access_traits::const_iterator b_r, typename e_access_traits::const_iterator e_r, const e_access_traits& r_traits); + + static iterator + leftmost_it(node_iterator nd_it); + + static iterator + rightmost_it(node_iterator nd_it); + + static bool + less(typename e_access_traits::const_iterator b_l, typename e_access_traits::const_iterator e_l, typename e_access_traits::const_iterator b_r, typename e_access_traits::const_iterator e_r, const e_access_traits& r_traits); + }; + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::size_type + PB_DS_CLASS_C_DEC:: + common_prefix_len(node_iterator nd_it, typename e_access_traits::const_iterator b_r, typename e_access_traits::const_iterator e_r, const e_access_traits& r_traits) + { + prefix_range_t pref_range = nd_it.valid_prefix(); + + typename e_access_traits::const_iterator b_l = pref_range.first; + typename e_access_traits::const_iterator e_l = pref_range.second; + + const size_type range_length_l = + std::distance(b_l, e_l); + + const size_type range_length_r = + std::distance(b_r, e_r); + + if (range_length_r < range_length_l) + { + std::swap(b_l, b_r); + + std::swap(e_l, e_r); + } + + size_type ret = 0; + + while (b_l != e_l) + { + if (r_traits.e_pos(*b_l) != r_traits.e_pos(*b_r)) + return (ret); + + ++ret; + + ++b_l; + + ++b_r; + } + + return (ret); + } + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::iterator + PB_DS_CLASS_C_DEC:: + leftmost_it(node_iterator nd_it) + { + if (nd_it.num_children() == 0) + return (*nd_it); + + return (leftmost_it(nd_it.get_child(0))); + } + + PB_DS_CLASS_T_DEC + typename PB_DS_CLASS_C_DEC::iterator + PB_DS_CLASS_C_DEC:: + rightmost_it(node_iterator nd_it) + { + const size_type num_children = nd_it.num_children(); + + if (num_children == 0) + return (*nd_it); + + return (rightmost_it(nd_it.get_child(num_children - 1))); + } + + PB_DS_CLASS_T_DEC + bool + PB_DS_CLASS_C_DEC:: + less(typename e_access_traits::const_iterator b_l, typename e_access_traits::const_iterator e_l, typename e_access_traits::const_iterator b_r, typename e_access_traits::const_iterator e_r, const e_access_traits& r_traits) + { + while (b_l != e_l) + { + if (b_r == e_r) + return (false); + + size_type l_pos = + r_traits.e_pos(*b_l); + size_type r_pos = + r_traits.e_pos(*b_r); + + if (l_pos != r_pos) + return (l_pos < r_pos); + + ++b_l; + ++b_r; + } + + return (b_r != e_r); + } + +#undef PB_DS_CLASS_T_DEC + +#undef PB_DS_CLASS_C_DEC + +#undef PB_DS_BASE_C_DEC + + } // namespace detail +} // namespace pb_ds + +#endif // #ifndef PB_DS_TRIE_POLICY_BASE_HPP + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/type_utils.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/type_utils.hpp new file mode 100644 index 000000000000..e917fac0bdcf --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/type_utils.hpp @@ -0,0 +1,165 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file type_utils.hpp + * Contains utilities for handnling types. All of these classes are based on + * "Modern C++" by Andrei Alxandrescu. + */ + +#ifndef PB_DS_TYPE_UTILS_HPP +#define PB_DS_TYPE_UTILS_HPP + +#include <cstddef> +#include <utility> +#include <tr1/type_traits> +#include <ext/type_traits.h> +#include <ext/numeric_traits.h> + +namespace pb_ds +{ + namespace detail + { + using std::tr1::is_same; + using std::tr1::is_const; + using std::tr1::is_pointer; + using std::tr1::is_reference; + using std::tr1::is_fundamental; + using std::tr1::is_member_object_pointer; + using std::tr1::is_member_pointer; + using std::tr1::is_base_of; + using std::tr1::remove_const; + using std::tr1::remove_reference; + + // Need integral_const<bool, true> <-> integral_const<int, 1>, so + // because of this use the following typedefs instead of importing + // std::tr1's. + using std::tr1::integral_constant; + typedef std::tr1::integral_constant<int, 1> true_type; + typedef std::tr1::integral_constant<int, 0> false_type; + + using __gnu_cxx::__conditional_type; + using __gnu_cxx::__numeric_traits; + + template<typename T> + struct is_const_pointer + { + enum + { + value = is_const<T>::value && is_pointer<T>::value + }; + }; + + template<typename T> + struct is_const_reference + { + enum + { + value = is_const<T>::value && is_reference<T>::value + }; + }; + + template<typename T> + struct is_simple + { + enum + { + value = is_fundamental<typename remove_const<T>::type>::value + || is_pointer<typename remove_const<T>::type>::value + || is_member_pointer<T>::value + }; + }; + + template<typename T> + class is_pair + { + private: + template<typename U> + struct is_pair_imp + { + enum + { + value = 0 + }; + }; + + template<typename U, typename V> + struct is_pair_imp<std::pair<U,V> > + { + enum + { + value = 1 + }; + }; + + public: + enum + { + value = is_pair_imp<T>::value + }; + }; + + + template<bool> + struct static_assert; + + template<> + struct static_assert<true> + { }; + + template<int> + struct static_assert_dumclass + { + enum + { + v = 1 + }; + }; + + template<typename Type> + struct type_to_type + { + typedef Type type; + }; + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/types_traits.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/types_traits.hpp new file mode 100644 index 000000000000..8272c8a71a4c --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/types_traits.hpp @@ -0,0 +1,85 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file types_traits.hpp + * Contains a traits class of types used by containers. + */ + +#ifndef PB_DS_TYPES_TRAITS_HPP +#define PB_DS_TYPES_TRAITS_HPP + +#include <ext/pb_ds/detail/basic_types.hpp> +#include <ext/pb_ds/detail/type_utils.hpp> +#include <utility> + +namespace pb_ds +{ + namespace detail + { + template<typename Key, typename Mapped, typename Alloc, bool Store_Extra> + struct vt_base_selector + { + typedef value_type_base<Key, Mapped, Alloc, Store_Extra> type; + }; + + template<typename Key, typename Mapped, typename Alloc, bool Store_Extra> + struct types_traits + : public vt_base_selector<Key, Mapped, Alloc, Store_Extra>::type + { + typedef typename Alloc::template rebind<Key>::other key_allocator; + typedef typename key_allocator::value_type key_type; + typedef typename key_allocator::pointer key_pointer; + typedef typename key_allocator::const_pointer const_key_pointer; + typedef typename key_allocator::reference key_reference; + typedef typename key_allocator::const_reference const_key_reference; + typedef typename Alloc::size_type size_type; + + // Extra value (used when the extra value is stored with each value). + typedef std::pair<size_type, size_type> comp_hash; + + integral_constant<int, Store_Extra> m_store_extra_indicator; + typename no_throw_copies<Key, Mapped>::indicator m_no_throw_copies_indicator; + }; + } // namespace detail +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/unordered_iterator/const_iterator.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/unordered_iterator/const_iterator.hpp new file mode 100644 index 000000000000..84419e59a5eb --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/unordered_iterator/const_iterator.hpp @@ -0,0 +1,135 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file const_iterator.hpp + * Contains an iterator class used for const ranging over the elements of the + * table. + */ + +// Const range-type iterator. +class const_iterator_ : + public const_point_iterator_ + +{ + +public: + + // Category. + typedef std::forward_iterator_tag iterator_category; + + // Difference type. + typedef typename Allocator::difference_type difference_type; + + // Iterator's value type. + typedef value_type_ value_type; + + // Iterator's pointer type. + typedef pointer_ pointer; + + // Iterator's const pointer type. + typedef const_pointer_ const_pointer; + + // Iterator's reference type. + typedef reference_ reference; + + // Iterator's const reference type. + typedef const_reference_ const_reference; + +public: + + // Default constructor. + inline + const_iterator_() + + : m_p_tbl(NULL) + { } + + // Increments. + inline const_iterator_& + operator++() + { + m_p_tbl->inc_it_state(base_type::m_p_value, m_pos); + + return (*this); + } + + // Increments. + inline const_iterator_ + operator++(int) + { + const_iterator_ ret =* this; + + m_p_tbl->inc_it_state(base_type::m_p_value, m_pos); + + return (ret); + } + +protected: + + typedef const_point_iterator_ base_type; + +protected: + + /** + * Constructor used by the table to initiate the generalized + * pointer and position (e.g., this is called from within a find() + * of a table. + * */ + inline + const_iterator_(const_pointer_ p_value, PB_DS_GEN_POS pos, const PB_DS_CLASS_C_DEC* p_tbl) : const_point_iterator_(p_value), + m_p_tbl(p_tbl), + m_pos(pos) + { } + +protected: + + /** + * Pointer to the table object which created the iterator (used for + * incrementing its position. + * */ + const PB_DS_CLASS_C_DEC* m_p_tbl; + + PB_DS_GEN_POS m_pos; + + friend class PB_DS_CLASS_C_DEC; +}; + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/unordered_iterator/const_point_iterator.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/unordered_iterator/const_point_iterator.hpp new file mode 100644 index 000000000000..e1e93a5eed9a --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/unordered_iterator/const_point_iterator.hpp @@ -0,0 +1,157 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file const_point_iterator.hpp + * Contains an iterator class returned by the tables' const find and insert + * methods. + */ + +class point_iterator_; + +// Const point-type iterator. +class const_point_iterator_ +{ + +public: + + // Category. + typedef trivial_iterator_tag iterator_category; + + // Difference type. + typedef trivial_iterator_difference_type difference_type; + + // Iterator's value type. + typedef value_type_ value_type; + + // Iterator's pointer type. + typedef pointer_ pointer; + + // Iterator's const pointer type. + typedef const_pointer_ const_pointer; + + // Iterator's reference type. + typedef reference_ reference; + + // Iterator's const reference type. + typedef const_reference_ const_reference; + +public: + + inline + const_point_iterator_(const_pointer p_value) : m_p_value(p_value) + { } + + // Default constructor. + inline + const_point_iterator_() + + : m_p_value(NULL) + { } + + // Copy constructor. + inline + const_point_iterator_(const const_point_iterator_& other) + + : m_p_value(other.m_p_value) + { } + + // Copy constructor. + inline + const_point_iterator_(const point_iterator_& other) + + : m_p_value(other.m_p_value) + { } + + // Access. + inline const_pointer + operator->() const + { + _GLIBCXX_DEBUG_ASSERT(m_p_value != NULL); + + return (m_p_value); + } + + // Access. + inline const_reference + operator*() const + { + _GLIBCXX_DEBUG_ASSERT(m_p_value != NULL); + + return (*m_p_value); + } + + // Compares content to a different iterator object. + inline bool + operator==(const point_iterator_& other) const + { + return (m_p_value == other.m_p_value); + } + + // Compares content to a different iterator object. + inline bool + operator==(const const_point_iterator_& other) const + { + return (m_p_value == other.m_p_value); + } + + // Compares content (negatively) to a different iterator object. + inline bool + operator!=(const point_iterator_& other) const + { + return (m_p_value != other.m_p_value); + } + + // Compares content (negatively) to a different iterator object. + inline bool + operator!=(const const_point_iterator_& other) const + { + return (m_p_value != other.m_p_value); + } + +protected: + const_pointer m_p_value; + + friend class point_iterator_; + + friend class PB_DS_CLASS_C_DEC; +}; + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/unordered_iterator/iterator.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/unordered_iterator/iterator.hpp new file mode 100644 index 000000000000..11afafbbb576 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/unordered_iterator/iterator.hpp @@ -0,0 +1,156 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file iterator.hpp + * Contains an iterator_ class used for ranging over the elements of the + * table. + */ + +// Range-type iterator. +class iterator_ : + public const_iterator_ + +{ + +public: + + // Category. + typedef std::forward_iterator_tag iterator_category; + + // Difference type. + typedef typename Allocator::difference_type difference_type; + + // Iterator's value type. + typedef value_type_ value_type; + + // Iterator's pointer type. + typedef pointer_ pointer; + + // Iterator's const pointer type. + typedef const_pointer_ const_pointer; + + // Iterator's reference type. + typedef reference_ reference; + + // Iterator's const reference type. + typedef const_reference_ const_reference; + +public: + + // Default constructor. + inline + iterator_() + + : const_iterator_(NULL, PB_DS_GEN_POS(), NULL) + { } + + // Conversion to a point-type iterator. + inline + operator point_iterator_() + { + return (point_iterator_( + const_cast<pointer>(const_iterator_::m_p_value))); + } + + // Conversion to a point-type iterator. + inline + operator const point_iterator_() const + { + return (point_iterator_( + const_cast<pointer>(const_iterator_::m_p_value))); + } + + // Access. + inline pointer + operator->() const + { + _GLIBCXX_DEBUG_ASSERT(base_type::m_p_value != NULL); + + return (const_cast<pointer>(base_type::m_p_value)); + } + + // Access. + inline reference + operator*() const + { + _GLIBCXX_DEBUG_ASSERT(base_type::m_p_value != NULL); + + return (const_cast<reference>(*base_type::m_p_value)); + } + + // Increments. + inline iterator_& + operator++() + { + base_type::m_p_tbl->inc_it_state(base_type::m_p_value, base_type::m_pos); + + return (*this); + } + + // Increments. + inline iterator_ + operator++(int) + { + iterator_ ret =* this; + + base_type::m_p_tbl->inc_it_state(base_type::m_p_value, base_type::m_pos); + + return (ret); + } + +protected: + typedef const_iterator_ base_type; + +protected: + + /** + * Constructor used by the table to initiate the generalized + * pointer and position (e.g., this is called from within a find() + * of a table. + * */ + inline + iterator_(pointer p_value, PB_DS_GEN_POS pos, PB_DS_CLASS_C_DEC* p_tbl) : const_iterator_(p_value, pos, p_tbl) + { } + + friend class PB_DS_CLASS_C_DEC; +}; + diff --git a/contrib/libstdc++/include/ext/pb_ds/detail/unordered_iterator/point_iterator.hpp b/contrib/libstdc++/include/ext/pb_ds/detail/unordered_iterator/point_iterator.hpp new file mode 100644 index 000000000000..7b96425b1457 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/detail/unordered_iterator/point_iterator.hpp @@ -0,0 +1,149 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file point_iterator.hpp + * Contains an iterator class returned by the tables' find and insert + * methods. + */ + +// Find type iterator. +class point_iterator_ +{ + +public: + + // Category. + typedef trivial_iterator_tag iterator_category; + + // Difference type. + typedef trivial_iterator_difference_type difference_type; + + // Iterator's value type. + typedef value_type_ value_type; + + // Iterator's pointer type. + typedef pointer_ pointer; + + // Iterator's const pointer type. + typedef const_pointer_ const_pointer; + + // Iterator's reference type. + typedef reference_ reference; + + // Iterator's const reference type. + typedef const_reference_ const_reference; + +public: + + // Default constructor. + inline + point_iterator_() + + : m_p_value(NULL) + { } + + // Copy constructor. + inline + point_iterator_(const point_iterator_& other) + + : m_p_value(other.m_p_value) + { } + + // Access. + inline pointer + operator->() const + { + _GLIBCXX_DEBUG_ASSERT(m_p_value != NULL); + + return (m_p_value); + } + + // Access. + inline reference + operator*() const + { + _GLIBCXX_DEBUG_ASSERT(m_p_value != NULL); + + return (*m_p_value); + } + + // Compares content to a different iterator object. + inline bool + operator==(const point_iterator_& other) const + { + return (m_p_value == other.m_p_value); + } + + // Compares content to a different iterator object. + inline bool + operator==(const const_point_iterator_& other) const + { + return (m_p_value == other.m_p_value); + } + + // Compares content to a different iterator object. + inline bool + operator!=(const point_iterator_& other) const + { + return (m_p_value != other.m_p_value); + } + + // Compares content (negatively) to a different iterator object. + inline bool + operator!=(const const_point_iterator_& other) const + { + return (m_p_value != other.m_p_value); + } + + inline + point_iterator_(pointer p_value) : m_p_value(p_value) + { } + +protected: + friend class const_point_iterator_; + + friend class PB_DS_CLASS_C_DEC; + +protected: + pointer m_p_value; +}; + diff --git a/contrib/libstdc++/include/ext/pb_ds/exception.hpp b/contrib/libstdc++/include/ext/pb_ds/exception.hpp new file mode 100644 index 000000000000..896ff3918107 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/exception.hpp @@ -0,0 +1,108 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file exception.hpp + * Contains exception classes. + */ + +#ifndef PB_DS_EXCEPTION_HPP +#define PB_DS_EXCEPTION_HPP + +#include <stdexcept> + +namespace pb_ds +{ + // Base class for exceptions. + struct container_error : public std::logic_error + { + container_error() + : std::logic_error(__N("pb_ds::container_error")) { } + }; + + // An entry cannot be inserted into a container object for logical + // reasons (not, e.g., if memory is unabvailable, in which case + // the allocator's exception will be thrown). + struct insert_error : public container_error { }; + + // A join cannot be performed logical reasons (i.e., the ranges of + // the two container objects being joined overlaps. + struct join_error : public container_error { }; + + // A container cannot be resized. + struct resize_error : public container_error { }; + +#if __EXCEPTIONS + void + __throw_container_error(void) + { throw container_error(); } + + void + __throw_insert_error(void) + { throw insert_error(); } + + void + __throw_join_error(void) + { throw join_error(); } + + void + __throw_resize_error(void) + { throw resize_error(); } +#else + void + __throw_container_error(void) + { std::abort(); } + + void + __throw_insert_error(void) + { std::abort(); } + + void + __throw_join_error(void) + { std::abort(); } + + void + __throw_resize_error(void) + { std::abort(); } +#endif +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/hash_policy.hpp b/contrib/libstdc++/include/ext/pb_ds/hash_policy.hpp new file mode 100644 index 000000000000..c17d97831f8d --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/hash_policy.hpp @@ -0,0 +1,610 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file hash_policy.hpp + * Contains hash-related policies. + */ + +#ifndef PB_DS_HASH_POLICY_HPP +#define PB_DS_HASH_POLICY_HPP + +#include <algorithm> +#include <vector> +#include <cmath> +#include <ext/pb_ds/exception.hpp> +#include <ext/pb_ds/detail/type_utils.hpp> +#include <ext/pb_ds/detail/hash_fn/mask_based_range_hashing.hpp> +#include <ext/pb_ds/detail/hash_fn/mod_based_range_hashing.hpp> +#include <ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_size_base.hpp> + +namespace pb_ds +{ + // A null hash function, indicating that the combining hash function + // is actually a ranged hash function. + struct null_hash_fn + { }; + + // A null probe function, indicating that the combining probe + // function is actually a ranged probe function. + struct null_probe_fn + { }; + +#define PB_DS_CLASS_T_DEC template<typename Size_Type> +#define PB_DS_CLASS_C_DEC linear_probe_fn<Size_Type> + + // A probe sequence policy using fixed increments. + template<typename Size_Type = size_t> + class linear_probe_fn + { + public: + typedef Size_Type size_type; + + void + swap(PB_DS_CLASS_C_DEC& other); + + protected: + // Returns the i-th offset from the hash value. + inline size_type + operator()(size_type i) const; + }; + +#include <ext/pb_ds/detail/hash_fn/linear_probe_fn_imp.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +#define PB_DS_CLASS_T_DEC template<typename Size_Type> +#define PB_DS_CLASS_C_DEC quadratic_probe_fn<Size_Type> + + // A probe sequence policy using square increments. + template<typename Size_Type = size_t> + class quadratic_probe_fn + { + public: + typedef Size_Type size_type; + + void + swap(PB_DS_CLASS_C_DEC& other); + + protected: + // Returns the i-th offset from the hash value. + inline size_type + operator()(size_type i) const; + }; + +#include <ext/pb_ds/detail/hash_fn/quadratic_probe_fn_imp.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +#define PB_DS_CLASS_T_DEC template<typename Size_Type> +#define PB_DS_CLASS_C_DEC direct_mask_range_hashing<Size_Type> + + // A mask range-hashing class (uses a bit-mask). + template<typename Size_Type = size_t> + class direct_mask_range_hashing + : public detail::mask_based_range_hashing<Size_Type> + { + private: + typedef detail::mask_based_range_hashing<Size_Type> mask_based_base; + + public: + typedef Size_Type size_type; + + void + swap(PB_DS_CLASS_C_DEC& other); + + protected: + void + notify_resized(size_type size); + + // Transforms the __hash value hash into a ranged-hash value + // (using a bit-mask). + inline size_type + operator()(size_type hash) const; + }; + +#include <ext/pb_ds/detail/hash_fn/direct_mask_range_hashing_imp.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +#define PB_DS_CLASS_T_DEC template<typename Size_Type> +#define PB_DS_CLASS_C_DEC direct_mod_range_hashing<Size_Type> + + // A mod range-hashing class (uses the modulo function). + template<typename Size_Type = size_t> + class direct_mod_range_hashing + : public detail::mod_based_range_hashing<Size_Type> + { + public: + typedef Size_Type size_type; + + void + swap(PB_DS_CLASS_C_DEC& other); + + protected: + void + notify_resized(size_type size); + + // Transforms the __hash value hash into a ranged-hash value + // (using a modulo operation). + inline size_type + operator()(size_type hash) const; + + private: + typedef detail::mod_based_range_hashing<size_type> mod_based_base; + }; + +#include <ext/pb_ds/detail/hash_fn/direct_mod_range_hashing_imp.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +#define PB_DS_CLASS_T_DEC template<bool External_Load_Access, typename Size_Type> +#define PB_DS_CLASS_C_DEC hash_load_check_resize_trigger<External_Load_Access, Size_Type> +#define PB_DS_SIZE_BASE_C_DEC detail::hash_load_check_resize_trigger_size_base<Size_Type, External_Load_Access> + + // A resize trigger policy based on a load check. It keeps the + // load factor between some load factors load_min and load_max. + template<bool External_Load_Access = false, typename Size_Type = size_t> + class hash_load_check_resize_trigger : private PB_DS_SIZE_BASE_C_DEC + { + public: + typedef Size_Type size_type; + + enum + { + external_load_access = External_Load_Access + }; + + // Default constructor, or constructor taking load_min and + // load_max load factors between which this policy will keep the + // actual load. + hash_load_check_resize_trigger(float load_min = 0.125, + float load_max = 0.5); + + void + swap(hash_load_check_resize_trigger& other); + + virtual + ~hash_load_check_resize_trigger(); + + // Returns a pair of the minimal and maximal loads, respectively. + inline std::pair<float, float> + get_loads() const; + + // Sets the loads through a pair of the minimal and maximal + // loads, respectively. + void + set_loads(std::pair<float, float> load_pair); + + protected: + inline void + notify_insert_search_start(); + + inline void + notify_insert_search_collision(); + + inline void + notify_insert_search_end(); + + inline void + notify_find_search_start(); + + inline void + notify_find_search_collision(); + + inline void + notify_find_search_end(); + + inline void + notify_erase_search_start(); + + inline void + notify_erase_search_collision(); + + inline void + notify_erase_search_end(); + + // Notifies an element was inserted. The total number of entries + // in the table is num_entries. + inline void + notify_inserted(size_type num_entries); + + inline void + notify_erased(size_type num_entries); + + // Notifies the table was cleared. + void + notify_cleared(); + + // Notifies the table was resized as a result of this object's + // signifying that a resize is needed. + void + notify_resized(size_type new_size); + + void + notify_externally_resized(size_type new_size); + + inline bool + is_resize_needed() const; + + inline bool + is_grow_needed(size_type size, size_type num_entries) const; + + private: + virtual void + do_resize(size_type new_size); + + typedef PB_DS_SIZE_BASE_C_DEC size_base; + +#ifdef _GLIBCXX_DEBUG + void + assert_valid() const; +#endif + + float m_load_min; + float m_load_max; + size_type m_next_shrink_size; + size_type m_next_grow_size; + bool m_resize_needed; + }; + +#include <ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_imp.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_SIZE_BASE_C_DEC + +#define PB_DS_CLASS_T_DEC template<bool External_Load_Access, typename Size_Type> +#define PB_DS_CLASS_C_DEC cc_hash_max_collision_check_resize_trigger<External_Load_Access, Size_Type> + + // A resize trigger policy based on collision checks. It keeps the + // simulated load factor lower than some given load factor. + template<bool External_Load_Access = false, typename Size_Type = size_t> + class cc_hash_max_collision_check_resize_trigger + { + public: + typedef Size_Type size_type; + + enum + { + external_load_access = External_Load_Access + }; + + // Default constructor, or constructor taking load, a __load + // factor which it will attempt to maintain. + cc_hash_max_collision_check_resize_trigger(float load = 0.5); + + void + swap(PB_DS_CLASS_C_DEC& other); + + // Returns the current load. + inline float + get_load() const; + + // Sets the load; does not resize the container. + void + set_load(float load); + + protected: + inline void + notify_insert_search_start(); + + inline void + notify_insert_search_collision(); + + inline void + notify_insert_search_end(); + + inline void + notify_find_search_start(); + + inline void + notify_find_search_collision(); + + inline void + notify_find_search_end(); + + inline void + notify_erase_search_start(); + + inline void + notify_erase_search_collision(); + + inline void + notify_erase_search_end(); + + inline void + notify_inserted(size_type num_entries); + + inline void + notify_erased(size_type num_entries); + + void + notify_cleared(); + + // Notifies the table was resized as a result of this object's + // signifying that a resize is needed. + void + notify_resized(size_type new_size); + + void + notify_externally_resized(size_type new_size); + + inline bool + is_resize_needed() const; + + inline bool + is_grow_needed(size_type size, size_type num_entries) const; + + private: + void + calc_max_num_coll(); + + inline void + calc_resize_needed(); + + float m_load; + size_type m_size; + size_type m_num_col; + size_type m_max_col; + bool m_resize_needed; + }; + +#include <ext/pb_ds/detail/resize_policy/cc_hash_max_collision_check_resize_trigger_imp.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +#define PB_DS_CLASS_T_DEC template<typename Size_Type> +#define PB_DS_CLASS_C_DEC hash_exponential_size_policy<Size_Type> + + // A size policy whose sequence of sizes form an exponential + // sequence (typically powers of 2. + template<typename Size_Type = size_t> + class hash_exponential_size_policy + { + public: + typedef Size_Type size_type; + + // Default constructor, or onstructor taking a start_size, or + // constructor taking a start size and grow_factor. The policy + // will use the sequence of sizes start_size, start_size* + // grow_factor, start_size* grow_factor^2, ... + hash_exponential_size_policy(size_type start_size = 8, + size_type grow_factor = 2); + + void + swap(PB_DS_CLASS_C_DEC& other); + + protected: + size_type + get_nearest_larger_size(size_type size) const; + + size_type + get_nearest_smaller_size(size_type size) const; + + private: + size_type m_start_size; + size_type m_grow_factor; + }; + +#include <ext/pb_ds/detail/resize_policy/hash_exponential_size_policy_imp.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +#define PB_DS_CLASS_T_DEC +#define PB_DS_CLASS_C_DEC hash_prime_size_policy + + // A size policy whose sequence of sizes form a nearly-exponential + // sequence of primes. + class hash_prime_size_policy + { + public: + // Size type. + typedef size_t size_type; + + // Default constructor, or onstructor taking a start_size The + // policy will use the sequence of sizes approximately + // start_size, start_size* 2, start_size* 2^2, ... + hash_prime_size_policy(size_type start_size = 8); + + inline void + swap(PB_DS_CLASS_C_DEC& other); + + protected: + size_type + get_nearest_larger_size(size_type size) const; + + size_type + get_nearest_smaller_size(size_type size) const; + + private: + size_type m_start_size; + }; + +#include <ext/pb_ds/detail/resize_policy/hash_prime_size_policy_imp.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +#define PB_DS_CLASS_T_DEC template<typename Size_Policy, typename Trigger_Policy, bool External_Size_Access, typename Size_Type> + +#define PB_DS_CLASS_C_DEC hash_standard_resize_policy<Size_Policy, Trigger_Policy, External_Size_Access, Size_Type> + + // A resize policy which delegates operations to size and trigger policies. + template<typename Size_Policy = hash_exponential_size_policy<>, + typename Trigger_Policy = hash_load_check_resize_trigger<>, + bool External_Size_Access = false, + typename Size_Type = size_t> + class hash_standard_resize_policy + : public Size_Policy, public Trigger_Policy + { + public: + typedef Size_Type size_type; + typedef Trigger_Policy trigger_policy; + typedef Size_Policy size_policy; + + enum + { + external_size_access = External_Size_Access + }; + + // Default constructor. + hash_standard_resize_policy(); + + // constructor taking some policies r_size_policy will be copied + // by the Size_Policy object of this object. + hash_standard_resize_policy(const Size_Policy& r_size_policy); + + // constructor taking some policies. r_size_policy will be + // copied by the Size_Policy object of this + // object. r_trigger_policy will be copied by the Trigger_Policy + // object of this object. + hash_standard_resize_policy(const Size_Policy& r_size_policy, + const Trigger_Policy& r_trigger_policy); + + virtual + ~hash_standard_resize_policy(); + + inline void + swap(PB_DS_CLASS_C_DEC& other); + + // Access to the Size_Policy object used. + Size_Policy& + get_size_policy(); + + // Const access to the Size_Policy object used. + const Size_Policy& + get_size_policy() const; + + // Access to the Trigger_Policy object used. + Trigger_Policy& + get_trigger_policy(); + + // Access to the Trigger_Policy object used. + const Trigger_Policy& + get_trigger_policy() const; + + // Returns the actual size of the container. + inline size_type + get_actual_size() const; + + // Resizes the container to suggested_new_size, a suggested size + // (the actual size will be determined by the Size_Policy + // object). + void + resize(size_type suggested_new_size); + + protected: + inline void + notify_insert_search_start(); + + inline void + notify_insert_search_collision(); + + inline void + notify_insert_search_end(); + + inline void + notify_find_search_start(); + + inline void + notify_find_search_collision(); + + inline void + notify_find_search_end(); + + inline void + notify_erase_search_start(); + + inline void + notify_erase_search_collision(); + + inline void + notify_erase_search_end(); + + inline void + notify_inserted(size_type num_e); + + inline void + notify_erased(size_type num_e); + + void + notify_cleared(); + + void + notify_resized(size_type new_size); + + inline bool + is_resize_needed() const; + + // Queries what the new size should be, when the container is + // resized naturally. The current __size of the container is + // size, and the number of used entries within the container is + // num_used_e. + size_type + get_new_size(size_type size, size_type num_used_e) const; + + private: + // Resizes to new_size. + virtual void + do_resize(size_type new_size); + + typedef Trigger_Policy trigger_policy_base; + + typedef Size_Policy size_policy_base; + + size_type m_size; + }; + +#include <ext/pb_ds/detail/resize_policy/hash_standard_resize_policy_imp.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/list_update_policy.hpp b/contrib/libstdc++/include/ext/pb_ds/list_update_policy.hpp new file mode 100644 index 000000000000..cfe2a2c375e1 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/list_update_policy.hpp @@ -0,0 +1,141 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file list_update_policy.hpp + * Contains policies for list update containers. + */ + +#ifndef PB_DS_LU_POLICY_HPP +#define PB_DS_LU_POLICY_HPP + +#include <ext/pb_ds/detail/list_update_policy/counter_lu_metadata.hpp> + +namespace pb_ds +{ + // A null type that means that each link in a list-based container + // does not actually need metadata. + struct null_lu_metadata + { }; + +#define PB_DS_CLASS_T_DEC template<typename Allocator> +#define PB_DS_CLASS_C_DEC move_to_front_lu_policy<Allocator> + + // A list-update policy that unconditionally moves elements to the + // front of the list. + template<typename Allocator = std::allocator<char> > + class move_to_front_lu_policy + { + public: + typedef Allocator allocator; + + // Metadata on which this functor operates. + typedef null_lu_metadata metadata_type; + + // Reference to metadata on which this functor operates. + typedef typename allocator::template rebind<metadata_type>::other metadata_rebind; + typedef typename metadata_rebind::reference metadata_reference; + + // Creates a metadata object. + metadata_type + operator()() const; + + // Decides whether a metadata object should be moved to the front + // of the list. + inline bool + operator()(metadata_reference r_metadata) const; + + private: + static null_lu_metadata s_metadata; + }; + +#include <ext/pb_ds/detail/list_update_policy/mtf_lu_policy_imp.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +#define PB_DS_CLASS_T_DEC template<size_t Max_Count, class Allocator> +#define PB_DS_CLASS_C_DEC counter_lu_policy<Max_Count, Allocator> + + // A list-update policy that moves elements to the front of the list + // based on the counter algorithm. + template<size_t Max_Count = 5, typename Allocator = std::allocator<char> > + class counter_lu_policy + : private detail::counter_lu_policy_base<typename Allocator::size_type> + { + public: + typedef Allocator allocator; + + enum + { + max_count = Max_Count + }; + + typedef typename allocator::size_type size_type; + + // Metadata on which this functor operates. + typedef detail::counter_lu_metadata<size_type> metadata_type; + + // Reference to metadata on which this functor operates. + typedef typename Allocator::template rebind<metadata_type>::other metadata_rebind; + typedef typename metadata_rebind::reference metadata_reference; + + // Creates a metadata object. + metadata_type + operator()() const; + + // Decides whether a metadata object should be moved to the front + // of the list. + bool + operator()(metadata_reference r_metadata) const; + + private: + typedef detail::counter_lu_policy_base<typename Allocator::size_type> base_type; + }; + +#include <ext/pb_ds/detail/list_update_policy/counter_lu_policy_imp.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/priority_queue.hpp b/contrib/libstdc++/include/ext/pb_ds/priority_queue.hpp new file mode 100644 index 000000000000..c6373c5d1c95 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/priority_queue.hpp @@ -0,0 +1,131 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file priority_queue.hpp + * Contains priority_queues. + */ + +#ifndef PB_DS_PRIORITY_QUEUE_HPP +#define PB_DS_PRIORITY_QUEUE_HPP + +#include <ext/pb_ds/tag_and_trait.hpp> +#include <ext/pb_ds/detail/priority_queue_base_dispatch.hpp> +#include <ext/pb_ds/detail/standard_policies.hpp> + +namespace pb_ds +{ + // A priority queue. + template<typename Value_Type, + typename Cmp_Fn = std::less<Value_Type>, + typename Tag = pairing_heap_tag, + typename Allocator = std::allocator<char> > + class priority_queue + : public detail::priority_queue_base_dispatch<Value_Type,Cmp_Fn,Tag,Allocator>::type + { + private: + typedef typename detail::priority_queue_base_dispatch<Value_Type,Cmp_Fn,Tag,Allocator>::type base_type; + + public: + typedef Value_Type value_type; + typedef Cmp_Fn cmp_fn; + typedef Tag container_category; + typedef Allocator allocator; + typedef typename allocator::size_type size_type; + typedef typename allocator::difference_type difference_type; + + typedef typename allocator::template rebind<value_type>::other value_rebind; + typedef typename value_rebind::reference reference; + typedef typename value_rebind::const_reference const_reference; + typedef typename value_rebind::pointer pointer; + typedef typename value_rebind::const_pointer const_pointer; + + typedef typename base_type::const_point_iterator const_point_iterator; + typedef typename base_type::point_iterator point_iterator; + typedef typename base_type::const_iterator const_iterator; + typedef typename base_type::iterator iterator; + + priority_queue() { } + + // Constructor taking some policy objects. r_cmp_fn will be copied + // by the Cmp_Fn object of the container object. + priority_queue(const cmp_fn& r_cmp_fn) : base_type(r_cmp_fn) { } + + // Constructor taking __iterators to a range of value_types. The + // value_types between first_it and last_it will be inserted into + // the container object. + template<typename It> + priority_queue(It first_it, It last_it) + { base_type::copy_from_range(first_it, last_it); } + + // Constructor taking __iterators to a range of value_types and + // some policy objects The value_types between first_it and + // last_it will be inserted into the container object. r_cmp_fn + // will be copied by the cmp_fn object of the container object. + template<typename It> + priority_queue(It first_it, It last_it, const cmp_fn& r_cmp_fn) + : base_type(r_cmp_fn) + { base_type::copy_from_range(first_it, last_it); } + + priority_queue(const priority_queue& other) + : base_type((const base_type& )other) { } + + virtual + ~priority_queue() { } + + priority_queue& + operator=(const priority_queue& other) + { + if (this !=& other) + { + priority_queue tmp(other); + swap(tmp); + } + return *this; + } + + void + swap(priority_queue& other) + { base_type::swap(other); } + }; +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/tag_and_trait.hpp b/contrib/libstdc++/include/ext/pb_ds/tag_and_trait.hpp new file mode 100644 index 000000000000..94039af0d80c --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/tag_and_trait.hpp @@ -0,0 +1,357 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file tag_and_trait.hpp + * Contains tags and traits, e.g., ones describing underlying + * data structures. + */ + +#ifndef PB_DS_TAG_AND_TRAIT_HPP +#define PB_DS_TAG_AND_TRAIT_HPP + +#include <ext/pb_ds/detail/type_utils.hpp> + +namespace pb_ds +{ + // A trivial iterator tag. Signifies that the iterators has none of + // the STL's movement abilities. + struct trivial_iterator_tag + { }; + + // Prohibit moving trivial iterators. + typedef void trivial_iterator_difference_type; + + + // Signifies a basic invalidation guarantee that any iterator, + // pointer, or reference to a container object's mapped value type + // is valid as long as the container is not modified. + struct basic_invalidation_guarantee + { }; + + // Signifies an invalidation guarantee that includes all those of + // its base, and additionally, that any point-type iterator, + // pointer, or reference to a container object's mapped value type + // is valid as long as its corresponding entry has not be erased, + // regardless of modifications to the container object. + struct point_invalidation_guarantee : public basic_invalidation_guarantee + { }; + + // Signifies an invalidation guarantee that includes all those of + // its base, and additionally, that any range-type iterator + // (including the returns of begin() and end()) is in the correct + // relative positions to other range-type iterators as long as its + // corresponding entry has not be erased, regardless of + // modifications to the container object. + struct range_invalidation_guarantee : public point_invalidation_guarantee + { }; + + + // A mapped-policy indicating that an associative container is a set. + // XXX should this be a trait of the form is_set<T> ?? + struct null_mapped_type { }; + + + // Base data structure tag. + struct container_tag + { }; + + // Basic associative-container. + struct associative_container_tag : public container_tag { }; + + // Basic hash. + struct basic_hash_tag : public associative_container_tag { }; + + // Collision-chaining hash. + struct cc_hash_tag : public basic_hash_tag { }; + + // General-probing hash. + struct gp_hash_tag : public basic_hash_tag { }; + + // Basic tree. + struct basic_tree_tag : public associative_container_tag { }; + + // tree. + struct tree_tag : public basic_tree_tag { }; + + // Red-black tree. + struct rb_tree_tag : public tree_tag { }; + + // Splay tree. + struct splay_tree_tag : public tree_tag { }; + + // Ordered-vector tree. + struct ov_tree_tag : public tree_tag { }; + + // trie. + struct trie_tag : public basic_tree_tag { }; + + // PATRICIA trie. + struct pat_trie_tag : public trie_tag { }; + + // List-update. + struct list_update_tag : public associative_container_tag { }; + + // Basic priority-queue. + struct priority_queue_tag : public container_tag { }; + + // Pairing-heap. + struct pairing_heap_tag : public priority_queue_tag { }; + + // Binomial-heap. + struct binomial_heap_tag : public priority_queue_tag { }; + + // Redundant-counter binomial-heap. + struct rc_binomial_heap_tag : public priority_queue_tag { }; + + // Binary-heap (array-based). + struct binary_heap_tag : public priority_queue_tag { }; + + // Thin heap. + struct thin_heap_tag : public priority_queue_tag { }; + + + template<typename Tag> + struct container_traits_base; + + template<> + struct container_traits_base<cc_hash_tag> + { + typedef cc_hash_tag container_category; + typedef point_invalidation_guarantee invalidation_guarantee; + + enum + { + order_preserving = false, + erase_can_throw = false, + split_join_can_throw = false, + reverse_iteration = false + }; + }; + + template<> + struct container_traits_base<gp_hash_tag> + { + typedef gp_hash_tag container_category; + typedef basic_invalidation_guarantee invalidation_guarantee; + + enum + { + order_preserving = false, + erase_can_throw = false, + split_join_can_throw = false, + reverse_iteration = false + }; + }; + + template<> + struct container_traits_base<rb_tree_tag> + { + typedef rb_tree_tag container_category; + typedef range_invalidation_guarantee invalidation_guarantee; + + enum + { + order_preserving = true, + erase_can_throw = false, + split_join_can_throw = false, + reverse_iteration = true + }; + }; + + template<> + struct container_traits_base<splay_tree_tag> + { + typedef splay_tree_tag container_category; + typedef range_invalidation_guarantee invalidation_guarantee; + + enum + { + order_preserving = true, + erase_can_throw = false, + split_join_can_throw = false, + reverse_iteration = true + }; + }; + + template<> + struct container_traits_base<ov_tree_tag> + { + typedef ov_tree_tag container_category; + typedef basic_invalidation_guarantee invalidation_guarantee; + + enum + { + order_preserving = true, + erase_can_throw = true, + split_join_can_throw = true, + reverse_iteration = false + }; + }; + + template<> + struct container_traits_base<pat_trie_tag> + { + typedef pat_trie_tag container_category; + typedef range_invalidation_guarantee invalidation_guarantee; + + enum + { + order_preserving = true, + erase_can_throw = false, + split_join_can_throw = true, + reverse_iteration = true + }; + }; + + template<> + struct container_traits_base<list_update_tag> + { + typedef list_update_tag container_category; + typedef point_invalidation_guarantee invalidation_guarantee; + + enum + { + order_preserving = false, + erase_can_throw = false, + split_join_can_throw = false, + reverse_iteration = false + }; + }; + + + template<> + struct container_traits_base<pairing_heap_tag> + { + typedef pairing_heap_tag container_category; + typedef point_invalidation_guarantee invalidation_guarantee; + + enum + { + order_preserving = false, + erase_can_throw = false, + split_join_can_throw = false, + reverse_iteration = false + }; + }; + + template<> + struct container_traits_base<thin_heap_tag> + { + typedef thin_heap_tag container_category; + typedef point_invalidation_guarantee invalidation_guarantee; + + enum + { + order_preserving = false, + erase_can_throw = false, + split_join_can_throw = false, + reverse_iteration = false + }; + }; + + template<> + struct container_traits_base<binomial_heap_tag> + { + typedef binomial_heap_tag container_category; + typedef point_invalidation_guarantee invalidation_guarantee; + + enum + { + order_preserving = false, + erase_can_throw = false, + split_join_can_throw = false, + reverse_iteration = false + }; + }; + + template<> + struct container_traits_base<rc_binomial_heap_tag> + { + typedef rc_binomial_heap_tag container_category; + typedef point_invalidation_guarantee invalidation_guarantee; + + enum + { + order_preserving = false, + erase_can_throw = false, + split_join_can_throw = false, + reverse_iteration = false + }; + }; + + template<> + struct container_traits_base<binary_heap_tag> + { + typedef binary_heap_tag container_category; + typedef basic_invalidation_guarantee invalidation_guarantee; + + enum + { + order_preserving = false, + erase_can_throw = false, + split_join_can_throw = true, + reverse_iteration = false + }; + }; + + + // See Matt Austern for the name, S. Meyers MEFC++ #2, others. + template<typename Cntnr> + struct container_traits + : public container_traits_base<typename Cntnr::container_category> + { + typedef Cntnr container_type; + typedef typename Cntnr::container_category container_category; + typedef container_traits_base<container_category> base_type; + typedef typename base_type::invalidation_guarantee invalidation_guarantee; + + enum + { + order_preserving = base_type::order_preserving, + erase_can_throw = base_type::erase_can_throw, + split_join_can_throw = base_type::split_join_can_throw, + reverse_iteration = base_type::reverse_iteration + }; + }; +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/tree_policy.hpp b/contrib/libstdc++/include/ext/pb_ds/tree_policy.hpp new file mode 100644 index 000000000000..3c80fc6986a9 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/tree_policy.hpp @@ -0,0 +1,168 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file tree_policy.hpp + * Contains tree-related policies. + */ + +#ifndef PB_DS_TREE_POLICY_HPP +#define PB_DS_TREE_POLICY_HPP + +#include <iterator> +#include <ext/pb_ds/detail/type_utils.hpp> +#include <ext/pb_ds/detail/basic_tree_policy/basic_tree_policy_base.hpp> + +namespace pb_ds +{ + // A null node updator, indicating that no node updates are required. + template<typename Const_Node_Iterator, + typename Node_Iterator, + typename Cmp_Fn, + typename Allocator> + struct null_tree_node_update + { }; + +#define PB_DS_CLASS_T_DEC \ + template<typename Const_Node_Iterator, class Node_Iterator, class Cmp_Fn, class Allocator> + +#define PB_DS_CLASS_C_DEC \ + tree_order_statistics_node_update<Const_Node_Iterator, Node_Iterator, Cmp_Fn, Allocator> + +#define PB_DS_BASE_C_DEC \ + detail::basic_tree_policy_base<Const_Node_Iterator, Node_Iterator, Allocator> + + // Functor updating ranks of entrees. + template<typename Const_Node_Iterator, typename Node_Iterator, + typename Cmp_Fn, typename Allocator> + class tree_order_statistics_node_update : private PB_DS_BASE_C_DEC + { + private: + typedef PB_DS_BASE_C_DEC base_type; + + public: + typedef Cmp_Fn cmp_fn; + typedef Allocator allocator; + typedef typename allocator::size_type size_type; + typedef typename base_type::key_type key_type; + typedef typename base_type::const_key_reference const_key_reference; + + typedef size_type metadata_type; + typedef Const_Node_Iterator const_node_iterator; + typedef Node_Iterator node_iterator; + typedef typename const_node_iterator::value_type const_iterator; + typedef typename node_iterator::value_type iterator; + + // Finds an entry by __order. Returns a const_iterator to the + // entry with the __order order, or a const_iterator to the + // container object's end if order is at least the size of the + // container object. + inline const_iterator + find_by_order(size_type order) const; + + // Finds an entry by __order. Returns an iterator to the entry + // with the __order order, or an iterator to the container + // object's end if order is at least the size of the container + // object. + inline iterator + find_by_order(size_type order); + + // Returns the order of a key within a sequence. For exapmle, if + // r_key is the smallest key, this method will return 0; if r_key + // is a key between the smallest and next key, this method will + // return 1; if r_key is a key larger than the largest key, this + // method will return the size of r_c. + inline size_type + order_of_key(const_key_reference r_key) const; + + private: + // Const reference to the container's value-type. + typedef typename base_type::const_reference const_reference; + + // Const pointer to the container's value-type. + typedef typename base_type::const_pointer const_pointer; + + typedef typename allocator::template rebind<metadata_type>::other metadata_rebind; + // Const metadata reference. + typedef typename metadata_rebind::const_reference const_metadata_reference; + + // Metadata reference. + typedef typename metadata_rebind::reference metadata_reference; + + // Returns the const_node_iterator associated with the tree's root node. + virtual const_node_iterator + node_begin() const = 0; + + // Returns the node_iterator associated with the tree's root node. + virtual node_iterator + node_begin() = 0; + + // Returns the const_node_iterator associated with a just-after leaf node. + virtual const_node_iterator + node_end() const = 0; + + // Returns the node_iterator associated with a just-after leaf node. + virtual node_iterator + node_end() = 0; + + // Access to the cmp_fn object. + virtual cmp_fn& + get_cmp_fn() = 0; + + protected: + // Updates the rank of a node through a node_iterator node_it; + // end_nd_it is the end node iterator. + inline void + operator()(node_iterator node_it, const_node_iterator end_nd_it) const; + + virtual + ~tree_order_statistics_node_update(); + }; + +#include <ext/pb_ds/detail/tree_policy/order_statistics_imp.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_BASE_C_DEC + +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pb_ds/trie_policy.hpp b/contrib/libstdc++/include/ext/pb_ds/trie_policy.hpp new file mode 100644 index 000000000000..d74bed43e7f4 --- /dev/null +++ b/contrib/libstdc++/include/ext/pb_ds/trie_policy.hpp @@ -0,0 +1,365 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** + * @file trie_policy.hpp + * Contains trie-related policies. + */ + +#ifndef PB_DS_TRIE_POLICY_HPP +#define PB_DS_TRIE_POLICY_HPP + +#include <string> +#include <ext/pb_ds/detail/type_utils.hpp> +#include <ext/pb_ds/detail/trie_policy/trie_policy_base.hpp> + +namespace pb_ds +{ + // A null node updator, indicating that no node updates are required. + template<typename Const_Node_Iterator, + typename Node_Iterator, + typename E_Access_Traits, + typename Allocator> + struct null_trie_node_update + { }; + +#define PB_DS_STATIC_ASSERT(UNIQUE, E) \ + typedef detail::static_assert_dumclass<sizeof(detail::static_assert<bool(E)>)> UNIQUE##_static_assert_type + +#define PB_DS_CLASS_T_DEC \ + template<typename String, typename String::value_type Min_E_Val, typename String::value_type Max_E_Val, bool Reverse, typename Allocator> + +#define PB_DS_CLASS_C_DEC \ + string_trie_e_access_traits<String, Min_E_Val,Max_E_Val,Reverse,Allocator> + + // Element access traits for string types. + template<typename String = std::string, + typename String::value_type Min_E_Val = detail::__numeric_traits<typename String::value_type>::__min, + typename String::value_type Max_E_Val = detail::__numeric_traits<typename String::value_type>::__max, + bool Reverse = false, + typename Allocator = std::allocator<char> > + struct string_trie_e_access_traits + { + public: + typedef typename Allocator::size_type size_type; + typedef String key_type; + typedef typename Allocator::template rebind<key_type>::other key_rebind; + typedef typename key_rebind::const_reference const_key_reference; + + enum + { + reverse = Reverse + }; + + // Element const iterator type. + typedef typename detail::__conditional_type<Reverse, typename String::const_reverse_iterator, typename String::const_iterator>::__type const_iterator; + + // Element type. + typedef typename std::iterator_traits<const_iterator>::value_type e_type; + + enum + { + min_e_val = Min_E_Val, + max_e_val = Max_E_Val, + max_size = max_e_val - min_e_val + 1 + }; + PB_DS_STATIC_ASSERT(min_max_size, max_size >= 2); + + // Returns a const_iterator to the first element of + // const_key_reference agumnet. + inline static const_iterator + begin(const_key_reference); + + // Returns a const_iterator to the after-last element of + // const_key_reference argument. + inline static const_iterator + end(const_key_reference); + + // Maps an element to a position. + inline static size_type + e_pos(e_type e); + + private: + + inline static const_iterator + begin_imp(const_key_reference, detail::false_type); + + inline static const_iterator + begin_imp(const_key_reference, detail::true_type); + + inline static const_iterator + end_imp(const_key_reference, detail::false_type); + + inline static const_iterator + end_imp(const_key_reference, detail::true_type); + + static detail::integral_constant<int, Reverse> s_rev_ind; + }; + +#include <ext/pb_ds/detail/trie_policy/string_trie_e_access_traits_imp.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC + +#define PB_DS_CLASS_T_DEC \ + template<typename Const_Node_Iterator,typename Node_Iterator,class E_Access_Traits, typename Allocator> + +#define PB_DS_CLASS_C_DEC \ + trie_prefix_search_node_update<Const_Node_Iterator, Node_Iterator, E_Access_Traits,Allocator> + +#define PB_DS_BASE_C_DEC \ + detail::trie_policy_base<Const_Node_Iterator,Node_Iterator,E_Access_Traits, Allocator> + + // A node updator that allows tries to be searched for the range of + // values that match a certain prefix. + template<typename Const_Node_Iterator, + typename Node_Iterator, + typename E_Access_Traits, + typename Allocator> + class trie_prefix_search_node_update : private PB_DS_BASE_C_DEC + { + private: + typedef PB_DS_BASE_C_DEC base_type; + + public: + typedef typename base_type::key_type key_type; + typedef typename base_type::const_key_reference const_key_reference; + + // Element access traits. + typedef E_Access_Traits e_access_traits; + + // Const element iterator. + typedef typename e_access_traits::const_iterator const_e_iterator; + + // Allocator type. + typedef Allocator allocator; + + // Size type. + typedef typename allocator::size_type size_type; + typedef detail::null_node_metadata metadata_type; + typedef Const_Node_Iterator const_node_iterator; + typedef Node_Iterator node_iterator; + typedef typename const_node_iterator::value_type const_iterator; + typedef typename node_iterator::value_type iterator; + + // Finds the const iterator range corresponding to all values + // whose prefixes match r_key. + std::pair<const_iterator, const_iterator> + prefix_range(const_key_reference) const; + + // Finds the iterator range corresponding to all values whose + // prefixes match r_key. + std::pair<iterator, iterator> + prefix_range(const_key_reference); + + // Finds the const iterator range corresponding to all values + // whose prefixes match [b, e). + std::pair<const_iterator, const_iterator> + prefix_range(const_e_iterator, const_e_iterator) const; + + // Finds the iterator range corresponding to all values whose + // prefixes match [b, e). + std::pair<iterator, iterator> + prefix_range(const_e_iterator, const_e_iterator); + + protected: + // Called to update a node's metadata. + inline void + operator()(node_iterator node_it, const_node_iterator end_nd_it) const; + + private: + // Returns the const iterator associated with the just-after last element. + virtual const_iterator + end() const = 0; + + // Returns the iterator associated with the just-after last element. + virtual iterator + end() = 0; + + // Returns the const_node_iterator associated with the trie's root node. + virtual const_node_iterator + node_begin() const = 0; + + // Returns the node_iterator associated with the trie's root node. + virtual node_iterator + node_begin() = 0; + + // Returns the const_node_iterator associated with a just-after leaf node. + virtual const_node_iterator + node_end() const = 0; + + // Returns the node_iterator associated with a just-after leaf node. + virtual node_iterator + node_end() = 0; + + // Access to the cmp_fn object. + virtual const e_access_traits& + get_e_access_traits() const = 0; + + node_iterator + next_child(node_iterator, const_e_iterator, const_e_iterator, + node_iterator, const e_access_traits&); + }; + +#include <ext/pb_ds/detail/trie_policy/prefix_search_node_update_imp.hpp> + +#undef PB_DS_CLASS_C_DEC + +#define PB_DS_CLASS_C_DEC \ + trie_order_statistics_node_update<Const_Node_Iterator, Node_Iterator,E_Access_Traits, Allocator> + + // Functor updating ranks of entrees. + template<typename Const_Node_Iterator, + typename Node_Iterator, + typename E_Access_Traits, + typename Allocator> + class trie_order_statistics_node_update : private PB_DS_BASE_C_DEC + { + private: + typedef PB_DS_BASE_C_DEC base_type; + + public: + typedef E_Access_Traits e_access_traits; + typedef typename e_access_traits::const_iterator const_e_iterator; + typedef Allocator allocator; + typedef typename allocator::size_type size_type; + typedef typename base_type::key_type key_type; + typedef typename base_type::const_key_reference const_key_reference; + + typedef size_type metadata_type; + typedef Const_Node_Iterator const_node_iterator; + typedef Node_Iterator node_iterator; + typedef typename const_node_iterator::value_type const_iterator; + typedef typename node_iterator::value_type iterator; + + // Finds an entry by __order. Returns a const_iterator to the + // entry with the __order order, or a const_iterator to the + // container object's end if order is at least the size of the + // container object. + inline const_iterator + find_by_order(size_type) const; + + // Finds an entry by __order. Returns an iterator to the entry + // with the __order order, or an iterator to the container + // object's end if order is at least the size of the container + // object. + inline iterator + find_by_order(size_type); + + // Returns the order of a key within a sequence. For exapmle, if + // r_key is the smallest key, this method will return 0; if r_key + // is a key between the smallest and next key, this method will + // return 1; if r_key is a key larger than the largest key, this + // method will return the size of r_c. + inline size_type + order_of_key(const_key_reference) const; + + // Returns the order of a prefix within a sequence. For exapmle, + // if [b, e] is the smallest prefix, this method will return 0; if + // r_key is a key between the smallest and next key, this method + // will return 1; if r_key is a key larger than the largest key, + // this method will return the size of r_c. + inline size_type + order_of_prefix(const_e_iterator, const_e_iterator) const; + + private: + typedef typename base_type::const_reference const_reference; + typedef typename base_type::const_pointer const_pointer; + + typedef typename Allocator::template rebind<metadata_type>::other metadata_rebind; + typedef typename metadata_rebind::const_reference const_metadata_reference; + typedef typename metadata_rebind::reference metadata_reference; + + // Returns true if the container is empty. + virtual bool + empty() const = 0; + + // Returns the iterator associated with the trie's first element. + virtual iterator + begin() = 0; + + // Returns the iterator associated with the trie's + // just-after-last element. + virtual iterator + end() = 0; + + // Returns the const_node_iterator associated with the trie's root node. + virtual const_node_iterator + node_begin() const = 0; + + // Returns the node_iterator associated with the trie's root node. + virtual node_iterator + node_begin() = 0; + + // Returns the const_node_iterator associated with a just-after + // leaf node. + virtual const_node_iterator + node_end() const = 0; + + // Returns the node_iterator associated with a just-after leaf node. + virtual node_iterator + node_end() = 0; + + // Access to the cmp_fn object. + virtual e_access_traits& + get_e_access_traits() = 0; + + protected: + // Updates the rank of a node through a node_iterator node_it; + // end_nd_it is the end node iterator. + inline void + operator()(node_iterator, const_node_iterator) const; + + // Destructor. + virtual + ~trie_order_statistics_node_update(); + }; + +#include <ext/pb_ds/detail/trie_policy/order_statistics_imp.hpp> + +#undef PB_DS_CLASS_T_DEC +#undef PB_DS_CLASS_C_DEC +#undef PB_DS_BASE_C_DEC +#undef PB_DS_STATIC_ASSERT + +} // namespace pb_ds + +#endif diff --git a/contrib/libstdc++/include/ext/pod_char_traits.h b/contrib/libstdc++/include/ext/pod_char_traits.h index c69025e005d2..236e349cd44e 100644 --- a/contrib/libstdc++/include/ext/pod_char_traits.h +++ b/contrib/libstdc++/include/ext/pod_char_traits.h @@ -1,6 +1,6 @@ // POD character, std::char_traits specialization -*- C++ -*- -// Copyright (C) 2002, 2003 Free Software Foundation, Inc. +// Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -15,7 +15,7 @@ // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, // USA. // As a special exception, you may use this file as part of a free software @@ -27,6 +27,10 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. +/** @file ext/pod_char_traits.h + * This file is a GNU extension to the Standard C++ Library. + */ + // Gabriel Dos Reis <gdr@integrable-solutions.net> // Benjamin Kosnik <bkoz@redhat.com> @@ -35,42 +39,60 @@ #include <string> -namespace __gnu_cxx -{ +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + // POD character abstraction. + // NB: The char_type parameter is a subset of int_type, as to allow + // int_type to properly hold the full range of char_type values as + // well as EOF. + /// @brief A POD class that serves as a character abstraction class. template<typename V, typename I, typename S = mbstate_t> struct character { - typedef V value_type; - typedef I int_type; - typedef S state_type; + typedef V value_type; + typedef I int_type; + typedef S state_type; + typedef character<V, I, S> char_type; + value_type value; + + template<typename V2> + static char_type + from(const V2& v) + { + char_type ret = { static_cast<value_type>(v) }; + return ret; + } + + template<typename V2> + static V2 + to(const char_type& c) + { + V2 ret = { static_cast<V2>(c.value) }; + return ret; + } + }; - template<typename V, typename I> + template<typename V, typename I, typename S> inline bool - operator==(const character<V, I>& lhs, const character<V, I>& rhs) + operator==(const character<V, I, S>& lhs, const character<V, I, S>& rhs) { return lhs.value == rhs.value; } - template<typename V, typename I> + template<typename V, typename I, typename S> inline bool - operator<(const character<V, I>& lhs, const character<V, I>& rhs) + operator<(const character<V, I, S>& lhs, const character<V, I, S>& rhs) { return lhs.value < rhs.value; } -} // namespace __gnu_cxx -namespace std -{ - // Provide std::char_traits specialization. +_GLIBCXX_END_NAMESPACE + +_GLIBCXX_BEGIN_NAMESPACE(std) + + /// char_traits<__gnu_cxx::character> specialization. template<typename V, typename I, typename S> struct char_traits<__gnu_cxx::character<V, I, S> > { typedef __gnu_cxx::character<V, I, S> char_type; - - // NB: This type should be bigger than char_type, so as to - // properly hold EOF values in addition to the full range of - // char_type values. - // Also, assumes - // int_type(value_type) is valid. - // int_type(-1) is possible. typedef typename char_type::int_type int_type; typedef typename char_type::state_type state_type; typedef fpos<state_type> pos_type; @@ -117,42 +139,49 @@ namespace std static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) - { return (char_type*) memmove(__s1, __s2, __n * sizeof(char_type)); } + { + return static_cast<char_type*>(std::memmove(__s1, __s2, + __n * sizeof(char_type))); + } static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) - { return (char_type*) memcpy(__s1, __s2, __n * sizeof(char_type)); } + { + std::copy(__s2, __s2 + __n, __s1); + return __s1; + } static char_type* assign(char_type* __s, size_t __n, char_type __a) { - for (char_type* __p = __s; __p < __s + __n; ++__p) - assign(*__p, __a); + std::fill_n(__s, __n, __a); return __s; } static char_type - to_char_type(const int_type& __c) - { - char_type __r = { __c }; - return __r; - } + to_char_type(const int_type& __i) + { return char_type::template from(__i); } static int_type to_int_type(const char_type& __c) - { return int_type(__c.value); } + { return char_type::template to<int_type>(__c); } static bool eq_int_type(const int_type& __c1, const int_type& __c2) { return __c1 == __c2; } static int_type - eof() { return static_cast<int_type>(-1); } + eof() + { + int_type __r = { -1 }; + return __r; + } static int_type not_eof(const int_type& __c) - { return eq_int_type(__c, eof()) ? int_type(0) : __c; } + { return eq_int_type(__c, eof()) ? int_type() : __c; } }; -} + +_GLIBCXX_END_NAMESPACE #endif diff --git a/contrib/libstdc++/include/ext/pool_allocator.h b/contrib/libstdc++/include/ext/pool_allocator.h index 0f087a03c1e9..e78bf21778c2 100644 --- a/contrib/libstdc++/include/ext/pool_allocator.h +++ b/contrib/libstdc++/include/ext/pool_allocator.h @@ -1,6 +1,7 @@ // Allocators -*- C++ -*- -// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 +// Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -15,7 +16,7 @@ // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, // USA. // As a special exception, you may use this file as part of a free software @@ -42,8 +43,8 @@ /** @file ext/pool_allocator.h * This file is a GNU extension to the Standard C++ Library. - * You should only include this header if you are using GCC 3 or later. */ + #ifndef _POOL_ALLOCATOR_H #define _POOL_ALLOCATOR_H 1 @@ -51,12 +52,17 @@ #include <cstdlib> #include <new> #include <bits/functexcept.h> -#include <bits/atomicity.h> -#include <bits/concurrence.h> +#include <ext/atomicity.h> +#include <ext/concurrence.h> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + using std::size_t; + using std::ptrdiff_t; -namespace __gnu_cxx -{ /** + * @brief Base class for __pool_alloc. + * * @if maint * Uses various allocators to fulfill underlying requests (and makes as * few requests as possible when in default high-speed pool mode). @@ -71,7 +77,6 @@ namespace __gnu_cxx * without permanently losing part of the object. * * @endif - * (See @link Allocators allocators info @endlink for more.) */ class __pool_alloc_base { @@ -79,7 +84,7 @@ namespace __gnu_cxx enum { _S_align = 8 }; enum { _S_max_bytes = 128 }; - enum { _S_free_list_size = _S_max_bytes / _S_align }; + enum { _S_free_list_size = (size_t)_S_max_bytes / (size_t)_S_align }; union _Obj { @@ -101,7 +106,7 @@ namespace __gnu_cxx _Obj* volatile* _M_get_free_list(size_t __bytes); - mutex_type& + __mutex& _M_get_mutex(); // Returns an object of size __n, and optionally adds to size __n @@ -116,6 +121,7 @@ namespace __gnu_cxx }; + /// @brief class __pool_alloc. template<typename _Tp> class __pool_alloc : private __pool_alloc_base { @@ -189,43 +195,41 @@ namespace __gnu_cxx __pool_alloc<_Tp>::allocate(size_type __n, const void*) { pointer __ret = 0; - if (__n) + if (__builtin_expect(__n != 0, true)) { - if (__n <= max_size()) + if (__builtin_expect(__n > this->max_size(), false)) + std::__throw_bad_alloc(); + + // If there is a race through here, assume answer from getenv + // will resolve in same direction. Inspired by techniques + // to efficiently support threading found in basic_string.h. + if (_S_force_new == 0) { - // If there is a race through here, assume answer from getenv - // will resolve in same direction. Inspired by techniques - // to efficiently support threading found in basic_string.h. - if (_S_force_new == 0) - { - if (getenv("GLIBCXX_FORCE_NEW")) - __atomic_add(&_S_force_new, 1); - else - __atomic_add(&_S_force_new, -1); - } + if (std::getenv("GLIBCXX_FORCE_NEW")) + __atomic_add_dispatch(&_S_force_new, 1); + else + __atomic_add_dispatch(&_S_force_new, -1); + } - const size_t __bytes = __n * sizeof(_Tp); - if (__bytes > size_t(_S_max_bytes) || _S_force_new == 1) - __ret = static_cast<_Tp*>(::operator new(__bytes)); + const size_t __bytes = __n * sizeof(_Tp); + if (__bytes > size_t(_S_max_bytes) || _S_force_new == 1) + __ret = static_cast<_Tp*>(::operator new(__bytes)); + else + { + _Obj* volatile* __free_list = _M_get_free_list(__bytes); + + __scoped_lock sentry(_M_get_mutex()); + _Obj* __restrict__ __result = *__free_list; + if (__builtin_expect(__result == 0, 0)) + __ret = static_cast<_Tp*>(_M_refill(_M_round_up(__bytes))); else { - _Obj* volatile* __free_list = _M_get_free_list(__bytes); - - lock sentry(_M_get_mutex()); - _Obj* __restrict__ __result = *__free_list; - if (__builtin_expect(__result == 0, 0)) - __ret = static_cast<_Tp*>(_M_refill(_M_round_up(__bytes))); - else - { - *__free_list = __result->_M_free_list_link; - __ret = reinterpret_cast<_Tp*>(__result); - } - if (__builtin_expect(__ret == 0, 0)) - std::__throw_bad_alloc(); + *__free_list = __result->_M_free_list_link; + __ret = reinterpret_cast<_Tp*>(__result); } + if (__builtin_expect(__ret == 0, 0)) + std::__throw_bad_alloc(); } - else - std::__throw_bad_alloc(); } return __ret; } @@ -234,7 +238,7 @@ namespace __gnu_cxx void __pool_alloc<_Tp>::deallocate(pointer __p, size_type __n) { - if (__n) + if (__builtin_expect(__n != 0 && __p != 0, true)) { const size_t __bytes = __n * sizeof(_Tp); if (__bytes > static_cast<size_t>(_S_max_bytes) || _S_force_new == 1) @@ -244,12 +248,13 @@ namespace __gnu_cxx _Obj* volatile* __free_list = _M_get_free_list(__bytes); _Obj* __q = reinterpret_cast<_Obj*>(__p); - lock sentry(_M_get_mutex()); + __scoped_lock sentry(_M_get_mutex()); __q ->_M_free_list_link = *__free_list; *__free_list = __q; } } } -} // namespace __gnu_cxx + +_GLIBCXX_END_NAMESPACE #endif diff --git a/contrib/libstdc++/include/ext/rb_tree b/contrib/libstdc++/include/ext/rb_tree index 2c38b39706e2..22dd7cd01992 100644 --- a/contrib/libstdc++/include/ext/rb_tree +++ b/contrib/libstdc++/include/ext/rb_tree @@ -1,6 +1,6 @@ // rb_tree extension -*- C++ -*- -// Copyright (C) 2002 Free Software Foundation, Inc. +// Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -15,7 +15,7 @@ // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, // USA. // As a special exception, you may use this file as part of a free software @@ -55,8 +55,7 @@ /** @file ext/rb_tree * This file is a GNU extension to the Standard C++ Library (possibly - * containing extensions from the HP/SGI STL subset). You should only - * include this header if you are using GCC 3 or later. + * containing extensions from the HP/SGI STL subset). */ #ifndef _RB_TREE @@ -66,8 +65,8 @@ #include <bits/stl_tree.h> -namespace __gnu_cxx -{ +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + using std::_Rb_tree; using std::allocator; @@ -81,17 +80,19 @@ namespace __gnu_cxx */ template <class _Key, class _Value, class _KeyOfValue, class _Compare, class _Alloc = allocator<_Value> > - 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; + 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()) + rb_tree(const _Compare& __comp = _Compare(), + const allocator_type& __a = allocator_type()) : _Base(__comp, __a) { } - ~rb_tree() { } - }; -} // namespace __gnu_cxx + ~rb_tree() { } + }; + +_GLIBCXX_END_NAMESPACE #endif diff --git a/contrib/libstdc++/include/ext/rc_string_base.h b/contrib/libstdc++/include/ext/rc_string_base.h new file mode 100644 index 000000000000..4eab4c69fb9b --- /dev/null +++ b/contrib/libstdc++/include/ext/rc_string_base.h @@ -0,0 +1,717 @@ +// Reference-counted versatile string base -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/** @file ext/rc_string_base.h + * This file is a GNU extension to the Standard C++ Library. + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _RC_STRING_BASE_H +#define _RC_STRING_BASE_H 1 + +#include <ext/atomicity.h> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + /** + * @if maint + * Documentation? What's that? + * Nathan Myers <ncm@cantrip.org>. + * + * A string looks like this: + * + * @code + * [_Rep] + * _M_length + * [__rc_string_base<char_type>] _M_capacity + * _M_dataplus _M_refcount + * _M_p ----------------> unnamed array of char_type + * @endcode + * + * Where the _M_p points to the first character in the string, and + * you cast it to a pointer-to-_Rep and subtract 1 to get a + * pointer to the header. + * + * This approach has the enormous advantage that a string object + * requires only one allocation. All the ugliness is confined + * within a single pair of inline functions, which each compile to + * a single "add" instruction: _Rep::_M_refdata(), and + * __rc_string_base::_M_rep(); and the allocation function which gets a + * block of raw bytes and with room enough and constructs a _Rep + * object at the front. + * + * The reason you want _M_data pointing to the character array and + * not the _Rep is so that the debugger can see the string + * contents. (Probably we should add a non-inline member to get + * the _Rep for the debugger to use, so users can check the actual + * string length.) + * + * Note that the _Rep object is a POD so that you can have a + * static "empty string" _Rep object already "constructed" before + * static constructors have run. The reference-count encoding is + * chosen so that a 0 indicates one reference, so you never try to + * destroy the empty-string _Rep object. + * + * All but the last paragraph is considered pretty conventional + * for a C++ string implementation. + * @endif + */ + template<typename _CharT, typename _Traits, typename _Alloc> + class __rc_string_base + : protected __vstring_utility<_CharT, _Traits, _Alloc> + { + public: + typedef _Traits traits_type; + typedef typename _Traits::char_type value_type; + typedef _Alloc allocator_type; + + typedef __vstring_utility<_CharT, _Traits, _Alloc> _Util_Base; + typedef typename _Util_Base::_CharT_alloc_type _CharT_alloc_type; + typedef typename _CharT_alloc_type::size_type size_type; + + private: + // _Rep: string representation + // Invariants: + // 1. String really contains _M_length + 1 characters: due to 21.3.4 + // must be kept null-terminated. + // 2. _M_capacity >= _M_length + // Allocated memory is always (_M_capacity + 1) * sizeof(_CharT). + // 3. _M_refcount has three states: + // -1: leaked, one reference, no ref-copies allowed, non-const. + // 0: one reference, non-const. + // n>0: n + 1 references, operations require a lock, const. + // 4. All fields == 0 is an empty string, given the extra storage + // beyond-the-end for a null terminator; thus, the shared + // empty string representation needs no constructor. + struct _Rep + { + union + { + struct + { + size_type _M_length; + size_type _M_capacity; + _Atomic_word _M_refcount; + } _M_info; + + // Only for alignment purposes. + _CharT _M_align; + }; + + typedef typename _Alloc::template rebind<_Rep>::other _Rep_alloc_type; + + _CharT* + _M_refdata() throw() + { return reinterpret_cast<_CharT*>(this + 1); } + + _CharT* + _M_refcopy() throw() + { + __atomic_add_dispatch(&_M_info._M_refcount, 1); + return _M_refdata(); + } // XXX MT + + void + _M_set_length(size_type __n) + { + _M_info._M_refcount = 0; // One reference. + _M_info._M_length = __n; + // grrr. (per 21.3.4) + // You cannot leave those LWG people alone for a second. + traits_type::assign(_M_refdata()[__n], _CharT()); + } + + // Create & Destroy + static _Rep* + _S_create(size_type, size_type, const _Alloc&); + + void + _M_destroy(const _Alloc&) throw(); + + _CharT* + _M_clone(const _Alloc&, size_type __res = 0); + }; + + struct _Rep_empty + : public _Rep + { + _CharT _M_terminal; + }; + + static _Rep_empty _S_empty_rep; + + // The maximum number of individual char_type elements of an + // individual string is determined by _S_max_size. This is the + // value that will be returned by max_size(). (Whereas npos + // is the maximum number of bytes the allocator can allocate.) + // If one was to divvy up the theoretical largest size string, + // with a terminating character and m _CharT elements, it'd + // look like this: + // npos = sizeof(_Rep) + (m * sizeof(_CharT)) + sizeof(_CharT) + // + sizeof(_Rep) - 1 + // (NB: last two terms for rounding reasons, see _M_create below) + // Solving for m: + // m = ((npos - 2 * sizeof(_Rep) + 1) / sizeof(_CharT)) - 1 + // In addition, this implementation halfs this amount. + enum { _S_max_size = (((static_cast<size_type>(-1) - 2 * sizeof(_Rep) + + 1) / sizeof(_CharT)) - 1) / 2 }; + + // Data Member (private): + mutable typename _Util_Base::template _Alloc_hider<_Alloc> _M_dataplus; + + void + _M_data(_CharT* __p) + { _M_dataplus._M_p = __p; } + + _Rep* + _M_rep() const + { return &((reinterpret_cast<_Rep*>(_M_data()))[-1]); } + + _CharT* + _M_grab(const _Alloc& __alloc) const + { + return (!_M_is_leaked() && _M_get_allocator() == __alloc) + ? _M_rep()->_M_refcopy() : _M_rep()->_M_clone(__alloc); + } + + void + _M_dispose() + { + if (__exchange_and_add_dispatch(&_M_rep()->_M_info._M_refcount, + -1) <= 0) + _M_rep()->_M_destroy(_M_get_allocator()); + } // XXX MT + + bool + _M_is_leaked() const + { return _M_rep()->_M_info._M_refcount < 0; } + + void + _M_set_sharable() + { _M_rep()->_M_info._M_refcount = 0; } + + void + _M_leak_hard(); + + // _S_construct_aux is used to implement the 21.3.1 para 15 which + // requires special behaviour if _InIterator is an integral type + template<typename _InIterator> + static _CharT* + _S_construct_aux(_InIterator __beg, _InIterator __end, + const _Alloc& __a, std::__false_type) + { + typedef typename iterator_traits<_InIterator>::iterator_category _Tag; + return _S_construct(__beg, __end, __a, _Tag()); + } + + template<typename _InIterator> + static _CharT* + _S_construct_aux(_InIterator __beg, _InIterator __end, + const _Alloc& __a, std::__true_type) + { return _S_construct(static_cast<size_type>(__beg), + static_cast<value_type>(__end), __a); } + + template<typename _InIterator> + static _CharT* + _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a) + { + typedef typename std::__is_integer<_InIterator>::__type _Integral; + return _S_construct_aux(__beg, __end, __a, _Integral()); + } + + // For Input Iterators, used in istreambuf_iterators, etc. + template<typename _InIterator> + static _CharT* + _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, + std::input_iterator_tag); + + // For forward_iterators up to random_access_iterators, used for + // string::iterator, _CharT*, etc. + template<typename _FwdIterator> + static _CharT* + _S_construct(_FwdIterator __beg, _FwdIterator __end, const _Alloc& __a, + std::forward_iterator_tag); + + static _CharT* + _S_construct(size_type __req, _CharT __c, const _Alloc& __a); + + public: + size_type + _M_max_size() const + { return size_type(_S_max_size); } + + _CharT* + _M_data() const + { return _M_dataplus._M_p; } + + size_type + _M_length() const + { return _M_rep()->_M_info._M_length; } + + size_type + _M_capacity() const + { return _M_rep()->_M_info._M_capacity; } + + bool + _M_is_shared() const + { return _M_rep()->_M_info._M_refcount > 0; } + + void + _M_set_leaked() + { _M_rep()->_M_info._M_refcount = -1; } + + void + _M_leak() // for use in begin() & non-const op[] + { + if (!_M_is_leaked()) + _M_leak_hard(); + } + + void + _M_set_length(size_type __n) + { _M_rep()->_M_set_length(__n); } + + __rc_string_base() + : _M_dataplus(_Alloc(), _S_empty_rep._M_refcopy()) { } + + __rc_string_base(const _Alloc& __a); + + __rc_string_base(const __rc_string_base& __rcs); + + __rc_string_base(size_type __n, _CharT __c, const _Alloc& __a); + + template<typename _InputIterator> + __rc_string_base(_InputIterator __beg, _InputIterator __end, + const _Alloc& __a); + + ~__rc_string_base() + { _M_dispose(); } + + allocator_type& + _M_get_allocator() + { return _M_dataplus; } + + const allocator_type& + _M_get_allocator() const + { return _M_dataplus; } + + void + _M_swap(__rc_string_base& __rcs); + + void + _M_assign(const __rc_string_base& __rcs); + + void + _M_reserve(size_type __res); + + void + _M_mutate(size_type __pos, size_type __len1, const _CharT* __s, + size_type __len2); + + void + _M_erase(size_type __pos, size_type __n); + + void + _M_clear() + { _M_erase(size_type(0), _M_length()); } + + bool + _M_compare(const __rc_string_base&) const + { return false; } + }; + + template<typename _CharT, typename _Traits, typename _Alloc> + typename __rc_string_base<_CharT, _Traits, _Alloc>::_Rep_empty + __rc_string_base<_CharT, _Traits, _Alloc>::_S_empty_rep; + + template<typename _CharT, typename _Traits, typename _Alloc> + typename __rc_string_base<_CharT, _Traits, _Alloc>::_Rep* + __rc_string_base<_CharT, _Traits, _Alloc>::_Rep:: + _S_create(size_type __capacity, size_type __old_capacity, + const _Alloc& __alloc) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 83. String::npos vs. string::max_size() + if (__capacity > size_type(_S_max_size)) + std::__throw_length_error(__N("__rc_string_base::_Rep::_S_create")); + + // The standard places no restriction on allocating more memory + // than is strictly needed within this layer at the moment or as + // requested by an explicit application call to reserve(). + + // Many malloc implementations perform quite poorly when an + // application attempts to allocate memory in a stepwise fashion + // growing each allocation size by only 1 char. Additionally, + // it makes little sense to allocate less linear memory than the + // natural blocking size of the malloc implementation. + // Unfortunately, we would need a somewhat low-level calculation + // with tuned parameters to get this perfect for any particular + // malloc implementation. Fortunately, generalizations about + // common features seen among implementations seems to suffice. + + // __pagesize need not match the actual VM page size for good + // results in practice, thus we pick a common value on the low + // side. __malloc_header_size is an estimate of the amount of + // overhead per memory allocation (in practice seen N * sizeof + // (void*) where N is 0, 2 or 4). According to folklore, + // picking this value on the high side is better than + // low-balling it (especially when this algorithm is used with + // malloc implementations that allocate memory blocks rounded up + // to a size which is a power of 2). + const size_type __pagesize = 4096; + const size_type __malloc_header_size = 4 * sizeof(void*); + + // The below implements an exponential growth policy, necessary to + // meet amortized linear time requirements of the library: see + // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html. + if (__capacity > __old_capacity && __capacity < 2 * __old_capacity) + { + __capacity = 2 * __old_capacity; + // Never allocate a string bigger than _S_max_size. + if (__capacity > size_type(_S_max_size)) + __capacity = size_type(_S_max_size); + } + + // NB: Need an array of char_type[__capacity], plus a terminating + // null char_type() element, plus enough for the _Rep data structure, + // plus sizeof(_Rep) - 1 to upper round to a size multiple of + // sizeof(_Rep). + // Whew. Seemingly so needy, yet so elemental. + size_type __size = ((__capacity + 1) * sizeof(_CharT) + + 2 * sizeof(_Rep) - 1); + + const size_type __adj_size = __size + __malloc_header_size; + if (__adj_size > __pagesize && __capacity > __old_capacity) + { + const size_type __extra = __pagesize - __adj_size % __pagesize; + __capacity += __extra / sizeof(_CharT); + if (__capacity > size_type(_S_max_size)) + __capacity = size_type(_S_max_size); + __size = (__capacity + 1) * sizeof(_CharT) + 2 * sizeof(_Rep) - 1; + } + + // NB: Might throw, but no worries about a leak, mate: _Rep() + // does not throw. + _Rep* __place = _Rep_alloc_type(__alloc).allocate(__size / sizeof(_Rep)); + _Rep* __p = new (__place) _Rep; + __p->_M_info._M_capacity = __capacity; + return __p; + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + __rc_string_base<_CharT, _Traits, _Alloc>::_Rep:: + _M_destroy(const _Alloc& __a) throw () + { + const size_type __size = ((_M_info._M_capacity + 1) * sizeof(_CharT) + + 2 * sizeof(_Rep) - 1); + _Rep_alloc_type(__a).deallocate(this, __size / sizeof(_Rep)); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + _CharT* + __rc_string_base<_CharT, _Traits, _Alloc>::_Rep:: + _M_clone(const _Alloc& __alloc, size_type __res) + { + // Requested capacity of the clone. + const size_type __requested_cap = _M_info._M_length + __res; + _Rep* __r = _Rep::_S_create(__requested_cap, _M_info._M_capacity, + __alloc); + + if (_M_info._M_length) + _S_copy(__r->_M_refdata(), _M_refdata(), _M_info._M_length); + + __r->_M_set_length(_M_info._M_length); + return __r->_M_refdata(); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + __rc_string_base<_CharT, _Traits, _Alloc>:: + __rc_string_base(const _Alloc& __a) + : _M_dataplus(__a, _S_construct(size_type(), _CharT(), __a)) { } + + template<typename _CharT, typename _Traits, typename _Alloc> + __rc_string_base<_CharT, _Traits, _Alloc>:: + __rc_string_base(const __rc_string_base& __rcs) + : _M_dataplus(__rcs._M_get_allocator(), + __rcs._M_grab(__rcs._M_get_allocator())) { } + + template<typename _CharT, typename _Traits, typename _Alloc> + __rc_string_base<_CharT, _Traits, _Alloc>:: + __rc_string_base(size_type __n, _CharT __c, const _Alloc& __a) + : _M_dataplus(__a, _S_construct(__n, __c, __a)) { } + + template<typename _CharT, typename _Traits, typename _Alloc> + template<typename _InputIterator> + __rc_string_base<_CharT, _Traits, _Alloc>:: + __rc_string_base(_InputIterator __beg, _InputIterator __end, + const _Alloc& __a) + : _M_dataplus(__a, _S_construct(__beg, __end, __a)) { } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + __rc_string_base<_CharT, _Traits, _Alloc>:: + _M_leak_hard() + { + if (_M_is_shared()) + _M_erase(0, 0); + _M_set_leaked(); + } + + // NB: This is the special case for Input Iterators, used in + // istreambuf_iterators, etc. + // Input Iterators have a cost structure very different from + // pointers, calling for a different coding style. + template<typename _CharT, typename _Traits, typename _Alloc> + template<typename _InIterator> + _CharT* + __rc_string_base<_CharT, _Traits, _Alloc>:: + _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, + std::input_iterator_tag) + { + if (__beg == __end && __a == _Alloc()) + return _S_empty_rep._M_refcopy(); + + // Avoid reallocation for common case. + _CharT __buf[128]; + size_type __len = 0; + while (__beg != __end && __len < sizeof(__buf) / sizeof(_CharT)) + { + __buf[__len++] = *__beg; + ++__beg; + } + _Rep* __r = _Rep::_S_create(__len, size_type(0), __a); + _S_copy(__r->_M_refdata(), __buf, __len); + try + { + while (__beg != __end) + { + if (__len == __r->_M_info._M_capacity) + { + // Allocate more space. + _Rep* __another = _Rep::_S_create(__len + 1, __len, __a); + _S_copy(__another->_M_refdata(), __r->_M_refdata(), __len); + __r->_M_destroy(__a); + __r = __another; + } + __r->_M_refdata()[__len++] = *__beg; + ++__beg; + } + } + catch(...) + { + __r->_M_destroy(__a); + __throw_exception_again; + } + __r->_M_set_length(__len); + return __r->_M_refdata(); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + template<typename _InIterator> + _CharT* + __rc_string_base<_CharT, _Traits, _Alloc>:: + _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, + std::forward_iterator_tag) + { + if (__beg == __end && __a == _Alloc()) + return _S_empty_rep._M_refcopy(); + + // NB: Not required, but considered best practice. + if (__builtin_expect(_S_is_null_pointer(__beg) && __beg != __end, 0)) + std::__throw_logic_error(__N("__rc_string_base::" + "_S_construct NULL not valid")); + + const size_type __dnew = static_cast<size_type>(std::distance(__beg, + __end)); + // Check for out_of_range and length_error exceptions. + _Rep* __r = _Rep::_S_create(__dnew, size_type(0), __a); + try + { _S_copy_chars(__r->_M_refdata(), __beg, __end); } + catch(...) + { + __r->_M_destroy(__a); + __throw_exception_again; + } + __r->_M_set_length(__dnew); + return __r->_M_refdata(); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + _CharT* + __rc_string_base<_CharT, _Traits, _Alloc>:: + _S_construct(size_type __n, _CharT __c, const _Alloc& __a) + { + if (__n == 0 && __a == _Alloc()) + return _S_empty_rep._M_refcopy(); + + // Check for out_of_range and length_error exceptions. + _Rep* __r = _Rep::_S_create(__n, size_type(0), __a); + if (__n) + _S_assign(__r->_M_refdata(), __n, __c); + + __r->_M_set_length(__n); + return __r->_M_refdata(); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + __rc_string_base<_CharT, _Traits, _Alloc>:: + _M_swap(__rc_string_base& __rcs) + { + if (_M_is_leaked()) + _M_set_sharable(); + if (__rcs._M_is_leaked()) + __rcs._M_set_sharable(); + + _CharT* __tmp = _M_data(); + _M_data(__rcs._M_data()); + __rcs._M_data(__tmp); + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 431. Swapping containers with unequal allocators. + std::__alloc_swap<allocator_type>::_S_do_it(_M_get_allocator(), + __rcs._M_get_allocator()); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + __rc_string_base<_CharT, _Traits, _Alloc>:: + _M_assign(const __rc_string_base& __rcs) + { + if (_M_rep() != __rcs._M_rep()) + { + _CharT* __tmp = __rcs._M_grab(_M_get_allocator()); + _M_dispose(); + _M_data(__tmp); + } + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + __rc_string_base<_CharT, _Traits, _Alloc>:: + _M_reserve(size_type __res) + { + // Make sure we don't shrink below the current size. + if (__res < _M_length()) + __res = _M_length(); + + if (__res != _M_capacity() || _M_is_shared()) + { + _CharT* __tmp = _M_rep()->_M_clone(_M_get_allocator(), + __res - _M_length()); + _M_dispose(); + _M_data(__tmp); + } + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + __rc_string_base<_CharT, _Traits, _Alloc>:: + _M_mutate(size_type __pos, size_type __len1, const _CharT* __s, + size_type __len2) + { + const size_type __how_much = _M_length() - __pos - __len1; + + _Rep* __r = _Rep::_S_create(_M_length() + __len2 - __len1, + _M_capacity(), _M_get_allocator()); + + if (__pos) + _S_copy(__r->_M_refdata(), _M_data(), __pos); + if (__s && __len2) + _S_copy(__r->_M_refdata() + __pos, __s, __len2); + if (__how_much) + _S_copy(__r->_M_refdata() + __pos + __len2, + _M_data() + __pos + __len1, __how_much); + + _M_dispose(); + _M_data(__r->_M_refdata()); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + __rc_string_base<_CharT, _Traits, _Alloc>:: + _M_erase(size_type __pos, size_type __n) + { + const size_type __new_size = _M_length() - __n; + const size_type __how_much = _M_length() - __pos - __n; + + if (_M_is_shared()) + { + // Must reallocate. + _Rep* __r = _Rep::_S_create(__new_size, _M_capacity(), + _M_get_allocator()); + + if (__pos) + _S_copy(__r->_M_refdata(), _M_data(), __pos); + if (__how_much) + _S_copy(__r->_M_refdata() + __pos, + _M_data() + __pos + __n, __how_much); + + _M_dispose(); + _M_data(__r->_M_refdata()); + } + else if (__how_much && __n) + { + // Work in-place. + _S_move(_M_data() + __pos, + _M_data() + __pos + __n, __how_much); + } + + _M_rep()->_M_set_length(__new_size); + } + + template<> + inline bool + __rc_string_base<char, std::char_traits<char>, + std::allocator<char> >:: + _M_compare(const __rc_string_base& __rcs) const + { + if (_M_rep() == __rcs._M_rep()) + return true; + return false; + } + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + inline bool + __rc_string_base<wchar_t, std::char_traits<wchar_t>, + std::allocator<wchar_t> >:: + _M_compare(const __rc_string_base& __rcs) const + { + if (_M_rep() == __rcs._M_rep()) + return true; + return false; + } +#endif + +_GLIBCXX_END_NAMESPACE + +#endif /* _RC_STRING_BASE_H */ diff --git a/contrib/libstdc++/include/ext/rope b/contrib/libstdc++/include/ext/rope index b4bf2c9650ca..0cfd21e44625 100644 --- a/contrib/libstdc++/include/ext/rope +++ b/contrib/libstdc++/include/ext/rope @@ -1,6 +1,7 @@ // SGI's rope class -*- C++ -*- -// Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 +// Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -15,7 +16,7 @@ // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, // USA. // As a special exception, you may use this file as part of a free software @@ -42,8 +43,7 @@ /** @file ext/rope * This file is a GNU extension to the Standard C++ Library (possibly - * containing extensions from the HP/SGI STL subset). You should only - * include this header if you are using GCC 3 or later. + * containing extensions from the HP/SGI STL subset). */ #ifndef _ROPE @@ -67,282 +67,372 @@ #include <ext/memory> // For uninitialized_copy_n -namespace __gnu_cxx -{ -using std::size_t; -using std::ptrdiff_t; -using std::allocator; -using std::iterator; -using std::reverse_iterator; -using std::_Destroy; - -// 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 <class _CharT> -inline _CharT _S_eos(_CharT*) { return _CharT(); } - -// Test for basic character types. -// For basic character types leaves having a trailing eos. -template <class _CharT> -inline bool _S_is_basic_char_type(_CharT*) { return false; } -template <class _CharT> -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 <class _CharT> -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 _CharT> -class char_producer { +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + namespace __detail + { + enum { _S_max_rope_depth = 45 }; + enum _Tag {_S_leaf, _S_concat, _S_substringfn, _S_function}; + } // namespace __detail + + using std::size_t; + using std::ptrdiff_t; + using std::allocator; + using std::iterator; + using std::reverse_iterator; + using std::_Destroy; + + // 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 <class _CharT> + inline _CharT + _S_eos(_CharT*) + { return _CharT(); } + + // Test for basic character types. + // For basic character types leaves having a trailing eos. + template <class _CharT> + inline bool + _S_is_basic_char_type(_CharT*) + { return false; } + + template <class _CharT> + 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 <class _CharT> + 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 _CharT> + class char_producer + { public: - virtual ~char_producer() {}; - virtual void operator()(size_t __start_pos, size_t __len, - _CharT* __buffer) = 0; - // Buffer should really be an arbitrary output iterator. - // That way we could flatten directly into an ostream, etc. - // This is thoroughly impossible, since iterator types don't - // have runtime descriptions. -}; - -// Sequence buffers: -// -// Sequence must provide an append operation that appends an -// array to the sequence. Sequence buffers are useful only if -// appending an entire array is cheaper than appending element by element. -// This is true for many string representations. -// This should perhaps inherit from ostream<sequence::value_type> -// and be implemented correspondingly, so that they can be used -// for formatted. For the sake of portability, we don't do this yet. -// -// For now, sequence buffers behave as output iterators. But they also -// behave a little like basic_ostringstream<sequence::value_type> and a -// little like containers. + 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. + }; -template<class _Sequence, size_t _Buf_sz = 100> -class sequence_buffer : public iterator<std::output_iterator_tag,void,void,void,void> -{ + // Sequence buffers: + // + // Sequence must provide an append operation that appends an + // array to the sequence. Sequence buffers are useful only if + // appending an entire array is cheaper than appending element by element. + // This is true for many string representations. + // This should perhaps inherit from ostream<sequence::value_type> + // and be implemented correspondingly, so that they can be used + // for formatted. For the sake of portability, we don't do this yet. + // + // For now, sequence buffers behave as output iterators. But they also + // behave a little like basic_ostringstream<sequence::value_type> and a + // little like containers. + + template<class _Sequence, size_t _Buf_sz = 100> + class sequence_buffer + : public iterator<std::output_iterator_tag, void, void, void, void> + { public: - typedef typename _Sequence::value_type value_type; + typedef typename _Sequence::value_type value_type; protected: - _Sequence* _M_prefix; - value_type _M_buffer[_Buf_sz]; - size_t _M_buf_count; + _Sequence* _M_prefix; + value_type _M_buffer[_Buf_sz]; + size_t _M_buf_count; public: - 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; - std::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; - std::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; - for (size_t __j = 0; __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 _CharT> -class _Rope_char_consumer { + + 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; + std::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; + std::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; + for (size_t __j = 0; __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 _CharT> + class _Rope_char_consumer + { public: - // If we had member templates, these should not be virtual. - // For now we need to use run-time parametrization where - // compile-time would do. Hence this should all be private - // for now. - // The symmetry with char_producer is accidental and temporary. - virtual ~_Rope_char_consumer() {}; - virtual bool operator()(const _CharT* __buffer, size_t __len) = 0; -}; - -// First a lot of forward declarations. The standard seems to require -// much stricter "declaration before use" than many of the implementations -// that preceded it. -template<class _CharT, class _Alloc = allocator<_CharT> > class rope; -template<class _CharT, class _Alloc> struct _Rope_RopeConcatenation; -template<class _CharT, class _Alloc> struct _Rope_RopeLeaf; -template<class _CharT, class _Alloc> struct _Rope_RopeFunction; -template<class _CharT, class _Alloc> struct _Rope_RopeSubstring; -template<class _CharT, class _Alloc> class _Rope_iterator; -template<class _CharT, class _Alloc> class _Rope_const_iterator; -template<class _CharT, class _Alloc> class _Rope_char_ref_proxy; -template<class _CharT, class _Alloc> class _Rope_char_ptr_proxy; - -template<class _CharT, class _Alloc> -bool operator== (const _Rope_char_ptr_proxy<_CharT,_Alloc>& __x, - const _Rope_char_ptr_proxy<_CharT,_Alloc>& __y); - -template<class _CharT, class _Alloc> -_Rope_const_iterator<_CharT,_Alloc> operator- - (const _Rope_const_iterator<_CharT,_Alloc>& __x, - ptrdiff_t __n); - -template<class _CharT, class _Alloc> -_Rope_const_iterator<_CharT,_Alloc> operator+ - (const _Rope_const_iterator<_CharT,_Alloc>& __x, - ptrdiff_t __n); - -template<class _CharT, class _Alloc> -_Rope_const_iterator<_CharT,_Alloc> operator+ - (ptrdiff_t __n, - const _Rope_const_iterator<_CharT,_Alloc>& __x); - -template<class _CharT, class _Alloc> -bool operator== - (const _Rope_const_iterator<_CharT,_Alloc>& __x, - const _Rope_const_iterator<_CharT,_Alloc>& __y); - -template<class _CharT, class _Alloc> -bool operator< - (const _Rope_const_iterator<_CharT,_Alloc>& __x, - const _Rope_const_iterator<_CharT,_Alloc>& __y); - -template<class _CharT, class _Alloc> -ptrdiff_t operator- - (const _Rope_const_iterator<_CharT,_Alloc>& __x, - const _Rope_const_iterator<_CharT,_Alloc>& __y); - -template<class _CharT, class _Alloc> -_Rope_iterator<_CharT,_Alloc> operator- - (const _Rope_iterator<_CharT,_Alloc>& __x, - ptrdiff_t __n); - -template<class _CharT, class _Alloc> -_Rope_iterator<_CharT,_Alloc> operator+ - (const _Rope_iterator<_CharT,_Alloc>& __x, - ptrdiff_t __n); - -template<class _CharT, class _Alloc> -_Rope_iterator<_CharT,_Alloc> operator+ - (ptrdiff_t __n, - const _Rope_iterator<_CharT,_Alloc>& __x); - -template<class _CharT, class _Alloc> -bool operator== - (const _Rope_iterator<_CharT,_Alloc>& __x, - const _Rope_iterator<_CharT,_Alloc>& __y); - -template<class _CharT, class _Alloc> -bool operator< - (const _Rope_iterator<_CharT,_Alloc>& __x, - const _Rope_iterator<_CharT,_Alloc>& __y); - -template<class _CharT, class _Alloc> -ptrdiff_t operator- - (const _Rope_iterator<_CharT,_Alloc>& __x, - const _Rope_iterator<_CharT,_Alloc>& __y); - -template<class _CharT, class _Alloc> -rope<_CharT,_Alloc> operator+ (const rope<_CharT,_Alloc>& __left, - const rope<_CharT,_Alloc>& __right); - -template<class _CharT, class _Alloc> -rope<_CharT,_Alloc> operator+ (const rope<_CharT,_Alloc>& __left, - const _CharT* __right); - -template<class _CharT, class _Alloc> -rope<_CharT,_Alloc> operator+ (const rope<_CharT,_Alloc>& __left, - _CharT __right); - -// Some helpers, so we can use power on ropes. -// See below for why this isn't local to the implementation. - -// This uses a nonstandard refcount convention. -// The result has refcount 0. -template<class _CharT, class _Alloc> -struct _Rope_Concat_fn - : public std::binary_function<rope<_CharT,_Alloc>, rope<_CharT,_Alloc>, - rope<_CharT,_Alloc> > { - rope<_CharT,_Alloc> operator() (const rope<_CharT,_Alloc>& __x, - const rope<_CharT,_Alloc>& __y) { - return __x + __y; - } -}; - -template <class _CharT, class _Alloc> -inline -rope<_CharT,_Alloc> -identity_element(_Rope_Concat_fn<_CharT, _Alloc>) -{ - return rope<_CharT,_Alloc>(); -} + // 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; + }; + + // First a lot of forward declarations. The standard seems to require + // much stricter "declaration before use" than many of the implementations + // that preceded it. + template<class _CharT, class _Alloc = allocator<_CharT> > + class rope; + + template<class _CharT, class _Alloc> + struct _Rope_RopeConcatenation; + template<class _CharT, class _Alloc> + struct _Rope_RopeLeaf; + + template<class _CharT, class _Alloc> + struct _Rope_RopeFunction; + + template<class _CharT, class _Alloc> + struct _Rope_RopeSubstring; + + template<class _CharT, class _Alloc> + class _Rope_iterator; + + template<class _CharT, class _Alloc> + class _Rope_const_iterator; + + template<class _CharT, class _Alloc> + class _Rope_char_ref_proxy; + + template<class _CharT, class _Alloc> + class _Rope_char_ptr_proxy; + + template<class _CharT, class _Alloc> + bool + operator==(const _Rope_char_ptr_proxy<_CharT, _Alloc>& __x, + const _Rope_char_ptr_proxy<_CharT, _Alloc>& __y); + + template<class _CharT, class _Alloc> + _Rope_const_iterator<_CharT, _Alloc> + operator-(const _Rope_const_iterator<_CharT, _Alloc>& __x, + ptrdiff_t __n); + + template<class _CharT, class _Alloc> + _Rope_const_iterator<_CharT, _Alloc> + operator+(const _Rope_const_iterator<_CharT, _Alloc>& __x, + ptrdiff_t __n); + + template<class _CharT, class _Alloc> + _Rope_const_iterator<_CharT, _Alloc> + operator+(ptrdiff_t __n, + const _Rope_const_iterator<_CharT, _Alloc>& __x); + + template<class _CharT, class _Alloc> + bool + operator==(const _Rope_const_iterator<_CharT, _Alloc>& __x, + const _Rope_const_iterator<_CharT, _Alloc>& __y); + + template<class _CharT, class _Alloc> + bool + operator<(const _Rope_const_iterator<_CharT, _Alloc>& __x, + const _Rope_const_iterator<_CharT, _Alloc>& __y); + + template<class _CharT, class _Alloc> + ptrdiff_t + operator-(const _Rope_const_iterator<_CharT, _Alloc>& __x, + const _Rope_const_iterator<_CharT, _Alloc>& __y); + + template<class _CharT, class _Alloc> + _Rope_iterator<_CharT, _Alloc> + operator-(const _Rope_iterator<_CharT, _Alloc>& __x, ptrdiff_t __n); + + template<class _CharT, class _Alloc> + _Rope_iterator<_CharT, _Alloc> + operator+(const _Rope_iterator<_CharT, _Alloc>& __x, ptrdiff_t __n); + + template<class _CharT, class _Alloc> + _Rope_iterator<_CharT, _Alloc> + operator+(ptrdiff_t __n, const _Rope_iterator<_CharT, _Alloc>& __x); + + template<class _CharT, class _Alloc> + bool + operator==(const _Rope_iterator<_CharT, _Alloc>& __x, + const _Rope_iterator<_CharT, _Alloc>& __y); + + template<class _CharT, class _Alloc> + bool + operator<(const _Rope_iterator<_CharT, _Alloc>& __x, + const _Rope_iterator<_CharT, _Alloc>& __y); + + template<class _CharT, class _Alloc> + ptrdiff_t + operator-(const _Rope_iterator<_CharT, _Alloc>& __x, + const _Rope_iterator<_CharT, _Alloc>& __y); + + template<class _CharT, class _Alloc> + rope<_CharT, _Alloc> + operator+(const rope<_CharT, _Alloc>& __left, + const rope<_CharT, _Alloc>& __right); + + template<class _CharT, class _Alloc> + rope<_CharT, _Alloc> + operator+(const rope<_CharT, _Alloc>& __left, const _CharT* __right); + + template<class _CharT, class _Alloc> + rope<_CharT, _Alloc> + operator+(const rope<_CharT, _Alloc>& __left, _CharT __right); + + // Some helpers, so we can use power on ropes. + // See below for why this isn't local to the implementation. + + // This uses a nonstandard refcount convention. + // The result has refcount 0. + template<class _CharT, class _Alloc> + struct _Rope_Concat_fn + : public std::binary_function<rope<_CharT, _Alloc>, rope<_CharT, _Alloc>, + rope<_CharT, _Alloc> > + { + rope<_CharT, _Alloc> + operator()(const rope<_CharT, _Alloc>& __x, + const rope<_CharT, _Alloc>& __y) + { return __x + __y; } + }; + + template <class _CharT, class _Alloc> + inline rope<_CharT, _Alloc> + identity_element(_Rope_Concat_fn<_CharT, _Alloc>) + { return rope<_CharT, _Alloc>(); } // Class _Refcount_Base provides a type, _RC_t, a data member, // _M_ref_count, and member functions _M_incr and _M_decr, which perform @@ -352,7 +442,7 @@ identity_element(_Rope_Concat_fn<_CharT, _Alloc>) { // The type _RC_t typedef size_t _RC_t; - + // The data member _M_ref_count volatile _RC_t _M_ref_count; @@ -389,30 +479,30 @@ identity_element(_Rope_Concat_fn<_CharT, _Alloc>) } }; -// -// What follows should really be local to rope. Unfortunately, -// that doesn't work, since it makes it impossible to define generic -// equality on rope iterators. According to the draft standard, the -// template parameters for such an equality operator cannot be inferred -// from the occurrence of a member class as a parameter. -// (SGI compilers in fact allow this, but the __result wouldn't be -// portable.) -// Similarly, some of the static member functions are member functions -// only to avoid polluting the global namespace, and to circumvent -// restrictions on type inference for template functions. -// - -// -// The internal data structure for representing a rope. This is -// private to the implementation. A rope is really just a pointer -// to one of these. -// -// A few basic functions for manipulating this data structure -// are members of _RopeRep. Most of the more complex algorithms -// are implemented as rope members. -// -// Some of the static member functions of _RopeRep have identically -// named functions in rope that simply invoke the _RopeRep versions. + // + // What follows should really be local to rope. Unfortunately, + // that doesn't work, since it makes it impossible to define generic + // equality on rope iterators. According to the draft standard, the + // template parameters for such an equality operator cannot be inferred + // from the occurrence of a member class as a parameter. + // (SGI compilers in fact allow this, but the __result wouldn't be + // portable.) + // Similarly, some of the static member functions are member functions + // only to avoid polluting the global namespace, and to circumvent + // restrictions on type inference for template functions. + // + + // + // The internal data structure for representing a rope. This is + // private to the implementation. A rope is really just a pointer + // to one of these. + // + // A few basic functions for manipulating this data structure + // are members of _RopeRep. Most of the more complex algorithms + // are implemented as rope members. + // + // Some of the static member functions of _RopeRep have identically + // named functions in rope that simply invoke the _RopeRep versions. #define __ROPE_DEFINE_ALLOCS(__a) \ __ROPE_DEFINE_ALLOC(_CharT,_Data) /* character data */ \ @@ -425,28 +515,29 @@ identity_element(_Rope_Concat_fn<_CharT, _Alloc>) 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. + // 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. #define __STATIC_IF_SGI_ALLOC /* not static */ -template <class _CharT, class _Alloc> -struct _Rope_rep_base -: public _Alloc -{ - typedef _Alloc allocator_type; + template <class _CharT, class _Alloc> + struct _Rope_rep_base + : public _Alloc + { + typedef _Alloc allocator_type; - allocator_type - get_allocator() const { return *static_cast<const _Alloc*>(this); } + allocator_type + get_allocator() const + { return *static_cast<const _Alloc*>(this); } - _Rope_rep_base(size_t __size, const allocator_type&) - : _M_size(__size) {} + _Rope_rep_base(size_t __size, const allocator_type&) + : _M_size(__size) { } - size_t _M_size; + size_t _M_size; # define __ROPE_DEFINE_ALLOC(_Tp, __name) \ typedef typename \ @@ -455,2039 +546,2367 @@ struct _Rope_rep_base { return __name##Alloc().allocate(__n); } \ static void __name##_deallocate(_Tp *__p, size_t __n) \ { __name##Alloc().deallocate(__p, __n); } - __ROPE_DEFINE_ALLOCS(_Alloc) + __ROPE_DEFINE_ALLOCS(_Alloc) # undef __ROPE_DEFINE_ALLOC -}; - -namespace _Rope_constants -{ - enum { _S_max_rope_depth = 45 }; - enum _Tag {_S_leaf, _S_concat, _S_substringfn, _S_function}; -} + }; -template<class _CharT, class _Alloc> -struct _Rope_RopeRep : public _Rope_rep_base<_CharT,_Alloc> + template<class _CharT, class _Alloc> + struct _Rope_RopeRep + : public _Rope_rep_base<_CharT, _Alloc> # ifndef __GC - , _Refcount_Base + , _Refcount_Base # endif -{ + { public: - _Rope_constants::_Tag _M_tag:8; - bool _M_is_balanced:8; - unsigned char _M_depth; - __GC_CONST _CharT* _M_c_string; - __gthread_mutex_t _M_c_string_lock; + __detail::_Tag _M_tag:8; + bool _M_is_balanced:8; + unsigned char _M_depth; + __GC_CONST _CharT* _M_c_string; + __gthread_mutex_t _M_c_string_lock; /* 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 typename _Rope_rep_base<_CharT,_Alloc>::allocator_type - allocator_type; - using _Rope_rep_base<_CharT,_Alloc>::get_allocator; - _Rope_RopeRep(_Rope_constants::_Tag __t, int __d, bool __b, size_t __size, - allocator_type __a) - : _Rope_rep_base<_CharT,_Alloc>(__size, __a), -# ifndef __GC - _Refcount_Base(1), -# endif - _M_tag(__t), _M_is_balanced(__b), _M_depth(__d), _M_c_string(0) + typedef typename _Rope_rep_base<_CharT, _Alloc>::allocator_type + allocator_type; + + using _Rope_rep_base<_CharT, _Alloc>::get_allocator; + + _Rope_RopeRep(__detail::_Tag __t, int __d, bool __b, size_t __size, + allocator_type __a) + : _Rope_rep_base<_CharT, _Alloc>(__size, __a), +#ifndef __GC + _Refcount_Base(1), +#endif + _M_tag(__t), _M_is_balanced(__b), _M_depth(__d), _M_c_string(0) #ifdef __GTHREAD_MUTEX_INIT { - // Do not copy a POSIX/gthr mutex once in use. However, bits are bits. - __gthread_mutex_t __tmp = __GTHREAD_MUTEX_INIT; - _M_c_string_lock = __tmp; + // Do not copy a POSIX/gthr mutex once in use. However, bits are bits. + __gthread_mutex_t __tmp = __GTHREAD_MUTEX_INIT; + _M_c_string_lock = __tmp; } #else { __GTHREAD_MUTEX_INIT_FUNCTION (&_M_c_string_lock); } #endif -# ifdef __GC - void _M_incr () {} -# endif - 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); +#ifdef __GC + void + _M_incr () { } +#endif + 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); // 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 _M_free_c_string(); - void _M_free_tree(); - // Deallocate t. Assumes t is not 0. - void _M_unref_nonnil() - { - if (0 == _M_decr()) _M_free_tree(); - } - void _M_ref_nonnil() - { - _M_incr(); - } - 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(); - } - static void _S_free_if_unref(_Rope_RopeRep* __t) - { - if (0 != __t && 0 == __t->_M_ref_count) __t->_M_free_tree(); - } +#ifndef __GC + void _M_free_c_string(); + void _M_free_tree(); + // Deallocate t. Assumes t is not 0. + void + _M_unref_nonnil() + { + if (0 == _M_decr()) + _M_free_tree(); + } + + void + _M_ref_nonnil() + { _M_incr(); } + + 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(); + } + + static void + _S_free_if_unref(_Rope_RopeRep* __t) + { + if (0 != __t && 0 == __t->_M_ref_count) + __t->_M_free_tree(); + } # else /* __GC */ - 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*) {} + 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 protected: - _Rope_RopeRep& - operator=(const _Rope_RopeRep&); + _Rope_RopeRep& + operator=(const _Rope_RopeRep&); - _Rope_RopeRep(const _Rope_RopeRep&); -}; + _Rope_RopeRep(const _Rope_RopeRep&); + }; -template<class _CharT, class _Alloc> -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 accommodate future growth and for basic - // character types, to hold a trailing eos character. - enum { _S_alloc_granularity = 8 }; - static size_t _S_rounded_up_size(size_t __n) { + template<class _CharT, class _Alloc> + 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 accommodate future growth and for basic + // character types, to hold a trailing eos character. + 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 + size_t(_S_alloc_granularity) - 1) + &~ (size_t(_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 typename _Rope_rep_base<_CharT,_Alloc>::allocator_type + allocator_type; - 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 + _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 typename _Rope_rep_base<_CharT,_Alloc>::allocator_type - allocator_type; - _Rope_RopeLeaf(__GC_CONST _CharT* __d, size_t __size, allocator_type __a) - : _Rope_RopeRep<_CharT,_Alloc>(_Rope_constants::_S_leaf, 0, true, __size, __a), _M_data(__d) - { - if (_S_is_basic_char_type((_CharT *)0)) { + _Rope_RopeLeaf(__GC_CONST _CharT* __d, size_t __size, + allocator_type __a) + : _Rope_RopeRep<_CharT, _Alloc>(__detail::_S_leaf, 0, true, + __size, __a), _M_data(__d) + { + if (_S_is_basic_char_type((_CharT *)0)) + { // already eos terminated. this->_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() throw() { - if (_M_data != this->_M_c_string) { + } + } + // 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() throw() + { + if (_M_data != this->_M_c_string) this->_M_free_c_string(); - } + __STL_FREE_STRING(_M_data, this->_M_size, this->get_allocator()); - } -# endif + } +#endif protected: - _Rope_RopeLeaf& - operator=(const _Rope_RopeLeaf&); + _Rope_RopeLeaf& + operator=(const _Rope_RopeLeaf&); - _Rope_RopeLeaf(const _Rope_RopeLeaf&); -}; + _Rope_RopeLeaf(const _Rope_RopeLeaf&); + }; -template<class _CharT, class _Alloc> -struct _Rope_RopeConcatenation : public _Rope_RopeRep<_CharT,_Alloc> { - public: - _Rope_RopeRep<_CharT,_Alloc>* _M_left; - _Rope_RopeRep<_CharT,_Alloc>* _M_right; - typedef typename _Rope_rep_base<_CharT,_Alloc>::allocator_type - allocator_type; - _Rope_RopeConcatenation(_Rope_RopeRep<_CharT,_Alloc>* __l, - _Rope_RopeRep<_CharT,_Alloc>* __r, - allocator_type __a) - - : _Rope_RopeRep<_CharT,_Alloc>(_Rope_constants::_S_concat, - std::max(__l->_M_depth, __r->_M_depth) + 1, - false, - __l->_M_size + __r->_M_size, __a), + template<class _CharT, class _Alloc> + struct _Rope_RopeConcatenation + : public _Rope_RopeRep<_CharT, _Alloc> + { + public: + _Rope_RopeRep<_CharT, _Alloc>* _M_left; + _Rope_RopeRep<_CharT, _Alloc>* _M_right; + + typedef typename _Rope_rep_base<_CharT, _Alloc>::allocator_type + allocator_type; + + _Rope_RopeConcatenation(_Rope_RopeRep<_CharT, _Alloc>* __l, + _Rope_RopeRep<_CharT, _Alloc>* __r, + allocator_type __a) + : _Rope_RopeRep<_CharT, _Alloc>(__detail::_S_concat, + std::max(__l->_M_depth, + __r->_M_depth) + 1, + false, + __l->_M_size + __r->_M_size, __a), _M_left(__l), _M_right(__r) - {} -# ifndef __GC - ~_Rope_RopeConcatenation() throw() { - this->_M_free_c_string(); - _M_left->_M_unref_nonnil(); - _M_right->_M_unref_nonnil(); - } -# endif + { } +#ifndef __GC + ~_Rope_RopeConcatenation() throw() + { + this->_M_free_c_string(); + _M_left->_M_unref_nonnil(); + _M_right->_M_unref_nonnil(); + } +#endif protected: - _Rope_RopeConcatenation& - operator=(const _Rope_RopeConcatenation&); - - _Rope_RopeConcatenation(const _Rope_RopeConcatenation&); -}; + _Rope_RopeConcatenation& + operator=(const _Rope_RopeConcatenation&); + + _Rope_RopeConcatenation(const _Rope_RopeConcatenation&); + }; -template<class _CharT, class _Alloc> -struct _Rope_RopeFunction : public _Rope_RopeRep<_CharT,_Alloc> { - public: - char_producer<_CharT>* _M_fn; -# ifndef __GC + template<class _CharT, class _Alloc> + struct _Rope_RopeFunction + : public _Rope_RopeRep<_CharT, _Alloc> + { + public: + char_producer<_CharT>* _M_fn; +#ifndef __GC bool _M_delete_when_done; // Char_producer is owned by the // rope and should be explicitly // deleted when the rope becomes // inaccessible. -# else +#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 typename _Rope_rep_base<_CharT,_Alloc>::allocator_type - allocator_type; - _Rope_RopeFunction(char_producer<_CharT>* __f, size_t __size, + static void + _S_fn_finalization_proc(void * __tree, void *) + { delete ((_Rope_RopeFunction *)__tree) -> _M_fn; } +#endif + typedef typename _Rope_rep_base<_CharT, _Alloc>::allocator_type + allocator_type; + + _Rope_RopeFunction(char_producer<_CharT>* __f, size_t __size, bool __d, allocator_type __a) - : _Rope_RopeRep<_CharT,_Alloc>(_Rope_constants::_S_function, - 0, true, __size, __a) - , _M_fn(__f) -# ifndef __GC - , _M_delete_when_done(__d) -# endif - { -# ifdef __GC - if (__d) { - GC_REGISTER_FINALIZER( - this, _Rope_RopeFunction::_S_fn_finalization_proc, 0, 0, 0); - } -# endif - } -# ifndef __GC - ~_Rope_RopeFunction() throw() { - this->_M_free_c_string(); - if (_M_delete_when_done) { - delete _M_fn; - } - } + : _Rope_RopeRep<_CharT, _Alloc>(__detail::_S_function, 0, true, __size, __a) + , _M_fn(__f) +#ifndef __GC + , _M_delete_when_done(__d) +#endif + { +#ifdef __GC + if (__d) + { + GC_REGISTER_FINALIZER(this, _Rope_RopeFunction:: + _S_fn_finalization_proc, 0, 0, 0); + } +#endif + } +#ifndef __GC + ~_Rope_RopeFunction() throw() + { + this->_M_free_c_string(); + if (_M_delete_when_done) + delete _M_fn; + } # endif -protected: - _Rope_RopeFunction& - operator=(const _Rope_RopeFunction&); - - _Rope_RopeFunction(const _Rope_RopeFunction&); -}; -// Substring results are usually represented using just -// concatenation nodes. But in the case of very long flat ropes -// or ropes with a functional representation that isn't practical. -// In that case, we represent the __result as a special case of -// RopeFunction, whose char_producer points back to the rope itself. -// In all cases except repeated substring operations and -// deallocation, we treat the __result as a RopeFunction. -template<class _CharT, class _Alloc> -struct _Rope_RopeSubstring : public _Rope_RopeFunction<_CharT,_Alloc>, - public char_producer<_CharT> { - public: - // 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 _Rope_constants::_S_function: - case _Rope_constants::_S_substringfn: - { - char_producer<_CharT>* __fn = - ((_Rope_RopeFunction<_CharT,_Alloc>*)_M_base)->_M_fn; - (*__fn)(__start_pos + _M_start, __req_len, __buffer); - } - break; - case _Rope_constants::_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: - break; - } - } - typedef typename _Rope_rep_base<_CharT,_Alloc>::allocator_type + protected: + _Rope_RopeFunction& + operator=(const _Rope_RopeFunction&); + + _Rope_RopeFunction(const _Rope_RopeFunction&); + }; + // Substring results are usually represented using just + // concatenation nodes. But in the case of very long flat ropes + // or ropes with a functional representation that isn't practical. + // In that case, we represent the __result as a special case of + // RopeFunction, whose char_producer points back to the rope itself. + // In all cases except repeated substring operations and + // deallocation, we treat the __result as a RopeFunction. + template<class _CharT, class _Alloc> + struct _Rope_RopeSubstring + : public _Rope_RopeFunction<_CharT, _Alloc>, + public char_producer<_CharT> + { + public: + // 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 __detail::_S_function: + case __detail::_S_substringfn: + { + char_producer<_CharT>* __fn = + ((_Rope_RopeFunction<_CharT,_Alloc>*)_M_base)->_M_fn; + (*__fn)(__start_pos + _M_start, __req_len, __buffer); + } + break; + case __detail::_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: + break; + } + } + + typedef typename _Rope_rep_base<_CharT, _Alloc>::allocator_type allocator_type; - _Rope_RopeSubstring(_Rope_RopeRep<_CharT,_Alloc>* __b, size_t __s, + + _Rope_RopeSubstring(_Rope_RopeRep<_CharT, _Alloc>* __b, size_t __s, size_t __l, allocator_type __a) - : _Rope_RopeFunction<_CharT,_Alloc>(this, __l, false, __a), - char_producer<_CharT>(), - _M_base(__b), - _M_start(__s) - { -# ifndef __GC - _M_base->_M_ref_nonnil(); -# endif - this->_M_tag = _Rope_constants::_S_substringfn; - } + : _Rope_RopeFunction<_CharT, _Alloc>(this, __l, false, __a), + char_producer<_CharT>(), _M_base(__b), _M_start(__s) + { +#ifndef __GC + _M_base->_M_ref_nonnil(); +#endif + this->_M_tag = __detail::_S_substringfn; + } virtual ~_Rope_RopeSubstring() throw() { -# ifndef __GC - _M_base->_M_unref_nonnil(); - // _M_free_c_string(); -- done by parent class -# endif +#ifndef __GC + _M_base->_M_unref_nonnil(); + // _M_free_c_string(); -- done by parent class +#endif } -}; - + }; -// 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 -// is raised. It is the caller's responsibility to -// adjust reference counts when these pointers are initialized -// or assigned to. (This convention significantly reduces -// the number of potentially expensive reference count -// updates.) + // 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 + // is raised. It is the caller's responsibility to + // adjust reference counts when these pointers are initialized + // or assigned to. (This convention significantly reduces + // the number of potentially expensive reference count + // updates.) #ifndef __GC template<class _CharT, class _Alloc> - struct _Rope_self_destruct_ptr { - _Rope_RopeRep<_CharT,_Alloc>* _M_ptr; - ~_Rope_self_destruct_ptr() - { _Rope_RopeRep<_CharT,_Alloc>::_S_unref(_M_ptr); } + struct _Rope_self_destruct_ptr + { + _Rope_RopeRep<_CharT, _Alloc>* _M_ptr; + + ~_Rope_self_destruct_ptr() + { _Rope_RopeRep<_CharT, _Alloc>::_S_unref(_M_ptr); } #ifdef __EXCEPTIONS - _Rope_self_destruct_ptr() : _M_ptr(0) {}; + _Rope_self_destruct_ptr() : _M_ptr(0) { }; #else - _Rope_self_destruct_ptr() {}; + _Rope_self_destruct_ptr() { }; #endif - _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; } - }; + _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 -// Dereferencing a nonconst iterator has to return something -// that behaves almost like a reference. It's not possible to -// return an actual reference since assignment requires extra -// work. And we would get into the same problems as with the -// CD2 version of basic_string. -template<class _CharT, class _Alloc> -class _Rope_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_RopeRep<_CharT,_Alloc>* _Self_destruct_ptr; -# else - typedef _Rope_self_destruct_ptr<_CharT,_Alloc> _Self_destruct_ptr; -# endif - 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_char_ref_proxy(_My_rope* __r, size_t __p) - : _M_pos(__p), _M_current(), _M_current_valid(false), _M_root(__r) {} - - _Rope_char_ref_proxy(const _Rope_char_ref_proxy& __x) - : _M_pos(__x._M_pos), _M_current(__x._M_current), _M_current_valid(false), - _M_root(__x._M_root) {} - - // 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_current(__c), _M_current_valid(true), _M_root(__r) {} - 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 _CharT, class __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; -} - -template<class _CharT, class _Alloc> -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_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) { + // Dereferencing a nonconst iterator has to return something + // that behaves almost like a reference. It's not possible to + // return an actual reference since assignment requires extra + // work. And we would get into the same problems as with the + // CD2 version of basic_string. + template<class _CharT, class _Alloc> + class _Rope_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_RopeRep<_CharT, _Alloc>* _Self_destruct_ptr; +#else + typedef _Rope_self_destruct_ptr<_CharT, _Alloc> _Self_destruct_ptr; +#endif + 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_char_ref_proxy(_My_rope* __r, size_t __p) + : _M_pos(__p), _M_current(), _M_current_valid(false), _M_root(__r) { } + + _Rope_char_ref_proxy(const _Rope_char_ref_proxy& __x) + : _M_pos(__x._M_pos), _M_current(__x._M_current), + _M_current_valid(false), _M_root(__x._M_root) { } + + // 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_current(__c), _M_current_valid(true), _M_root(__r) { } + + 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 _CharT, class __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_char_ptr_proxy& - operator= (const _Rope_char_ptr_proxy& __x) { + + template<class _CharT, class _Alloc> + 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_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) { } + + _Rope_char_ptr_proxy& + operator=(const _Rope_char_ptr_proxy& __x) + { _M_pos = __x._M_pos; _M_root = __x._M_root; return *this; - } - template<class _CharT2, class _Alloc2> - friend bool operator== (const _Rope_char_ptr_proxy<_CharT2,_Alloc2>& __x, - const _Rope_char_ptr_proxy<_CharT2,_Alloc2>& __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. -// When we run out of cache, we have to reconstruct the iterator -// value. -// Pointers from iterators are not included in reference counts. -// Iterators are assumed to be thread private. Ropes can -// be shared. - -template<class _CharT, class _Alloc> -class _Rope_iterator_base - : public iterator<std::random_access_iterator_tag, _CharT> -{ - friend class rope<_CharT,_Alloc>; - public: - typedef _Alloc _allocator_type; // used in _Rope_rotate, VC++ workaround - typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep; - // Borland doesn't want this to be protected. - protected: - 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 _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; + } + + template<class _CharT2, class _Alloc2> + friend bool + operator==(const _Rope_char_ptr_proxy<_CharT2, _Alloc2>& __x, + const _Rope_char_ptr_proxy<_CharT2, _Alloc2>& __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. + // When we run out of cache, we have to reconstruct the iterator + // value. + // Pointers from iterators are not included in reference counts. + // Iterators are assumed to be thread private. Ropes can + // be shared. + + template<class _CharT, class _Alloc> + class _Rope_iterator_base + : public iterator<std::random_access_iterator_tag, _CharT> + { + friend class rope<_CharT, _Alloc>; + public: + typedef _Alloc _allocator_type; // used in _Rope_rotate, VC++ workaround + typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep; + // Borland doesn't want this to be protected. + protected: + 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 _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]; + _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 _S_setbuf(_Rope_iterator_base& __x); + // The cached path is generally assumed to be valid + // only if the buffer is valid. + static void _S_setbuf(_Rope_iterator_base& __x); // Set buffer contents given // path cache. - static void _S_setcache(_Rope_iterator_base& __x); + static void _S_setcache(_Rope_iterator_base& __x); // Set buffer contents and // path cache. - static void _S_setcache_for_incr(_Rope_iterator_base& __x); + 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_current_pos(__pos), _M_root(__root), _M_buf_ptr(0) {} - void _M_incr(size_t __n); - void _M_decr(size_t __n); - public: - 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 { + _Rope_iterator_base() { } + + _Rope_iterator_base(_RopeRep* __root, size_t __pos) + : _M_current_pos(__pos), _M_root(__root), _M_buf_ptr(0) { } + + void _M_incr(size_t __n); + void _M_decr(size_t __n); + public: + 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 _CharT, class _Alloc> class _Rope_iterator; + template<class _CharT, class _Alloc> + class _Rope_iterator; -template<class _CharT, class _Alloc> -class _Rope_const_iterator : public _Rope_iterator_base<_CharT,_Alloc> { - friend class rope<_CharT,_Alloc>; - protected: - typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep; + template<class _CharT, class _Alloc> + class _Rope_const_iterator + : public _Rope_iterator_base<_CharT, _Alloc> + { + friend class rope<_CharT, _Alloc>; + protected: + typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep; // The one from the base class may not be directly visible. - _Rope_const_iterator(const _RopeRep* __root, size_t __pos): - _Rope_iterator_base<_CharT,_Alloc>( - const_cast<_RopeRep*>(__root), __pos) + _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<_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 { + public: + _Rope_const_iterator() { }; + + _Rope_const_iterator(const _Rope_const_iterator& __x) + : _Rope_iterator_base<_CharT,_Alloc>(__x) { } + + _Rope_const_iterator(const _Rope_iterator<_CharT,_Alloc>& __x); + + _Rope_const_iterator(const rope<_CharT, _Alloc>& __r, size_t __pos) + : _Rope_iterator_base<_CharT,_Alloc>(__r._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 + { this->_M_current_pos = __x._M_current_pos; this->_M_root = __x._M_root; this->_M_buf_ptr = 0; - } + } return(*this); - } - reference operator*() { - if (0 == this->_M_buf_ptr) _S_setcache(*this); + } + + reference + operator*() + { + if (0 == this->_M_buf_ptr) + _S_setcache(*this); return *this->_M_buf_ptr; - } - _Rope_const_iterator& operator++() { + } + + // Without this const version, Rope iterators do not meet the + // requirements of an Input Iterator. + reference + operator*() const + { + return *const_cast<_Rope_const_iterator&>(*this); + } + + _Rope_const_iterator& + operator++() + { __GC_CONST _CharT* __next; if (0 != this->_M_buf_ptr - && (__next = this->_M_buf_ptr + 1) < this->_M_buf_end) { + && (__next = this->_M_buf_ptr + 1) < this->_M_buf_end) + { this->_M_buf_ptr = __next; ++this->_M_current_pos; - } else { - this->_M_incr(1); - } - return *this; - } - _Rope_const_iterator& operator+=(ptrdiff_t __n) { - if (__n >= 0) { - this->_M_incr(__n); - } else { - this->_M_decr(-__n); - } - return *this; - } - _Rope_const_iterator& operator--() { + } + else + this->_M_incr(1); + return *this; + } + + _Rope_const_iterator& + operator+=(ptrdiff_t __n) + { + if (__n >= 0) + this->_M_incr(__n); + else + this->_M_decr(-__n); + return *this; + } + + _Rope_const_iterator& + operator--() + { this->_M_decr(1); return *this; - } - _Rope_const_iterator& operator-=(ptrdiff_t __n) { - if (__n >= 0) { - this->_M_decr(__n); - } else { - this->_M_incr(-__n); - } - return *this; - } - _Rope_const_iterator operator++(int) { + } + + _Rope_const_iterator& + operator-=(ptrdiff_t __n) + { + if (__n >= 0) + this->_M_decr(__n); + else + this->_M_incr(-__n); + return *this; + } + + _Rope_const_iterator + operator++(int) + { size_t __old_pos = this->_M_current_pos; this->_M_incr(1); return _Rope_const_iterator<_CharT,_Alloc>(this->_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) { + } + + _Rope_const_iterator + operator--(int) + { size_t __old_pos = this->_M_current_pos; this->_M_decr(1); return _Rope_const_iterator<_CharT,_Alloc>(this->_M_root, __old_pos); - } - template<class _CharT2, class _Alloc2> - friend _Rope_const_iterator<_CharT2,_Alloc2> operator- - (const _Rope_const_iterator<_CharT2,_Alloc2>& __x, - ptrdiff_t __n); - template<class _CharT2, class _Alloc2> - friend _Rope_const_iterator<_CharT2,_Alloc2> operator+ - (const _Rope_const_iterator<_CharT2,_Alloc2>& __x, - ptrdiff_t __n); - template<class _CharT2, class _Alloc2> - friend _Rope_const_iterator<_CharT2,_Alloc2> operator+ - (ptrdiff_t __n, - const _Rope_const_iterator<_CharT2,_Alloc2>& __x); - reference operator[](size_t __n) { - return rope<_CharT,_Alloc>::_S_fetch(this->_M_root, - this->_M_current_pos + __n); - } + } + + template<class _CharT2, class _Alloc2> + friend _Rope_const_iterator<_CharT2, _Alloc2> + operator-(const _Rope_const_iterator<_CharT2, _Alloc2>& __x, + ptrdiff_t __n); + + template<class _CharT2, class _Alloc2> + friend _Rope_const_iterator<_CharT2, _Alloc2> + operator+(const _Rope_const_iterator<_CharT2, _Alloc2>& __x, + ptrdiff_t __n); + + template<class _CharT2, class _Alloc2> + friend _Rope_const_iterator<_CharT2, _Alloc2> + operator+(ptrdiff_t __n, + const _Rope_const_iterator<_CharT2, _Alloc2>& __x); + + reference + operator[](size_t __n) + { return rope<_CharT, _Alloc>::_S_fetch(this->_M_root, + this->_M_current_pos + __n); } + + template<class _CharT2, class _Alloc2> + friend bool + operator==(const _Rope_const_iterator<_CharT2, _Alloc2>& __x, + const _Rope_const_iterator<_CharT2, _Alloc2>& __y); + + template<class _CharT2, class _Alloc2> + friend bool + operator<(const _Rope_const_iterator<_CharT2, _Alloc2>& __x, + const _Rope_const_iterator<_CharT2, _Alloc2>& __y); + + template<class _CharT2, class _Alloc2> + friend ptrdiff_t + operator-(const _Rope_const_iterator<_CharT2, _Alloc2>& __x, + const _Rope_const_iterator<_CharT2, _Alloc2>& __y); + }; + + template<class _CharT, class _Alloc> + class _Rope_iterator + : public _Rope_iterator_base<_CharT, _Alloc> + { + friend class rope<_CharT, _Alloc>; + protected: + typedef typename _Rope_iterator_base<_CharT, _Alloc>::_RopeRep _RopeRep; + rope<_CharT, _Alloc>* _M_root_rope; - template<class _CharT2, class _Alloc2> - friend bool operator== - (const _Rope_const_iterator<_CharT2,_Alloc2>& __x, - const _Rope_const_iterator<_CharT2,_Alloc2>& __y); - template<class _CharT2, class _Alloc2> - friend bool operator< - (const _Rope_const_iterator<_CharT2,_Alloc2>& __x, - const _Rope_const_iterator<_CharT2,_Alloc2>& __y); - template<class _CharT2, class _Alloc2> - friend ptrdiff_t operator- - (const _Rope_const_iterator<_CharT2,_Alloc2>& __x, - const _Rope_const_iterator<_CharT2,_Alloc2>& __y); -}; - -template<class _CharT, class _Alloc> -class _Rope_iterator : public _Rope_iterator_base<_CharT,_Alloc> { - friend class rope<_CharT,_Alloc>; - protected: - typedef typename _Rope_iterator_base<_CharT,_Alloc>::_RopeRep _RopeRep; - 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), + // 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(this->_M_root); - if (!(__r -> empty()))_S_setcache(*this); } + if (!(__r -> empty())) + _S_setcache(*this); + } - void _M_check(); - public: - typedef _Rope_char_ref_proxy<_CharT,_Alloc> reference; - typedef _Rope_char_ref_proxy<_CharT,_Alloc>* pointer; + void _M_check(); + public: + typedef _Rope_char_ref_proxy<_CharT, _Alloc> reference; + typedef _Rope_char_ref_proxy<_CharT, _Alloc>* pointer; - public: - rope<_CharT,_Alloc>& container() { return *_M_root_rope; } - _Rope_iterator() { + rope<_CharT, _Alloc>& + container() + { return *_M_root_rope; } + + _Rope_iterator() + { this->_M_root = 0; // Needed for reference counting. - }; - _Rope_iterator(const _Rope_iterator& __x) : - _Rope_iterator_base<_CharT,_Alloc>(__x) { + }; + + _Rope_iterator(const _Rope_iterator& __x) + : _Rope_iterator_base<_CharT, _Alloc>(__x) + { _M_root_rope = __x._M_root_rope; _RopeRep::_S_ref(this->_M_root); - } - _Rope_iterator(rope<_CharT,_Alloc>& __r, size_t __pos); - ~_Rope_iterator() { - _RopeRep::_S_unref(this->_M_root); - } - _Rope_iterator& operator= (const _Rope_iterator& __x) { - _RopeRep* __old = this->_M_root; + } + + _Rope_iterator(rope<_CharT, _Alloc>& __r, size_t __pos); + ~_Rope_iterator() + { _RopeRep::_S_unref(this->_M_root); } + + _Rope_iterator& + operator=(const _Rope_iterator& __x) + { + _RopeRep* __old = this->_M_root; + _RopeRep::_S_ref(__x._M_root); - if (0 != __x._M_buf_ptr) { + if (0 != __x._M_buf_ptr) + { _M_root_rope = __x._M_root_rope; - *(static_cast<_Rope_iterator_base<_CharT,_Alloc>*>(this)) = __x; - } else { + *(static_cast<_Rope_iterator_base<_CharT, _Alloc>*>(this)) = __x; + } + else + { this->_M_current_pos = __x._M_current_pos; this->_M_root = __x._M_root; _M_root_rope = __x._M_root_rope; this->_M_buf_ptr = 0; - } + } _RopeRep::_S_unref(__old); return(*this); - } - reference operator*() { + } + + reference + operator*() + { _M_check(); - if (0 == this->_M_buf_ptr) { - return _Rope_char_ref_proxy<_CharT,_Alloc>( - _M_root_rope, this->_M_current_pos); - } else { - return _Rope_char_ref_proxy<_CharT,_Alloc>( - _M_root_rope, this->_M_current_pos, *this->_M_buf_ptr); - } - } - _Rope_iterator& operator++() { + if (0 == this->_M_buf_ptr) + return _Rope_char_ref_proxy<_CharT, _Alloc>(_M_root_rope, + this->_M_current_pos); + else + return _Rope_char_ref_proxy<_CharT, _Alloc>(_M_root_rope, + this->_M_current_pos, + *this->_M_buf_ptr); + } + + // See above comment. + reference + operator*() const + { + return *const_cast<_Rope_iterator&>(*this); + } + + _Rope_iterator& + operator++() + { this->_M_incr(1); return *this; - } - _Rope_iterator& operator+=(ptrdiff_t __n) { - if (__n >= 0) { - this->_M_incr(__n); - } else { - this->_M_decr(-__n); - } - return *this; - } - _Rope_iterator& operator--() { + } + + _Rope_iterator& + operator+=(ptrdiff_t __n) + { + if (__n >= 0) + this->_M_incr(__n); + else + this->_M_decr(-__n); + return *this; + } + + _Rope_iterator& + operator--() + { this->_M_decr(1); return *this; - } - _Rope_iterator& operator-=(ptrdiff_t __n) { - if (__n >= 0) { - this->_M_decr(__n); - } else { - this->_M_incr(-__n); - } - return *this; - } - _Rope_iterator operator++(int) { + } + + _Rope_iterator& + operator-=(ptrdiff_t __n) + { + if (__n >= 0) + this->_M_decr(__n); + else + this->_M_incr(-__n); + return *this; + } + + _Rope_iterator + operator++(int) + { size_t __old_pos = this->_M_current_pos; this->_M_incr(1); return _Rope_iterator<_CharT,_Alloc>(_M_root_rope, __old_pos); - } - _Rope_iterator operator--(int) { + } + + _Rope_iterator + operator--(int) + { size_t __old_pos = this->_M_current_pos; this->_M_decr(1); return _Rope_iterator<_CharT,_Alloc>(_M_root_rope, __old_pos); - } - reference operator[](ptrdiff_t __n) { - return _Rope_char_ref_proxy<_CharT,_Alloc>( - _M_root_rope, this->_M_current_pos + __n); - } + } - template<class _CharT2, class _Alloc2> - friend bool operator== - (const _Rope_iterator<_CharT2,_Alloc2>& __x, - const _Rope_iterator<_CharT2,_Alloc2>& __y); - template<class _CharT2, class _Alloc2> - friend bool operator< - (const _Rope_iterator<_CharT2,_Alloc2>& __x, - const _Rope_iterator<_CharT2,_Alloc2>& __y); - template<class _CharT2, class _Alloc2> - friend ptrdiff_t operator- - (const _Rope_iterator<_CharT2,_Alloc2>& __x, - const _Rope_iterator<_CharT2,_Alloc2>& __y); - template<class _CharT2, class _Alloc2> - friend _Rope_iterator<_CharT2,_Alloc2> operator- - (const _Rope_iterator<_CharT2,_Alloc2>& __x, - ptrdiff_t __n); - template<class _CharT2, class _Alloc2> - friend _Rope_iterator<_CharT2,_Alloc2> operator+ - (const _Rope_iterator<_CharT2,_Alloc2>& __x, - ptrdiff_t __n); - template<class _CharT2, class _Alloc2> - friend _Rope_iterator<_CharT2,_Alloc2> operator+ - (ptrdiff_t __n, - const _Rope_iterator<_CharT2,_Alloc2>& __x); -}; - - -template <class _CharT, class _Alloc> -struct _Rope_base -: public _Alloc -{ - typedef _Alloc allocator_type; - - allocator_type - get_allocator() const { return *static_cast<const _Alloc*>(this); } - - typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep; - // The one in _Base may not be visible due to template rules. - - _Rope_base(_RopeRep* __t, const allocator_type&) - : _M_tree_ptr(__t) {} - _Rope_base(const allocator_type&) {} - - // The only data member of a rope: - _RopeRep *_M_tree_ptr; + reference + operator[](ptrdiff_t __n) + { return _Rope_char_ref_proxy<_CharT, _Alloc>(_M_root_rope, + this->_M_current_pos + + __n); } + + template<class _CharT2, class _Alloc2> + friend bool + operator==(const _Rope_iterator<_CharT2, _Alloc2>& __x, + const _Rope_iterator<_CharT2, _Alloc2>& __y); + + template<class _CharT2, class _Alloc2> + friend bool + operator<(const _Rope_iterator<_CharT2, _Alloc2>& __x, + const _Rope_iterator<_CharT2, _Alloc2>& __y); + + template<class _CharT2, class _Alloc2> + friend ptrdiff_t + operator-(const _Rope_iterator<_CharT2, _Alloc2>& __x, + const _Rope_iterator<_CharT2, _Alloc2>& __y); + + template<class _CharT2, class _Alloc2> + friend _Rope_iterator<_CharT2, _Alloc2> + operator-(const _Rope_iterator<_CharT2, _Alloc2>& __x, ptrdiff_t __n); + + template<class _CharT2, class _Alloc2> + friend _Rope_iterator<_CharT2, _Alloc2> + operator+(const _Rope_iterator<_CharT2, _Alloc2>& __x, ptrdiff_t __n); + + template<class _CharT2, class _Alloc2> + friend _Rope_iterator<_CharT2, _Alloc2> + operator+(ptrdiff_t __n, const _Rope_iterator<_CharT2, _Alloc2>& __x); + }; -# define __ROPE_DEFINE_ALLOC(_Tp, __name) \ + + template <class _CharT, class _Alloc> + struct _Rope_base + : public _Alloc + { + typedef _Alloc allocator_type; + + allocator_type + get_allocator() const + { return *static_cast<const _Alloc*>(this); } + + typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep; + // The one in _Base may not be visible due to template rules. + + _Rope_base(_RopeRep* __t, const allocator_type&) + : _M_tree_ptr(__t) { } + + _Rope_base(const allocator_type&) { } + + // The only data member of a rope: + _RopeRep *_M_tree_ptr; + +#define __ROPE_DEFINE_ALLOC(_Tp, __name) \ typedef typename \ _Alloc::template rebind<_Tp>::other __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 + __ROPE_DEFINE_ALLOCS(_Alloc) +#undef __ROPE_DEFINE_ALLOC + + protected: + _Rope_base& + operator=(const _Rope_base&); + + _Rope_base(const _Rope_base&); + }; -protected: - _Rope_base& - operator=(const _Rope_base&); + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template <class _CharT, class _Alloc> + 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<_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>; - _Rope_base(const _Rope_base&); -}; + protected: + typedef _Rope_base<_CharT, _Alloc> _Base; + typedef typename _Base::allocator_type allocator_type; + using _Base::_M_tree_ptr; + using _Base::get_allocator; + typedef __GC_CONST _CharT* _Cstrptr; + + 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; -/** - * This is an SGI extension. - * @ingroup SGIextensions - * @doctodo -*/ -template <class _CharT, class _Alloc> -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<_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>; + // Retrieve a character at the indicated position. + static _CharT _S_fetch(_RopeRep* __r, size_type __pos); - protected: - typedef _Rope_base<_CharT,_Alloc> _Base; - typedef typename _Base::allocator_type allocator_type; - using _Base::_M_tree_ptr; - using _Base::get_allocator; - typedef __GC_CONST _CharT* _Cstrptr; +#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 _CharT _S_empty_c_str[1]; + 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. - 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. +#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 _S_unref(_RopeRep*) { } + static void _S_ref(_RopeRep*) { } +#endif - 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 _S_unref(_RopeRep*) {} - static void _S_ref(_RopeRep*) {} -# endif - - -# ifdef __GC - 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, +#ifdef __GC + 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 - // relevant 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. + 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 + // relevant 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 - public: - void apply_to_pieces( size_t __begin, size_t __end, - _Rope_char_consumer<_CharT>& __c) const { - _S_apply_to_pieces(__c, this->_M_tree_ptr, __begin, __end); - } + 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<_CharT>& __c) const + { _S_apply_to_pieces(__c, this->_M_tree_ptr, __begin, __end); } protected: - 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) - { - _RopeLeaf* __space = typename _Base::_LAlloc(__a).allocate(1); - return new(__space) _RopeLeaf(__s, __size, __a); - } - - static _RopeConcatenation* _S_new_RopeConcatenation( - _RopeRep* __left, _RopeRep* __right, - allocator_type __a) - { - _RopeConcatenation* __space = typename _Base::_CAlloc(__a).allocate(1); - return new(__space) _RopeConcatenation(__left, __right, __a); - } - - static _RopeFunction* _S_new_RopeFunction(char_producer<_CharT>* __f, - size_t __size, bool __d, allocator_type __a) - { - _RopeFunction* __space = typename _Base::_FAlloc(__a).allocate(1); - 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) - { - _RopeSubstring* __space = typename _Base::_SAlloc(__a).allocate(1); - return new(__space) _RopeSubstring(__b, __s, __l, __a); - } - - 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) \ + 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) + { + _RopeLeaf* __space = typename _Base::_LAlloc(__a).allocate(1); + return new(__space) _RopeLeaf(__s, __size, __a); + } + + static _RopeConcatenation* + _S_new_RopeConcatenation(_RopeRep* __left, _RopeRep* __right, + allocator_type __a) + { + _RopeConcatenation* __space = typename _Base::_CAlloc(__a).allocate(1); + return new(__space) _RopeConcatenation(__left, __right, __a); + } + + static _RopeFunction* + _S_new_RopeFunction(char_producer<_CharT>* __f, + size_t __size, bool __d, allocator_type __a) + { + _RopeFunction* __space = typename _Base::_FAlloc(__a).allocate(1); + 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) + { + _RopeSubstring* __space = typename _Base::_SAlloc(__a).allocate(1); + return new(__space) _RopeSubstring(__b, __s, __l, __a); + } + + 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) - { - if (0 == __size) return 0; - _CharT* __buf = __a.allocate(_S_rounded_up_size(__size)); - - uninitialized_copy_n(__s, __size, __buf); - _S_cond_store_eos(__buf[__size]); - try { - return _S_new_RopeLeaf(__buf, __size, __a); - } - catch(...) - { - _RopeRep::__STL_FREE_STRING(__buf, __size, __a); - __throw_exception_again; - } - } - - - // 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_ref_count == 1. -# endif - - private: - - 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[_Rope_constants::_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); + { + if (0 == __size) + return 0; + _CharT* __buf = __a.allocate(_S_rounded_up_size(__size)); + + __uninitialized_copy_n_a(__s, __size, __buf, __a); + _S_cond_store_eos(__buf[__size]); + try + { return _S_new_RopeLeaf(__buf, __size, __a); } + catch(...) + { + _RopeRep::__STL_FREE_STRING(__buf, __size, __a); + __throw_exception_again; + } + } - public: - bool empty() const { return 0 == this->_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(this->_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 = this->_Data_allocate(_S_rounded_up_size(1)); - - std::_Construct(__buf, __c); - try { - this->_M_tree_ptr = _S_new_RopeLeaf(__buf, 1, __a); - } - catch(...) - { - _RopeRep::__STL_FREE_STRING(__buf, 1, __a); - __throw_exception_again; - } - } - - 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) - { - this->_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(this->_M_tree_ptr); - } + // 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_ref_count == 1. +#endif + + private: + + 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[__detail::_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 == this->_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(this->_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 = this->_Data_allocate(_S_rounded_up_size(1)); + + get_allocator().construct(__buf, __c); + try + { this->_M_tree_ptr = _S_new_RopeLeaf(__buf, 1, __a); } + catch(...) + { + _RopeRep::__STL_FREE_STRING(__buf, 1, __a); + __throw_exception_again; + } + } + + 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) + { + this->_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(this->_M_tree_ptr); } ~rope() throw() - { _S_unref(this->_M_tree_ptr); } - - rope& operator=(const rope& __x) - { - _RopeRep* __old = this->_M_tree_ptr; - this->_M_tree_ptr = __x._M_tree_ptr; - _S_ref(this->_M_tree_ptr); - _S_unref(__old); - return *this; - } - - void clear() - { - _S_unref(this->_M_tree_ptr); - this->_M_tree_ptr = 0; - } - - void push_back(_CharT __x) - { - _RopeRep* __old = this->_M_tree_ptr; - this->_M_tree_ptr - = _S_destr_concat_char_iter(this->_M_tree_ptr, &__x, 1); - _S_unref(__old); - } - - void pop_back() - { - _RopeRep* __old = this->_M_tree_ptr; - this->_M_tree_ptr = - _S_substring(this->_M_tree_ptr, - 0, - this->_M_tree_ptr->_M_size - 1); - _S_unref(__old); - } - - _CharT back() const - { - return _S_fetch(this->_M_tree_ptr, this->_M_tree_ptr->_M_size - 1); - } - - void push_front(_CharT __x) - { - _RopeRep* __old = this->_M_tree_ptr; - _RopeRep* __left = - __STL_ROPE_FROM_UNOWNED_CHAR_PTR(&__x, 1, this->get_allocator()); - try { - this->_M_tree_ptr = _S_concat(__left, this->_M_tree_ptr); - _S_unref(__old); - _S_unref(__left); - } - catch(...) - { - _S_unref(__left); - __throw_exception_again; - } - } - - void pop_front() - { - _RopeRep* __old = this->_M_tree_ptr; - this->_M_tree_ptr - = _S_substring(this->_M_tree_ptr, 1, this->_M_tree_ptr->_M_size); - _S_unref(__old); - } - - _CharT front() const - { - return _S_fetch(this->_M_tree_ptr, 0); - } - - void balance() - { - _RopeRep* __old = this->_M_tree_ptr; - this->_M_tree_ptr = _S_balance(this->_M_tree_ptr); - _S_unref(__old); - } - - void copy(_CharT* __buffer) const { - _Destroy(__buffer, __buffer + size()); - _S_flatten(this->_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(this->_M_tree_ptr, __pos, __len, __buffer); - return __len; - } - - // Print to stdout, exposing structure. May be useful for - // performance debugging. - void dump() { - _S_dump(this->_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 == this->_M_tree_ptr) return; - if (_Rope_constants::_S_leaf == this->_M_tree_ptr->_M_tag && - ((_RopeLeaf*)this->_M_tree_ptr)->_M_data == - this->_M_tree_ptr->_M_c_string) { - // Representation shared - return; - } -# ifndef __GC - this->_M_tree_ptr->_M_free_c_string(); -# endif - this->_M_tree_ptr->_M_c_string = 0; - } - - _CharT operator[] (size_type __pos) const { - return _S_fetch(this->_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(this->_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(this->_M_tree_ptr, 0)); - } - - const_iterator end() const { - return(const_iterator(this->_M_tree_ptr, size())); - } - - const_iterator const_end() const { - return(const_iterator(this->_M_tree_ptr, size())); - } - - size_type size() const { - return(0 == this->_M_tree_ptr? 0 : this->_M_tree_ptr->_M_size); - } - - size_type length() const { - return size(); - } - - size_type max_size() const { - return _S_min_len[_Rope_constants::_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. - } - - typedef reverse_iterator<const_iterator> const_reverse_iterator; - - 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()); - } - - template<class _CharT2, class _Alloc2> - friend rope<_CharT2,_Alloc2> - operator+ (const rope<_CharT2,_Alloc2>& __left, - const rope<_CharT2,_Alloc2>& __right); - - template<class _CharT2, class _Alloc2> - friend rope<_CharT2,_Alloc2> - operator+ (const rope<_CharT2,_Alloc2>& __left, - const _CharT2* __right); - - template<class _CharT2, class _Alloc2> - friend rope<_CharT2,_Alloc2> - operator+ (const rope<_CharT2,_Alloc2>& __left, _CharT2 __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(this->_M_tree_ptr, __iter, __n); - _S_unref(this->_M_tree_ptr); - this->_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(this->_M_tree_ptr, __s, __e - __s); - _S_unref(this->_M_tree_ptr); - this->_M_tree_ptr = __result; - return *this; - } - - rope& append(const_iterator __s, const_iterator __e) { - _Self_destruct_ptr __appendee(_S_substring( - __s._M_root, __s._M_current_pos, __e._M_current_pos)); - _RopeRep* __result = - _S_concat(this->_M_tree_ptr, (_RopeRep*)__appendee); - _S_unref(this->_M_tree_ptr); - this->_M_tree_ptr = __result; - return *this; - } - - rope& append(_CharT __c) { - _RopeRep* __result = - _S_destr_concat_char_iter(this->_M_tree_ptr, &__c, 1); - _S_unref(this->_M_tree_ptr); - this->_M_tree_ptr = __result; - return *this; - } - - rope& append() { return append(_CharT()); } // XXX why? - - rope& append(const rope& __y) { - _RopeRep* __result = _S_concat(this->_M_tree_ptr, __y._M_tree_ptr); - _S_unref(this->_M_tree_ptr); - this->_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) { - _RopeRep* __tmp = this->_M_tree_ptr; - this->_M_tree_ptr = __b._M_tree_ptr; - __b._M_tree_ptr = __tmp; - } + { _S_unref(this->_M_tree_ptr); } + + rope& + operator=(const rope& __x) + { + _RopeRep* __old = this->_M_tree_ptr; + this->_M_tree_ptr = __x._M_tree_ptr; + _S_ref(this->_M_tree_ptr); + _S_unref(__old); + return *this; + } + + void + clear() + { + _S_unref(this->_M_tree_ptr); + this->_M_tree_ptr = 0; + } + + void + push_back(_CharT __x) + { + _RopeRep* __old = this->_M_tree_ptr; + this->_M_tree_ptr + = _S_destr_concat_char_iter(this->_M_tree_ptr, &__x, 1); + _S_unref(__old); + } + + void + pop_back() + { + _RopeRep* __old = this->_M_tree_ptr; + this->_M_tree_ptr = _S_substring(this->_M_tree_ptr, + 0, this->_M_tree_ptr->_M_size - 1); + _S_unref(__old); + } + + _CharT + back() const + { return _S_fetch(this->_M_tree_ptr, this->_M_tree_ptr->_M_size - 1); } + + void + push_front(_CharT __x) + { + _RopeRep* __old = this->_M_tree_ptr; + _RopeRep* __left = + __STL_ROPE_FROM_UNOWNED_CHAR_PTR(&__x, 1, this->get_allocator()); + try + { + this->_M_tree_ptr = _S_concat(__left, this->_M_tree_ptr); + _S_unref(__old); + _S_unref(__left); + } + catch(...) + { + _S_unref(__left); + __throw_exception_again; + } + } + + void + pop_front() + { + _RopeRep* __old = this->_M_tree_ptr; + this->_M_tree_ptr + = _S_substring(this->_M_tree_ptr, 1, this->_M_tree_ptr->_M_size); + _S_unref(__old); + } + + _CharT + front() const + { return _S_fetch(this->_M_tree_ptr, 0); } + + void + balance() + { + _RopeRep* __old = this->_M_tree_ptr; + this->_M_tree_ptr = _S_balance(this->_M_tree_ptr); + _S_unref(__old); + } + + void + copy(_CharT* __buffer) const + { + _Destroy(__buffer, __buffer + size(), get_allocator()); + _S_flatten(this->_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, get_allocator()); + _S_flatten(this->_M_tree_ptr, __pos, __len, __buffer); + return __len; + } + + // Print to stdout, exposing structure. May be useful for + // performance debugging. + void + dump() + { _S_dump(this->_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 == this->_M_tree_ptr) + return; + if (__detail::_S_leaf == this->_M_tree_ptr->_M_tag && + ((_RopeLeaf*)this->_M_tree_ptr)->_M_data == + this->_M_tree_ptr->_M_c_string) + { + // Representation shared + return; + } +#ifndef __GC + this->_M_tree_ptr->_M_free_c_string(); +#endif + this->_M_tree_ptr->_M_c_string = 0; + } + + _CharT + operator[] (size_type __pos) const + { return _S_fetch(this->_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(this->_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(this->_M_tree_ptr, 0)); } + + const_iterator + end() const + { return(const_iterator(this->_M_tree_ptr, size())); } + + const_iterator + const_end() const + { return(const_iterator(this->_M_tree_ptr, size())); } + + size_type + size() const + { return(0 == this->_M_tree_ptr? 0 : this->_M_tree_ptr->_M_size); } + + size_type + length() const + { return size(); } + + size_type + max_size() const + { + return _S_min_len[int(__detail::_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. + } + + typedef reverse_iterator<const_iterator> const_reverse_iterator; + + 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()); } + + template<class _CharT2, class _Alloc2> + friend rope<_CharT2, _Alloc2> + operator+(const rope<_CharT2, _Alloc2>& __left, + const rope<_CharT2, _Alloc2>& __right); + + template<class _CharT2, class _Alloc2> + friend rope<_CharT2, _Alloc2> + operator+(const rope<_CharT2, _Alloc2>& __left, const _CharT2* __right); + + template<class _CharT2, class _Alloc2> + friend rope<_CharT2, _Alloc2> + operator+(const rope<_CharT2, _Alloc2>& __left, _CharT2 __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(this->_M_tree_ptr, __iter, __n); + _S_unref(this->_M_tree_ptr); + this->_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(this->_M_tree_ptr, __s, __e - __s); + _S_unref(this->_M_tree_ptr); + this->_M_tree_ptr = __result; + return *this; + } + + rope& + append(const_iterator __s, const_iterator __e) + { + _Self_destruct_ptr __appendee(_S_substring(__s._M_root, + __s._M_current_pos, + __e._M_current_pos)); + _RopeRep* __result = _S_concat(this->_M_tree_ptr, + (_RopeRep*)__appendee); + _S_unref(this->_M_tree_ptr); + this->_M_tree_ptr = __result; + return *this; + } + + rope& + append(_CharT __c) + { + _RopeRep* __result = + _S_destr_concat_char_iter(this->_M_tree_ptr, &__c, 1); + _S_unref(this->_M_tree_ptr); + this->_M_tree_ptr = __result; + return *this; + } + + rope& + append() + { return append(_CharT()); } // XXX why? + + rope& + append(const rope& __y) + { + _RopeRep* __result = _S_concat(this->_M_tree_ptr, __y._M_tree_ptr); + _S_unref(this->_M_tree_ptr); + this->_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) + { + _RopeRep* __tmp = this->_M_tree_ptr; + this->_M_tree_ptr = __b._M_tree_ptr; + __b._M_tree_ptr = __tmp; + } protected: - // 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; - - 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; - } + // 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; + + 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) { - _RopeRep* __result = - replace(this->_M_tree_ptr, __p, __p, __r._M_tree_ptr); - _S_unref(this->_M_tree_ptr); - this->_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(this->_M_tree_ptr, 0, __p)); - _Self_destruct_ptr __right(_S_substring(this->_M_tree_ptr, - __p, size())); - _Self_destruct_ptr __left_result( - _S_concat_char_iter(__left, __i, __n)); - // _S_ destr_concat_char_iter should be safe here. - // But as it stands it's probably not a win, since __left - // is likely to have additional references. - _RopeRep* __result = _S_concat(__left_result, __right); - _S_unref(this->_M_tree_ptr); - this->_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(this->_M_tree_ptr, __p, __p + __n, __r._M_tree_ptr); - _S_unref(this->_M_tree_ptr); - this->_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(this->_M_tree_ptr, __p, __p + __n, 0); - _S_unref(this->_M_tree_ptr); - this->_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(this->_M_tree_ptr, - __start, - __start + __len)); - } - - rope substr(iterator __start, iterator __end) const { - return rope<_CharT,_Alloc>( - _S_substring(this->_M_tree_ptr, - __start.index(), - __end.index())); - } - - rope substr(iterator __start) const { - size_t __pos = __start.index(); - return rope<_CharT,_Alloc>( - _S_substring(this->_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(this->_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(this->_M_tree_ptr, __pos, __pos + 1)); - } - - static const size_type npos; - - size_type find(_CharT __c, size_type __pos = 0) const; - size_type find(const _CharT* __s, size_type __pos = 0) const { - size_type __result_pos; - const_iterator __result = - std::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())); - } - - typedef reverse_iterator<iterator> reverse_iterator; - - reverse_iterator mutable_rbegin() { - return reverse_iterator(mutable_end()); - } - - reverse_iterator mutable_rend() { - return reverse_iterator(mutable_begin()); - } - - reference mutable_reference_at(size_type __pos) { - return reference(this, __pos); - } - -# ifdef __STD_STUFF - reference operator[] (size_type __pos) { - return _char_ref_proxy(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(); - } - - // Stuff below this line is dangerous because it's error prone. - // I would really like to get rid of it. - // copy function with funny arg ordering. - size_type copy(_CharT* __buffer, size_type __n, - size_type __pos = 0) const { - return copy(__pos, __n, __buffer); - } - - iterator end() { return mutable_end(); } - - iterator begin() { return mutable_begin(); } - - reverse_iterator rend() { return mutable_rend(); } - - reverse_iterator rbegin() { return mutable_rbegin(); } - -# else - - const_iterator end() { return const_end(); } - - const_iterator begin() { return const_begin(); } - - const_reverse_iterator rend() { return const_rend(); } - - const_reverse_iterator rbegin() { return const_rbegin(); } - -# endif - -}; - -template <class _CharT, class _Alloc> -const typename rope<_CharT, _Alloc>::size_type rope<_CharT, _Alloc>::npos = - (size_type)(-1); - -template <class _CharT, class _Alloc> -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 <class _CharT, class _Alloc> -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 <class _CharT, class _Alloc> -inline bool operator!= (const _Rope_const_iterator<_CharT,_Alloc>& __x, - const _Rope_const_iterator<_CharT,_Alloc>& __y) { - return !(__x == __y); -} - -template <class _CharT, class _Alloc> -inline bool operator> (const _Rope_const_iterator<_CharT,_Alloc>& __x, - const _Rope_const_iterator<_CharT,_Alloc>& __y) { - return __y < __x; -} - -template <class _CharT, class _Alloc> -inline bool operator<= (const _Rope_const_iterator<_CharT,_Alloc>& __x, - const _Rope_const_iterator<_CharT,_Alloc>& __y) { - return !(__y < __x); -} - -template <class _CharT, class _Alloc> -inline bool operator>= (const _Rope_const_iterator<_CharT,_Alloc>& __x, - const _Rope_const_iterator<_CharT,_Alloc>& __y) { - return !(__x < __y); -} - -template <class _CharT, class _Alloc> -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 <class _CharT, class _Alloc> -inline _Rope_const_iterator<_CharT,_Alloc> -operator-(const _Rope_const_iterator<_CharT,_Alloc>& __x, ptrdiff_t __n) { - return _Rope_const_iterator<_CharT,_Alloc>( - __x._M_root, __x._M_current_pos - __n); -} - -template <class _CharT, class _Alloc> -inline _Rope_const_iterator<_CharT,_Alloc> -operator+(const _Rope_const_iterator<_CharT,_Alloc>& __x, ptrdiff_t __n) { - return _Rope_const_iterator<_CharT,_Alloc>( - __x._M_root, __x._M_current_pos + __n); -} - -template <class _CharT, class _Alloc> -inline _Rope_const_iterator<_CharT,_Alloc> -operator+(ptrdiff_t __n, const _Rope_const_iterator<_CharT,_Alloc>& __x) { - return _Rope_const_iterator<_CharT,_Alloc>( - __x._M_root, __x._M_current_pos + __n); -} - -template <class _CharT, class _Alloc> -inline bool operator== (const _Rope_iterator<_CharT,_Alloc>& __x, - const _Rope_iterator<_CharT,_Alloc>& __y) { - return (__x._M_current_pos == __y._M_current_pos && - __x._M_root_rope == __y._M_root_rope); -} - -template <class _CharT, class _Alloc> -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 <class _CharT, class _Alloc> -inline bool operator!= (const _Rope_iterator<_CharT,_Alloc>& __x, - const _Rope_iterator<_CharT,_Alloc>& __y) { - return !(__x == __y); -} - -template <class _CharT, class _Alloc> -inline bool operator> (const _Rope_iterator<_CharT,_Alloc>& __x, - const _Rope_iterator<_CharT,_Alloc>& __y) { - return __y < __x; -} - -template <class _CharT, class _Alloc> -inline bool operator<= (const _Rope_iterator<_CharT,_Alloc>& __x, - const _Rope_iterator<_CharT,_Alloc>& __y) { - return !(__y < __x); -} - -template <class _CharT, class _Alloc> -inline bool operator>= (const _Rope_iterator<_CharT,_Alloc>& __x, - const _Rope_iterator<_CharT,_Alloc>& __y) { - return !(__x < __y); -} - -template <class _CharT, class _Alloc> -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 <class _CharT, class _Alloc> -inline _Rope_iterator<_CharT,_Alloc> -operator-(const _Rope_iterator<_CharT,_Alloc>& __x, - ptrdiff_t __n) { - return _Rope_iterator<_CharT,_Alloc>( - __x._M_root_rope, __x._M_current_pos - __n); -} - -template <class _CharT, class _Alloc> -inline _Rope_iterator<_CharT,_Alloc> -operator+(const _Rope_iterator<_CharT,_Alloc>& __x, - ptrdiff_t __n) { - return _Rope_iterator<_CharT,_Alloc>( - __x._M_root_rope, __x._M_current_pos + __n); -} - -template <class _CharT, class _Alloc> -inline _Rope_iterator<_CharT,_Alloc> -operator+(ptrdiff_t __n, const _Rope_iterator<_CharT,_Alloc>& __x) { - return _Rope_iterator<_CharT,_Alloc>( - __x._M_root_rope, __x._M_current_pos + __n); -} - -template <class _CharT, class _Alloc> -inline -rope<_CharT,_Alloc> -operator+ (const rope<_CharT,_Alloc>& __left, - const rope<_CharT,_Alloc>& __right) -{ - return rope<_CharT,_Alloc>( - rope<_CharT,_Alloc>::_S_concat(__left._M_tree_ptr, __right._M_tree_ptr)); - // Inlining this should make it possible to keep __left and - // __right in registers. -} - -template <class _CharT, class _Alloc> -inline -rope<_CharT,_Alloc>& -operator+= (rope<_CharT,_Alloc>& __left, - const rope<_CharT,_Alloc>& __right) -{ - __left.append(__right); - return __left; -} - -template <class _CharT, class _Alloc> -inline -rope<_CharT,_Alloc> -operator+ (const rope<_CharT,_Alloc>& __left, - const _CharT* __right) { - size_t __rlen = rope<_CharT,_Alloc>::_S_char_ptr_len(__right); - return rope<_CharT,_Alloc>( - rope<_CharT,_Alloc>::_S_concat_char_iter( - __left._M_tree_ptr, __right, __rlen)); -} - -template <class _CharT, class _Alloc> -inline -rope<_CharT,_Alloc>& -operator+= (rope<_CharT,_Alloc>& __left, - const _CharT* __right) { - __left.append(__right); - return __left; -} - -template <class _CharT, class _Alloc> -inline -rope<_CharT,_Alloc> -operator+ (const rope<_CharT,_Alloc>& __left, _CharT __right) { - return rope<_CharT,_Alloc>( - rope<_CharT,_Alloc>::_S_concat_char_iter( - __left._M_tree_ptr, &__right, 1)); -} - -template <class _CharT, class _Alloc> -inline -rope<_CharT,_Alloc>& -operator+= (rope<_CharT,_Alloc>& __left, _CharT __right) { - __left.append(__right); - return __left; -} - -template <class _CharT, class _Alloc> -bool -operator< (const rope<_CharT,_Alloc>& __left, - const rope<_CharT,_Alloc>& __right) { - return __left.compare(__right) < 0; -} - -template <class _CharT, class _Alloc> -bool -operator== (const rope<_CharT,_Alloc>& __left, - const rope<_CharT,_Alloc>& __right) { - return __left.compare(__right) == 0; -} - -template <class _CharT, class _Alloc> -inline bool operator== (const _Rope_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 <class _CharT, class _Alloc> -inline bool -operator!= (const rope<_CharT,_Alloc>& __x, const rope<_CharT,_Alloc>& __y) { - return !(__x == __y); -} - -template <class _CharT, class _Alloc> -inline bool -operator> (const rope<_CharT,_Alloc>& __x, const rope<_CharT,_Alloc>& __y) { - return __y < __x; -} - -template <class _CharT, class _Alloc> -inline bool -operator<= (const rope<_CharT,_Alloc>& __x, const rope<_CharT,_Alloc>& __y) { - return !(__y < __x); -} - -template <class _CharT, class _Alloc> -inline bool -operator>= (const rope<_CharT,_Alloc>& __x, const rope<_CharT,_Alloc>& __y) { - return !(__x < __y); -} - -template <class _CharT, class _Alloc> -inline bool operator!= (const _Rope_char_ptr_proxy<_CharT,_Alloc>& __x, - const _Rope_char_ptr_proxy<_CharT,_Alloc>& __y) { - return !(__x == __y); -} - -template<class _CharT, class _Traits, class _Alloc> -std::basic_ostream<_CharT, _Traits>& operator<< - (std::basic_ostream<_CharT, _Traits>& __o, - const rope<_CharT, _Alloc>& __r); - -typedef rope<char> crope; -typedef rope<wchar_t> wrope; - -inline crope::reference __mutable_reference_at(crope& __c, size_t __i) -{ - return __c.mutable_reference_at(__i); -} - -inline wrope::reference __mutable_reference_at(wrope& __c, size_t __i) -{ - return __c.mutable_reference_at(__i); -} - -template <class _CharT, class _Alloc> -inline void swap(rope<_CharT,_Alloc>& __x, rope<_CharT,_Alloc>& __y) { - __x.swap(__y); -} - -// Hash functions should probably be revisited later: -template<> struct hash<crope> -{ - size_t operator()(const crope& __str) const - { - size_t __size = __str.size(); + void + insert(size_t __p, const rope& __r) + { + _RopeRep* __result = + replace(this->_M_tree_ptr, __p, __p, __r._M_tree_ptr); + _S_unref(this->_M_tree_ptr); + this->_M_tree_ptr = __result; + } - if (0 == __size) return 0; - return 13*__str[0] + 5*__str[__size - 1] + __size; - } -}; + 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(this->_M_tree_ptr, 0, __p)); + _Self_destruct_ptr __right(_S_substring(this->_M_tree_ptr, + __p, size())); + _Self_destruct_ptr __left_result(_S_concat_char_iter(__left, __i, __n)); + // _S_ destr_concat_char_iter should be safe here. + // But as it stands it's probably not a win, since __left + // is likely to have additional references. + _RopeRep* __result = _S_concat(__left_result, __right); + _S_unref(this->_M_tree_ptr); + this->_M_tree_ptr = __result; + } + void + insert(size_t __p, const _CharT* __c_string) + { insert(__p, __c_string, _S_char_ptr_len(__c_string)); } -template<> struct hash<wrope> -{ - size_t operator()(const wrope& __str) const - { - size_t __size = __str.size(); + void + insert(size_t __p, _CharT __c) + { insert(__p, &__c, 1); } + + void + insert(size_t __p) + { + _CharT __c = _CharT(); + insert(__p, &__c, 1); + } - if (0 == __size) return 0; - return 13*__str[0] + 5*__str[__size - 1] + __size; - } -}; + 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(this->_M_tree_ptr, __p, __p + __n, __r._M_tree_ptr); + _S_unref(this->_M_tree_ptr); + this->_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(this->_M_tree_ptr, __p, + __p + __n, 0); + _S_unref(this->_M_tree_ptr); + this->_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(this->_M_tree_ptr, + __start, + __start + __len)); + } + + rope + substr(iterator __start, iterator __end) const + { + return rope<_CharT, _Alloc>(_S_substring(this->_M_tree_ptr, + __start.index(), + __end.index())); + } + + rope + substr(iterator __start) const + { + size_t __pos = __start.index(); + return rope<_CharT, _Alloc>(_S_substring(this->_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(this->_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(this->_M_tree_ptr, + __pos, __pos + 1)); + } + + static const size_type npos; + + size_type find(_CharT __c, size_type __pos = 0) const; + + size_type + find(const _CharT* __s, size_type __pos = 0) const + { + size_type __result_pos; + const_iterator __result = + std::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())); } + + typedef reverse_iterator<iterator> reverse_iterator; + + reverse_iterator + mutable_rbegin() + { return reverse_iterator(mutable_end()); } + + reverse_iterator + mutable_rend() + { return reverse_iterator(mutable_begin()); } + + reference + mutable_reference_at(size_type __pos) + { return reference(this, __pos); } + +#ifdef __STD_STUFF + reference + operator[] (size_type __pos) + { return _char_ref_proxy(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(); } + + // Stuff below this line is dangerous because it's error prone. + // I would really like to get rid of it. + // copy function with funny arg ordering. + size_type + copy(_CharT* __buffer, size_type __n, + size_type __pos = 0) const + { return copy(__pos, __n, __buffer); } + + iterator + end() + { return mutable_end(); } + + iterator + begin() + { return mutable_begin(); } + + reverse_iterator + rend() + { return mutable_rend(); } + + reverse_iterator + rbegin() + { return mutable_rbegin(); } + +#else + const_iterator + end() + { return const_end(); } + + const_iterator + begin() + { return const_begin(); } + + const_reverse_iterator + rend() + { return const_rend(); } + + const_reverse_iterator + rbegin() + { return const_rbegin(); } + +#endif + }; + + template <class _CharT, class _Alloc> + const typename rope<_CharT, _Alloc>::size_type + rope<_CharT, _Alloc>::npos = (size_type)(-1); + + template <class _CharT, class _Alloc> + 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 <class _CharT, class _Alloc> + 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 <class _CharT, class _Alloc> + inline bool operator!=(const _Rope_const_iterator<_CharT, _Alloc>& __x, + const _Rope_const_iterator<_CharT, _Alloc>& __y) + { return !(__x == __y); } + + template <class _CharT, class _Alloc> + inline bool operator>(const _Rope_const_iterator<_CharT, _Alloc>& __x, + const _Rope_const_iterator<_CharT, _Alloc>& __y) + { return __y < __x; } + + template <class _CharT, class _Alloc> + inline bool + operator<=(const _Rope_const_iterator<_CharT, _Alloc>& __x, + const _Rope_const_iterator<_CharT, _Alloc>& __y) + { return !(__y < __x); } + + template <class _CharT, class _Alloc> + inline bool + operator>=(const _Rope_const_iterator<_CharT, _Alloc>& __x, + const _Rope_const_iterator<_CharT, _Alloc>& __y) + { return !(__x < __y); } + + template <class _CharT, class _Alloc> + 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 <class _CharT, class _Alloc> + inline _Rope_const_iterator<_CharT, _Alloc> + operator-(const _Rope_const_iterator<_CharT, _Alloc>& __x, ptrdiff_t __n) + { return _Rope_const_iterator<_CharT, _Alloc>(__x._M_root, + __x._M_current_pos - __n); } + + template <class _CharT, class _Alloc> + inline _Rope_const_iterator<_CharT, _Alloc> + operator+(const _Rope_const_iterator<_CharT, _Alloc>& __x, ptrdiff_t __n) + { return _Rope_const_iterator<_CharT, _Alloc>(__x._M_root, + __x._M_current_pos + __n); } + + template <class _CharT, class _Alloc> + inline _Rope_const_iterator<_CharT, _Alloc> + operator+(ptrdiff_t __n, const _Rope_const_iterator<_CharT, _Alloc>& __x) + { return _Rope_const_iterator<_CharT, _Alloc>(__x._M_root, + __x._M_current_pos + __n); } + + template <class _CharT, class _Alloc> + inline bool + operator==(const _Rope_iterator<_CharT, _Alloc>& __x, + const _Rope_iterator<_CharT, _Alloc>& __y) + {return (__x._M_current_pos == __y._M_current_pos + && __x._M_root_rope == __y._M_root_rope); } + + template <class _CharT, class _Alloc> + 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 <class _CharT, class _Alloc> + inline bool + operator!=(const _Rope_iterator<_CharT, _Alloc>& __x, + const _Rope_iterator<_CharT, _Alloc>& __y) + { return !(__x == __y); } + + template <class _CharT, class _Alloc> + inline bool + operator>(const _Rope_iterator<_CharT, _Alloc>& __x, + const _Rope_iterator<_CharT, _Alloc>& __y) + { return __y < __x; } + + template <class _CharT, class _Alloc> + inline bool + operator<=(const _Rope_iterator<_CharT, _Alloc>& __x, + const _Rope_iterator<_CharT, _Alloc>& __y) + { return !(__y < __x); } + + template <class _CharT, class _Alloc> + inline bool + operator>=(const _Rope_iterator<_CharT, _Alloc>& __x, + const _Rope_iterator<_CharT, _Alloc>& __y) + { return !(__x < __y); } + + template <class _CharT, class _Alloc> + 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 <class _CharT, class _Alloc> + inline _Rope_iterator<_CharT, _Alloc> + operator-(const _Rope_iterator<_CharT, _Alloc>& __x, + ptrdiff_t __n) + { return _Rope_iterator<_CharT, _Alloc>(__x._M_root_rope, + __x._M_current_pos - __n); } + + template <class _CharT, class _Alloc> + inline _Rope_iterator<_CharT, _Alloc> + operator+(const _Rope_iterator<_CharT, _Alloc>& __x, ptrdiff_t __n) + { return _Rope_iterator<_CharT, _Alloc>(__x._M_root_rope, + __x._M_current_pos + __n); } + + template <class _CharT, class _Alloc> + inline _Rope_iterator<_CharT, _Alloc> + operator+(ptrdiff_t __n, const _Rope_iterator<_CharT, _Alloc>& __x) + { return _Rope_iterator<_CharT, _Alloc>(__x._M_root_rope, + __x._M_current_pos + __n); } + + template <class _CharT, class _Alloc> + inline rope<_CharT, _Alloc> + operator+(const rope<_CharT, _Alloc>& __left, + const rope<_CharT, _Alloc>& __right) + { + // Inlining this should make it possible to keep __left and + // __right in registers. + typedef rope<_CharT, _Alloc> rope_type; + return rope_type(rope_type::_S_concat(__left._M_tree_ptr, + __right._M_tree_ptr)); + } + + template <class _CharT, class _Alloc> + inline rope<_CharT, _Alloc>& + operator+=(rope<_CharT, _Alloc>& __left, + const rope<_CharT, _Alloc>& __right) + { + __left.append(__right); + return __left; + } + + template <class _CharT, class _Alloc> + inline rope<_CharT, _Alloc> + operator+(const rope<_CharT, _Alloc>& __left, + const _CharT* __right) + { + typedef rope<_CharT, _Alloc> rope_type; + size_t __rlen = rope_type::_S_char_ptr_len(__right); + return rope_type(rope_type::_S_concat_char_iter(__left._M_tree_ptr, + __right, __rlen)); + } + + template <class _CharT, class _Alloc> + inline rope<_CharT, _Alloc>& + operator+=(rope<_CharT, _Alloc>& __left, + const _CharT* __right) + { + __left.append(__right); + return __left; + } + + template <class _CharT, class _Alloc> + inline rope<_CharT, _Alloc> + operator+(const rope<_CharT, _Alloc>& __left, _CharT __right) + { + typedef rope<_CharT, _Alloc> rope_type; + return rope_type(rope_type::_S_concat_char_iter(__left._M_tree_ptr, + &__right, 1)); + } + + template <class _CharT, class _Alloc> + inline rope<_CharT, _Alloc>& + operator+=(rope<_CharT, _Alloc>& __left, _CharT __right) + { + __left.append(__right); + return __left; + } + + template <class _CharT, class _Alloc> + bool + operator<(const rope<_CharT, _Alloc>& __left, + const rope<_CharT, _Alloc>& __right) + { return __left.compare(__right) < 0; } + + template <class _CharT, class _Alloc> + bool + operator==(const rope<_CharT, _Alloc>& __left, + const rope<_CharT, _Alloc>& __right) + { return __left.compare(__right) == 0; } + + template <class _CharT, class _Alloc> + inline bool + operator==(const _Rope_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 <class _CharT, class _Alloc> + inline bool + operator!=(const rope<_CharT, _Alloc>& __x, + const rope<_CharT, _Alloc>& __y) + { return !(__x == __y); } + + template <class _CharT, class _Alloc> + inline bool + operator>(const rope<_CharT, _Alloc>& __x, + const rope<_CharT, _Alloc>& __y) + { return __y < __x; } + + template <class _CharT, class _Alloc> + inline bool + operator<=(const rope<_CharT, _Alloc>& __x, + const rope<_CharT, _Alloc>& __y) + { return !(__y < __x); } + + template <class _CharT, class _Alloc> + inline bool + operator>=(const rope<_CharT, _Alloc>& __x, + const rope<_CharT, _Alloc>& __y) + { return !(__x < __y); } + + template <class _CharT, class _Alloc> + inline bool + operator!=(const _Rope_char_ptr_proxy<_CharT, _Alloc>& __x, + const _Rope_char_ptr_proxy<_CharT, _Alloc>& __y) + { return !(__x == __y); } + + template<class _CharT, class _Traits, class _Alloc> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __o, + const rope<_CharT, _Alloc>& __r); + + typedef rope<char> crope; + typedef rope<wchar_t> wrope; + + inline crope::reference + __mutable_reference_at(crope& __c, size_t __i) + { return __c.mutable_reference_at(__i); } + + inline wrope::reference + __mutable_reference_at(wrope& __c, size_t __i) + { return __c.mutable_reference_at(__i); } + + template <class _CharT, class _Alloc> + inline void + swap(rope<_CharT, _Alloc>& __x, rope<_CharT, _Alloc>& __y) + { __x.swap(__y); } + + // Hash functions should probably be revisited later: + template<> + struct hash<crope> + { + size_t + operator()(const crope& __str) const + { + size_t __size = __str.size(); + if (0 == __size) + return 0; + return 13 * __str[0] + 5 * __str[__size - 1] + __size; + } + }; + + + template<> + struct hash<wrope> + { + size_t + operator()(const wrope& __str) const + { + size_t __size = __str.size(); + if (0 == __size) + return 0; + return 13 * __str[0] + 5 * __str[__size - 1] + __size; + } + }; -} // namespace __gnu_cxx +_GLIBCXX_END_NAMESPACE # include <ext/ropeimpl.h> diff --git a/contrib/libstdc++/include/ext/ropeimpl.h b/contrib/libstdc++/include/ext/ropeimpl.h index 29dc550a037c..bbe6b9970bfa 100644 --- a/contrib/libstdc++/include/ext/ropeimpl.h +++ b/contrib/libstdc++/include/ext/ropeimpl.h @@ -1,6 +1,7 @@ // SGI's rope class implementation -*- C++ -*- -// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 +// Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -15,7 +16,7 @@ // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, // USA. // As a special exception, you may use this file as part of a free software @@ -53,8 +54,8 @@ #include <ext/memory> // For uninitialized_copy_n #include <ext/numeric> // For power -namespace __gnu_cxx -{ +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + using std::size_t; using std::printf; using std::basic_ostream; @@ -62,1478 +63,1640 @@ namespace __gnu_cxx using std::_Destroy; using std::uninitialized_fill_n; -// Set buf_start, buf_end, and buf_ptr appropriately, filling tmp_buf -// 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 <class _CharT, class _Alloc> -void _Rope_iterator_base<_CharT,_Alloc>::_S_setbuf( - _Rope_iterator_base<_CharT,_Alloc>& __x) -{ - 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 _Rope_constants::_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 _Rope_constants::_S_function: - case _Rope_constants::_S_substringfn: - { - 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; - } - (*__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; + // Set buf_start, buf_end, and buf_ptr appropriately, filling tmp_buf + // 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 <class _CharT, class _Alloc> + void + _Rope_iterator_base<_CharT, _Alloc>:: + _S_setbuf(_Rope_iterator_base<_CharT, _Alloc>& __x) + { + 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 __detail::_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 __detail::_S_function: + case __detail::_S_substringfn: + { + 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; + (*__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: break; + } } -} - -// Set path and buffer inside a rope iterator. We assume that -// pos and root are already set. -template <class _CharT, class _Alloc> -void _Rope_iterator_base<_CharT,_Alloc>::_S_setcache -(_Rope_iterator_base<_CharT,_Alloc>& __x) -{ - const _RopeRep* __path[_Rope_constants::_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 - - if (__pos >= __x._M_root->_M_size) { - __x._M_buf_ptr = 0; - return; - } - __curr_rope = __x._M_root; - if (0 != __curr_rope->_M_c_string) { - /* Treat the root as a leaf. */ - __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; - __path[__curr_depth] = __curr_rope; - switch(__curr_rope->_M_tag) { - case _Rope_constants::_S_leaf: - case _Rope_constants::_S_function: - case _Rope_constants::_S_substringfn: - __x._M_leaf_pos = __curr_start_pos; - goto done; - case _Rope_constants::_S_concat: + + // Set path and buffer inside a rope iterator. We assume that + // pos and root are already set. + template <class _CharT, class _Alloc> + void + _Rope_iterator_base<_CharT, _Alloc>:: + _S_setcache(_Rope_iterator_base<_CharT, _Alloc>& __x) + { + const _RopeRep* __path[int(__detail::_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 + + if (__pos >= __x._M_root->_M_size) + { + __x._M_buf_ptr = 0; + return; + } + __curr_rope = __x._M_root; + if (0 != __curr_rope->_M_c_string) + { + /* Treat the root as a leaf. */ + __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; + __path[__curr_depth] = __curr_rope; + switch(__curr_rope->_M_tag) { - _Rope_RopeConcatenation<_CharT,_Alloc>* __c = - (_Rope_RopeConcatenation<_CharT,_Alloc>*)__curr_rope; + case __detail::_S_leaf: + case __detail::_S_function: + case __detail::_S_substringfn: + __x._M_leaf_pos = __curr_start_pos; + goto done; + case __detail::_S_concat: + { + _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) { + if (__pos >= __curr_start_pos + __left_len) + { __dirns |= 1; __curr_rope = __c->_M_right; __curr_start_pos += __left_len; - } else { - __curr_rope = __left; - } + } + else + __curr_rope = __left; + } + break; } - break; } - } - done: - // Copy last section of path into _M_path_end. + done: + // Copy last section of path into _M_path_end. { int __i = -1; - int __j = __curr_depth + 1 - _S_path_cache_len; + int __j = __curr_depth + 1 - int(_S_path_cache_len); if (__j < 0) __j = 0; - while (__j <= __curr_depth) { - __x._M_path_end[++__i] = __path[__j++]; - } + while (__j <= __curr_depth) + __x._M_path_end[++__i] = __path[__j++]; __x._M_leaf_index = __i; } __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 <class _CharT, class _Alloc> -void _Rope_iterator_base<_CharT,_Alloc>::_S_setcache_for_incr -(_Rope_iterator_base<_CharT,_Alloc>& __x) -{ - 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; - - if (__x._M_current_pos - __node_start_pos < __len) { - /* More stuff in this leaf, we just didn't cache it. */ - _S_setbuf(__x); - return; - } - // node_start_pos is starting position of last_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->_M_left->_M_size; - __dirns >>= 1; - } - if (__current_index < 0) { - // We underflowed the cache. Punt. - _S_setcache(__x); - return; } - __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->_M_left->_M_size; - __current_node = __c->_M_right; - __x._M_path_end[++__current_index] = __current_node; - __dirns |= 1; - while (_Rope_constants::_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++) { + + // Specialized version of the above. Assumes that + // the path cache is valid for the previous position. + template <class _CharT, class _Alloc> + void + _Rope_iterator_base<_CharT, _Alloc>:: + _S_setcache_for_incr(_Rope_iterator_base<_CharT, _Alloc>& __x) + { + 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; + + if (__x._M_current_pos - __node_start_pos < __len) + { + /* More stuff in this leaf, we just didn't cache it. */ + _S_setbuf(__x); + return; + } + // node_start_pos is starting position of last_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->_M_left->_M_size; + __dirns >>= 1; + } + if (__current_index < 0) + { + // We underflowed the cache. Punt. + _S_setcache(__x); + return; + } + __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->_M_left->_M_size; + __current_node = __c->_M_right; + __x._M_path_end[++__current_index] = __current_node; + __dirns |= 1; + while (__detail::_S_concat == __current_node->_M_tag) + { + ++__current_index; + if (int(_S_path_cache_len) == __current_index) + { + int __i; + for (__i = 0; __i < int(_S_path_cache_len) - 1; __i++) __x._M_path_end[__i] = __x._M_path_end[__i+1]; + --__current_index; + } + __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._M_leaf_index = __current_index; + __x._M_leaf_pos = __node_start_pos; + __x._M_path_directions = __dirns; + _S_setbuf(__x); + } + + template <class _CharT, class _Alloc> + 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); } - --__current_index; + else + _M_buf_ptr = 0; } - __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._M_leaf_index = __current_index; - __x._M_leaf_pos = __node_start_pos; - __x._M_path_directions = __dirns; - _S_setbuf(__x); -} - -template <class _CharT, class _Alloc> -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 { - _M_buf_ptr = 0; - } + + template <class _CharT, class _Alloc> + 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 + _M_buf_ptr = 0; + } + _M_current_pos -= __n; } -} - -template <class _CharT, class _Alloc> -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 { - _M_buf_ptr = 0; - } + + template <class _CharT, class _Alloc> + void + _Rope_iterator<_CharT, _Alloc>:: + _M_check() + { + if (_M_root_rope->_M_tree_ptr != this->_M_root) + { + // _Rope was modified. Get things fixed up. + _RopeRep::_S_unref(this->_M_root); + this->_M_root = _M_root_rope->_M_tree_ptr; + _RopeRep::_S_ref(this->_M_root); + this->_M_buf_ptr = 0; + } } - _M_current_pos -= __n; -} - -template <class _CharT, class _Alloc> -void _Rope_iterator<_CharT,_Alloc>::_M_check() { - if (_M_root_rope->_M_tree_ptr != this->_M_root) { - // _Rope was modified. Get things fixed up. - _RopeRep::_S_unref(this->_M_root); - this->_M_root = _M_root_rope->_M_tree_ptr; - _RopeRep::_S_ref(this->_M_root); - this->_M_buf_ptr = 0; + + template <class _CharT, class _Alloc> + inline + _Rope_const_iterator<_CharT, _Alloc>:: + _Rope_const_iterator(const _Rope_iterator<_CharT, _Alloc>& __x) + : _Rope_iterator_base<_CharT, _Alloc>(__x) + { } + + template <class _CharT, class _Alloc> + 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) + { _RopeRep::_S_ref(this->_M_root); } + + template <class _CharT, class _Alloc> + inline size_t + rope<_CharT, _Alloc>:: + _S_char_ptr_len(const _CharT* __s) + { + const _CharT* __p = __s; + + while (!_S_is0(*__p)) + ++__p; + return (__p - __s); } -} - -template <class _CharT, class _Alloc> -inline -_Rope_const_iterator<_CharT, _Alloc>::_Rope_const_iterator( - const _Rope_iterator<_CharT,_Alloc>& __x) -: _Rope_iterator_base<_CharT,_Alloc>(__x) -{ } - -template <class _CharT, class _Alloc> -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) -{ - _RopeRep::_S_ref(this->_M_root); -} - -template <class _CharT, class _Alloc> -inline size_t -rope<_CharT,_Alloc>::_S_char_ptr_len(const _CharT* __s) -{ - const _CharT* __p = __s; - - while (!_S_is0(*__p)) { ++__p; } - return (__p - __s); -} #ifndef __GC -template <class _CharT, class _Alloc> -inline void _Rope_RopeRep<_CharT,_Alloc>::_M_free_c_string() -{ - _CharT* __cstr = _M_c_string; - if (0 != __cstr) { - size_t __size = this->_M_size + 1; - _Destroy(__cstr, __cstr + __size); - this->_Data_deallocate(__cstr, __size); + template <class _CharT, class _Alloc> + inline void + _Rope_RopeRep<_CharT, _Alloc>:: + _M_free_c_string() + { + _CharT* __cstr = _M_c_string; + if (0 != __cstr) + { + size_t __size = this->_M_size + 1; + _Destroy(__cstr, __cstr + __size, get_allocator()); + this->_Data_deallocate(__cstr, __size); + } } -} - -template <class _CharT, class _Alloc> - inline void _Rope_RopeRep<_CharT,_Alloc>::_S_free_string(_CharT* __s, - size_t __n, - allocator_type __a) -{ - if (!_S_is_basic_char_type((_CharT*)0)) { - _Destroy(__s, __s + __n); + template <class _CharT, class _Alloc> + inline void + _Rope_RopeRep<_CharT, _Alloc>:: + _S_free_string(_CharT* __s, size_t __n, allocator_type __a) + { + if (!_S_is_basic_char_type((_CharT*)0)) + _Destroy(__s, __s + __n, __a); + + // This has to be a static member, so this gets a bit messy + __a.deallocate(__s, + _Rope_RopeLeaf<_CharT, _Alloc>::_S_rounded_up_size(__n)); } -// This has to be a static member, so this gets a bit messy - __a.deallocate( - __s, _Rope_RopeLeaf<_CharT,_Alloc>::_S_rounded_up_size(__n)); -} - - -// 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 <class _CharT, class _Alloc> -void _Rope_RopeRep<_CharT,_Alloc>::_M_free_tree() -{ - switch(_M_tag) { - case _Rope_constants::_S_leaf: - { - _Rope_RopeLeaf<_CharT,_Alloc>* __l - = (_Rope_RopeLeaf<_CharT,_Alloc>*)this; - __l->_Rope_RopeLeaf<_CharT,_Alloc>::~_Rope_RopeLeaf(); - _L_deallocate(__l, 1); - break; - } - case _Rope_constants::_S_concat: - { - _Rope_RopeConcatenation<_CharT,_Alloc>* __c - = (_Rope_RopeConcatenation<_CharT,_Alloc>*)this; - __c->_Rope_RopeConcatenation<_CharT,_Alloc>:: - ~_Rope_RopeConcatenation(); - _C_deallocate(__c, 1); - break; - } - case _Rope_constants::_S_function: - { - _Rope_RopeFunction<_CharT,_Alloc>* __f - = (_Rope_RopeFunction<_CharT,_Alloc>*)this; - __f->_Rope_RopeFunction<_CharT,_Alloc>::~_Rope_RopeFunction(); - _F_deallocate(__f, 1); - break; - } - case _Rope_constants::_S_substringfn: - { - _Rope_RopeSubstring<_CharT,_Alloc>* __ss = - (_Rope_RopeSubstring<_CharT,_Alloc>*)this; - __ss->_Rope_RopeSubstring<_CharT,_Alloc>:: - ~_Rope_RopeSubstring(); - _S_deallocate(__ss, 1); - break; - } + + // 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 <class _CharT, class _Alloc> + void + _Rope_RopeRep<_CharT, _Alloc>:: + _M_free_tree() + { + switch(_M_tag) + { + case __detail::_S_leaf: + { + _Rope_RopeLeaf<_CharT, _Alloc>* __l + = (_Rope_RopeLeaf<_CharT, _Alloc>*)this; + __l->_Rope_RopeLeaf<_CharT, _Alloc>::~_Rope_RopeLeaf(); + _L_deallocate(__l, 1); + break; + } + case __detail::_S_concat: + { + _Rope_RopeConcatenation<_CharT,_Alloc>* __c + = (_Rope_RopeConcatenation<_CharT, _Alloc>*)this; + __c->_Rope_RopeConcatenation<_CharT, _Alloc>:: + ~_Rope_RopeConcatenation(); + _C_deallocate(__c, 1); + break; + } + case __detail::_S_function: + { + _Rope_RopeFunction<_CharT, _Alloc>* __f + = (_Rope_RopeFunction<_CharT, _Alloc>*)this; + __f->_Rope_RopeFunction<_CharT, _Alloc>::~_Rope_RopeFunction(); + _F_deallocate(__f, 1); + break; + } + case __detail::_S_substringfn: + { + _Rope_RopeSubstring<_CharT, _Alloc>* __ss = + (_Rope_RopeSubstring<_CharT, _Alloc>*)this; + __ss->_Rope_RopeSubstring<_CharT, _Alloc>:: + ~_Rope_RopeSubstring(); + _S_deallocate(__ss, 1); + break; + } + } } -} #else -template <class _CharT, class _Alloc> - inline void _Rope_RopeRep<_CharT,_Alloc>::_S_free_string - (const _CharT*, size_t, allocator_type) -{} + template <class _CharT, class _Alloc> + inline void + _Rope_RopeRep<_CharT, _Alloc>:: + _S_free_string(const _CharT*, size_t, allocator_type) + { } #endif - -// Concatenate a C string onto a leaf rope by copying the rope data. -// Used for short ropes. -template <class _CharT, class _Alloc> -typename 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->_M_size; - _CharT* __new_data = (_CharT*) - _Data_allocate(_S_rounded_up_size(__old_len + __len)); - _RopeLeaf* __result; - - 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]); - try { - __result = _S_new_RopeLeaf(__new_data, __old_len + __len, - __r->get_allocator()); + // Concatenate a C string onto a leaf rope by copying the rope data. + // Used for short ropes. + template <class _CharT, class _Alloc> + typename 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->_M_size; + _CharT* __new_data = (_CharT*) + _Data_allocate(_S_rounded_up_size(__old_len + __len)); + _RopeLeaf* __result; + + 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]); + try + { + __result = _S_new_RopeLeaf(__new_data, __old_len + __len, + __r->get_allocator()); + } + catch(...) + { + _RopeRep::__STL_FREE_STRING(__new_data, __old_len + __len, + __r->get_allocator()); + __throw_exception_again; + } + return __result; } - catch(...) - { - _RopeRep::__STL_FREE_STRING(__new_data, __old_len + __len, - __r->get_allocator()); - __throw_exception_again; - } - return __result; -} #ifndef __GC -// As above, but it's OK to clobber original if refcount is 1 -template <class _CharT, class _Alloc> -typename rope<_CharT,_Alloc>::_RopeLeaf* -rope<_CharT,_Alloc>::_S_destr_leaf_concat_char_iter - (_RopeLeaf* __r, const _CharT* __iter, size_t __len) -{ - if (__r->_M_ref_count > 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->_M_data + __old_len); - if (_S_is_basic_char_type((_CharT*)0)) { + // As above, but it's OK to clobber original if refcount is 1 + template <class _CharT, class _Alloc> + typename rope<_CharT,_Alloc>::_RopeLeaf* + rope<_CharT, _Alloc>:: + _S_destr_leaf_concat_char_iter(_RopeLeaf* __r, const _CharT* __iter, + size_t __len) + { + if (__r->_M_ref_count > 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->_M_data + __old_len); + if (_S_is_basic_char_type((_CharT*)0)) _S_cond_store_eos(__r->_M_data[__old_len + __len]); - } else if (__r->_M_c_string != __r->_M_data && 0 != __r->_M_c_string) { - __r->_M_free_c_string(); - __r->_M_c_string = 0; + 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->_M_size = __old_len + __len; + __r->_M_ref_count = 2; + return __r; + } + else + { + _RopeLeaf* __result = _S_leaf_concat_char_iter(__r, __iter, __len); + return __result; } - __r->_M_size = __old_len + __len; - __r->_M_ref_count = 2; - return __r; - } else { - _RopeLeaf* __result = _S_leaf_concat_char_iter(__r, __iter, __len); - return __result; } -} #endif -// Assumes left and right are not 0. -// Does not increment (nor decrement on exception) child reference counts. -// Result has ref count 1. -template <class _CharT, class _Alloc> -typename rope<_CharT,_Alloc>::_RopeRep* -rope<_CharT,_Alloc>::_S_tree_concat (_RopeRep* __left, _RopeRep* __right) -{ - _RopeConcatenation* __result = _S_new_RopeConcatenation(__left, __right, - __left->get_allocator()); - size_t __depth = __result->_M_depth; - - if (__depth > 20 && (__result->_M_size < 1000 || - __depth > _Rope_constants::_S_max_rope_depth)) + // Assumes left and right are not 0. + // Does not increment (nor decrement on exception) child reference counts. + // Result has ref count 1. + template <class _CharT, class _Alloc> + typename rope<_CharT, _Alloc>::_RopeRep* + rope<_CharT, _Alloc>:: + _S_tree_concat(_RopeRep* __left, _RopeRep* __right) { - _RopeRep* __balanced; + _RopeConcatenation* __result = _S_new_RopeConcatenation(__left, __right, + __left-> + get_allocator()); + size_t __depth = __result->_M_depth; + + if (__depth > 20 + && (__result->_M_size < 1000 + || __depth > size_t(__detail::_S_max_rope_depth))) + { + _RopeRep* __balanced; + + try + { + __balanced = _S_balance(__result); + __result->_M_unref_nonnil(); + } + catch(...) + { + _C_deallocate(__result,1); + __throw_exception_again; + } + // In case of exception, we need to deallocate + // otherwise dangling result node. But caller + // still owns its children. Thus unref is + // inappropriate. + return __balanced; + } + else + return __result; + } + template <class _CharT, class _Alloc> + typename rope<_CharT, _Alloc>::_RopeRep* + rope<_CharT, _Alloc>:: + _S_concat_char_iter(_RopeRep* __r, const _CharT*__s, size_t __slen) + { + _RopeRep* __result; + if (0 == __slen) + { + _S_ref(__r); + return __r; + } + if (0 == __r) + return __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, + __r->get_allocator()); + if (__r->_M_tag == __detail::_S_leaf + && __r->_M_size + __slen <= size_t(_S_copy_max)) + { + __result = _S_leaf_concat_char_iter((_RopeLeaf*)__r, __s, __slen); + return __result; + } + if (__detail::_S_concat == __r->_M_tag + && __detail::_S_leaf == ((_RopeConcatenation*) __r)->_M_right->_M_tag) + { + _RopeLeaf* __right = + (_RopeLeaf* )(((_RopeConcatenation* )__r)->_M_right); + if (__right->_M_size + __slen <= size_t(_S_copy_max)) + { + _RopeRep* __left = ((_RopeConcatenation*)__r)->_M_left; + _RopeRep* __nright = + _S_leaf_concat_char_iter((_RopeLeaf*)__right, __s, __slen); + __left->_M_ref_nonnil(); + try + { __result = _S_tree_concat(__left, __nright); } + catch(...) + { + _S_unref(__left); + _S_unref(__nright); + __throw_exception_again; + } + return __result; + } + } + _RopeRep* __nright = + __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __r->get_allocator()); try { - __balanced = _S_balance(__result); - __result->_M_unref_nonnil(); - } + __r->_M_ref_nonnil(); + __result = _S_tree_concat(__r, __nright); + } catch(...) { - _C_deallocate(__result,1); + _S_unref(__r); + _S_unref(__nright); __throw_exception_again; } - // In case of exception, we need to deallocate - // otherwise dangling result node. But caller - // still owns its children. Thus unref is - // inappropriate. - return __balanced; - } - else - return __result; -} - -template <class _CharT, class _Alloc> -typename -rope<_CharT,_Alloc>::_RopeRep* rope<_CharT,_Alloc>::_S_concat_char_iter - (_RopeRep* __r, const _CharT*__s, size_t __slen) -{ - _RopeRep* __result; - if (0 == __slen) { - _S_ref(__r); - return __r; + return __result; } - if (0 == __r) - return __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, - __r->get_allocator()); - if (_Rope_constants::_S_leaf == __r->_M_tag && - __r->_M_size + __slen <= _S_copy_max) { - __result = _S_leaf_concat_char_iter((_RopeLeaf*)__r, __s, __slen); - return __result; + +#ifndef __GC + template <class _CharT, class _Alloc> + typename rope<_CharT,_Alloc>::_RopeRep* + rope<_CharT,_Alloc>:: + _S_destr_concat_char_iter(_RopeRep* __r, const _CharT* __s, size_t __slen) + { + _RopeRep* __result; + if (0 == __r) + return __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, + __r->get_allocator()); + size_t __count = __r->_M_ref_count; + size_t __orig_size = __r->_M_size; + if (__count > 1) + return _S_concat_char_iter(__r, __s, __slen); + if (0 == __slen) + { + __r->_M_ref_count = 2; // One more than before + return __r; + } + if (__orig_size + __slen <= size_t(_S_copy_max) + && __detail::_S_leaf == __r->_M_tag) + { + __result = _S_destr_leaf_concat_char_iter((_RopeLeaf*)__r, __s, + __slen); + return __result; + } + if (__detail::_S_concat == __r->_M_tag) + { + _RopeLeaf* __right = (_RopeLeaf*)(((_RopeConcatenation*) + __r)->_M_right); + if (__detail::_S_leaf == __right->_M_tag + && __right->_M_size + __slen <= size_t(_S_copy_max)) + { + _RopeRep* __new_right = + _S_destr_leaf_concat_char_iter(__right, __s, __slen); + if (__right == __new_right) + __new_right->_M_ref_count = 1; + else + __right->_M_unref_nonnil(); + __r->_M_ref_count = 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; + } + } + _RopeRep* __right = + __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __r->get_allocator()); + __r->_M_ref_nonnil(); + try + { __result = _S_tree_concat(__r, __right); } + catch(...) + { + _S_unref(__r); + _S_unref(__right); + __throw_exception_again; + } + return __result; } - if (_Rope_constants::_S_concat == __r->_M_tag - && _Rope_constants::_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); +#endif /* !__GC */ + + template <class _CharT, class _Alloc> + typename rope<_CharT, _Alloc>::_RopeRep* + rope<_CharT, _Alloc>:: + _S_concat(_RopeRep* __left, _RopeRep* __right) + { + if (0 == __left) + { + _S_ref(__right); + return __right; + } + if (0 == __right) + { __left->_M_ref_nonnil(); - try { - __result = _S_tree_concat(__left, __nright); - } - catch(...) + return __left; + } + if (__detail::_S_leaf == __right->_M_tag) + { + if (__detail::_S_leaf == __left->_M_tag) { - _S_unref(__left); - _S_unref(__nright); - __throw_exception_again; + if (__right->_M_size + __left->_M_size <= size_t(_S_copy_max)) + return _S_leaf_concat_char_iter((_RopeLeaf*)__left, + ((_RopeLeaf*)__right)->_M_data, + __right->_M_size); + } + else if (__detail::_S_concat == __left->_M_tag + && __detail::_S_leaf == ((_RopeConcatenation*) + __left)->_M_right->_M_tag) + { + _RopeLeaf* __leftright = + (_RopeLeaf*)(((_RopeConcatenation*)__left)->_M_right); + if (__leftright->_M_size + + __right->_M_size <= size_t(_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(); + try + { return(_S_tree_concat(__leftleft, __rest)); } + catch(...) + { + _S_unref(__leftleft); + _S_unref(__rest); + __throw_exception_again; + } + } } - return __result; + } + __left->_M_ref_nonnil(); + __right->_M_ref_nonnil(); + try + { return(_S_tree_concat(__left, __right)); } + catch(...) + { + _S_unref(__left); + _S_unref(__right); + __throw_exception_again; } } - _RopeRep* __nright = - __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __r->get_allocator()); - try { - __r->_M_ref_nonnil(); - __result = _S_tree_concat(__r, __nright); - } - catch(...) - { - _S_unref(__r); - _S_unref(__nright); - __throw_exception_again; - } - return __result; -} -#ifndef __GC -template <class _CharT, class _Alloc> -typename rope<_CharT,_Alloc>::_RopeRep* -rope<_CharT,_Alloc>::_S_destr_concat_char_iter( - _RopeRep* __r, const _CharT* __s, size_t __slen) -{ - _RopeRep* __result; - if (0 == __r) - return __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, - __r->get_allocator()); - size_t __count = __r->_M_ref_count; - size_t __orig_size = __r->_M_size; - if (__count > 1) return _S_concat_char_iter(__r, __s, __slen); - if (0 == __slen) { - __r->_M_ref_count = 2; // One more than before - return __r; - } - if (__orig_size + __slen <= _S_copy_max && - _Rope_constants::_S_leaf == __r->_M_tag) { - __result = _S_destr_leaf_concat_char_iter((_RopeLeaf*)__r, __s, __slen); - return __result; - } - if (_Rope_constants::_S_concat == __r->_M_tag) { - _RopeLeaf* __right = (_RopeLeaf*)(((_RopeConcatenation*)__r)->_M_right); - if (_Rope_constants::_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) - __new_right->_M_ref_count = 1; + template <class _CharT, class _Alloc> + typename 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->_M_size; + size_t __adj_endp1; + const size_t __lazy_threshold = 128; + + if (__endp1 >= __len) + { + if (0 == __start) + { + __base->_M_ref_nonnil(); + return __base; + } else - __right->_M_unref_nonnil(); - __r->_M_ref_count = 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; + __adj_endp1 = __len; + } - } - _RopeRep* __right = - __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __r->get_allocator()); - __r->_M_ref_nonnil(); - try { - __result = _S_tree_concat(__r, __right); - } - catch(...) - { - _S_unref(__r); - _S_unref(__right); - __throw_exception_again; - } - return __result; -} -#endif /* !__GC */ + else + __adj_endp1 = __endp1; -template <class _CharT, class _Alloc> -typename rope<_CharT,_Alloc>::_RopeRep* -rope<_CharT,_Alloc>::_S_concat(_RopeRep* __left, _RopeRep* __right) -{ - if (0 == __left) { - _S_ref(__right); - return __right; - } - if (0 == __right) { - __left->_M_ref_nonnil(); - return __left; - } - if (_Rope_constants::_S_leaf == __right->_M_tag) { - if (_Rope_constants::_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); + switch(__base->_M_tag) + { + case __detail::_S_concat: + { + _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(_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); + return __result; + } + case __detail::_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; +#ifdef __GC + 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 = __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__l->_M_data + __start, + __result_len, + __base-> + get_allocator()); +#endif + return __result; + } + case __detail::_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* __result = + _S_new_RopeSubstring(__old->_M_base, + __start + __old->_M_start, + __adj_endp1 - __start, + __base->get_allocator()); + return __result; + + } // *** else fall through: *** } - } else if (_Rope_constants::_S_concat == __left->_M_tag - && _Rope_constants::_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(); - try { - return(_S_tree_concat(__leftleft, __rest)); - } + case __detail::_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*) + _Data_allocate(_S_rounded_up_size(__result_len)); + try + { (*(__f->_M_fn))(__start, __result_len, __section); } catch(...) { - _S_unref(__leftleft); - _S_unref(__rest); + _RopeRep::__STL_FREE_STRING(__section, __result_len, + __base->get_allocator()); __throw_exception_again; } + _S_cond_store_eos(__section[__result_len]); + return _S_new_RopeLeaf(__section, __result_len, + __base->get_allocator()); } } - } - __left->_M_ref_nonnil(); - __right->_M_ref_nonnil(); - try { - return(_S_tree_concat(__left, __right)); - } - catch(...) + lazy: { - _S_unref(__left); - _S_unref(__right); - __throw_exception_again; - } -} - -template <class _CharT, class _Alloc> -typename 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->_M_size; - size_t __adj_endp1; - const size_t __lazy_threshold = 128; - - if (__endp1 >= __len) { - if (0 == __start) { - __base->_M_ref_nonnil(); - return __base; - } else { - __adj_endp1 = __len; - } - } else { - __adj_endp1 = __endp1; - } - switch(__base->_M_tag) { - case _Rope_constants::_S_concat: - { - _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( - _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); - return __result; - } - case _Rope_constants::_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; -# ifdef __GC - 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 = __STL_ROPE_FROM_UNOWNED_CHAR_PTR( - __l->_M_data + __start, __result_len, - __base->get_allocator()); -# endif - return __result; - } - case _Rope_constants::_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* __result = - _S_new_RopeSubstring(__old->_M_base, - __start + __old->_M_start, - __adj_endp1 - __start, - __base->get_allocator()); - return __result; - - } // *** else fall through: *** - } - case _Rope_constants::_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*) - _Data_allocate(_S_rounded_up_size(__result_len)); - try { - (*(__f->_M_fn))(__start, __result_len, __section); - } - catch(...) - { - _RopeRep::__STL_FREE_STRING( - __section, __result_len, __base->get_allocator()); - __throw_exception_again; - } - _S_cond_store_eos(__section[__result_len]); - return _S_new_RopeLeaf(__section, __result_len, - __base->get_allocator()); - } - } - lazy: - { // Create substring node. return _S_new_RopeSubstring(__base, __start, __adj_endp1 - __start, - __base->get_allocator()); + __base->get_allocator()); + } } -} -template<class _CharT> -class _Rope_flatten_char_consumer : public _Rope_char_consumer<_CharT> { + template<class _CharT> + class _Rope_flatten_char_consumer + : public _Rope_char_consumer<_CharT> + { private: - _CharT* _M_buf_ptr; + _CharT* _M_buf_ptr; public: + + _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, _M_buf_ptr); + _M_buf_ptr += __n; + return true; + } + }; - _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, _M_buf_ptr); - _M_buf_ptr += __n; - return true; - } -}; - -template<class _CharT> -class _Rope_find_char_char_consumer : public _Rope_char_consumer<_CharT> { + template<class _CharT> + class _Rope_find_char_char_consumer + : public _Rope_char_consumer<_CharT> + { private: - _CharT _M_pattern; + _CharT _M_pattern; public: - 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; - } - } - _M_count += __n; return true; - } -}; + 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; + } + } + _M_count += __n; return true; + } + }; template<class _CharT, class _Traits> // Here _CharT is both the stream and rope character type. -class _Rope_insert_char_consumer : public _Rope_char_consumer<_CharT> { + class _Rope_insert_char_consumer + : public _Rope_char_consumer<_CharT> + { private: - typedef basic_ostream<_CharT,_Traits> _Insert_ostream; - _Insert_ostream& _M_o; + typedef basic_ostream<_CharT,_Traits> _Insert_ostream; + _Insert_ostream& _M_o; public: - _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); - // Returns true to continue traversal. -}; - -template<class _CharT, class _Traits> -bool _Rope_insert_char_consumer<_CharT, _Traits>::operator() - (const _CharT* __leaf, size_t __n) -{ - size_t __i; - // We assume that formatting is set up correctly for each element. - for (__i = 0; __i < __n; __i++) _M_o.put(__leaf[__i]); - return true; -} - -template <class _CharT, class _Alloc> -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->_M_tag) { - case _Rope_constants::_S_concat: - { - _RopeConcatenation* __conc = (_RopeConcatenation*)__r; - _RopeRep* __left = __conc->_M_left; - size_t __left_len = __left->_M_size; - if (__begin < __left_len) { - size_t __left_end = std::min(__left_len, __end); - if (!_S_apply_to_pieces(__c, __left, __begin, __left_end)) - return false; - } - if (__end > __left_len) { - _RopeRep* __right = __conc->_M_right; - size_t __right_start = std::max(__left_len, __begin); - if (!_S_apply_to_pieces(__c, __right, - __right_start - __left_len, - __end - __left_len)) { - return false; - } - } - } - return true; - case _Rope_constants::_S_leaf: - { - _RopeLeaf* __l = (_RopeLeaf*)__r; - return __c(__l->_M_data + __begin, __end - __begin); - } - case _Rope_constants::_S_function: - case _Rope_constants::_S_substringfn: + _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); + // Returns true to continue traversal. + }; + + template<class _CharT, class _Traits> + bool + _Rope_insert_char_consumer<_CharT, _Traits>:: + operator()(const _CharT* __leaf, size_t __n) + { + size_t __i; + // We assume that formatting is set up correctly for each element. + for (__i = 0; __i < __n; __i++) + _M_o.put(__leaf[__i]); + return true; + } + + template <class _CharT, class _Alloc> + 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->_M_tag) + { + case __detail::_S_concat: + { + _RopeConcatenation* __conc = (_RopeConcatenation*)__r; + _RopeRep* __left = __conc->_M_left; + size_t __left_len = __left->_M_size; + if (__begin < __left_len) + { + size_t __left_end = std::min(__left_len, __end); + if (!_S_apply_to_pieces(__c, __left, __begin, __left_end)) + return false; + } + if (__end > __left_len) + { + _RopeRep* __right = __conc->_M_right; + size_t __right_start = std::max(__left_len, __begin); + if (!_S_apply_to_pieces(__c, __right, + __right_start - __left_len, + __end - __left_len)) + return false; + } + } + return true; + case __detail::_S_leaf: + { + _RopeLeaf* __l = (_RopeLeaf*)__r; + return __c(__l->_M_data + __begin, __end - __begin); + } + case __detail::_S_function: + case __detail::_S_substringfn: { - _RopeFunction* __f = (_RopeFunction*)__r; - size_t __len = __end - __begin; - bool __result; - _CharT* __buffer = - (_CharT*)_Alloc().allocate(__len * sizeof(_CharT)); - try { + _RopeFunction* __f = (_RopeFunction*)__r; + size_t __len = __end - __begin; + bool __result; + _CharT* __buffer = + (_CharT*)_Alloc().allocate(__len * sizeof(_CharT)); + try + { (*(__f->_M_fn))(__begin, __len, __buffer); __result = __c(__buffer, __len); _Alloc().deallocate(__buffer, __len * sizeof(_CharT)); } - catch(...) - { - _Alloc().deallocate(__buffer, __len * sizeof(_CharT)); - __throw_exception_again; - } - return __result; + catch(...) + { + _Alloc().deallocate(__buffer, __len * sizeof(_CharT)); + __throw_exception_again; + } + return __result; } default: return false; + } } -} template<class _CharT, class _Traits> - inline void _Rope_fill(basic_ostream<_CharT, _Traits>& __o, size_t __n) -{ - char __f = __o.fill(); - size_t __i; - - for (__i = 0; __i < __n; __i++) __o.put(__f); -} - - -template <class _CharT> 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<class _CharT, class _Traits, class _Alloc> -basic_ostream<_CharT, _Traits>& operator<< (basic_ostream<_CharT, _Traits>& __o, - const rope<_CharT, _Alloc>& __r) -{ - size_t __w = __o.width(); - bool __left = bool(__o.flags() & std::ios::left); - size_t __pad_len; - size_t __rope_len = __r.size(); - _Rope_insert_char_consumer<_CharT, _Traits> __c(__o); - bool __is_simple = _Rope_is_simple((_CharT*)0); + inline void + _Rope_fill(basic_ostream<_CharT, _Traits>& __o, size_t __n) + { + char __f = __o.fill(); + size_t __i; + + for (__i = 0; __i < __n; __i++) + __o.put(__f); + } + + + template <class _CharT> + inline bool + _Rope_is_simple(_CharT*) + { return false; } + + inline bool + _Rope_is_simple(char*) + { return true; } - if (__rope_len < __w) { + inline bool + _Rope_is_simple(wchar_t*) + { return true; } + + template<class _CharT, class _Traits, class _Alloc> + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __o, + const rope<_CharT, _Alloc>& __r) + { + size_t __w = __o.width(); + bool __left = bool(__o.flags() & std::ios::left); + size_t __pad_len; + size_t __rope_len = __r.size(); + _Rope_insert_char_consumer<_CharT, _Traits> __c(__o); + bool __is_simple = _Rope_is_simple((_CharT*)0); + + if (__rope_len < __w) __pad_len = __w - __rope_len; - } else { + else __pad_len = 0; - } - if (!__is_simple) __o.width(__w/__rope_len); - try { - 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); + __o.width(__w / __rope_len); + try + { + 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); + } + catch(...) + { + if (!__is_simple) + __o.width(__w); + __throw_exception_again; + } + return __o; } - catch(...) - { - if (!__is_simple) - __o.width(__w); - __throw_exception_again; - } - return __o; -} - -template <class _CharT, class _Alloc> -_CharT* -rope<_CharT,_Alloc>::_S_flatten(_RopeRep* __r, - size_t __start, size_t __len, - _CharT* __buffer) -{ - _Rope_flatten_char_consumer<_CharT> __c(__buffer); - _S_apply_to_pieces(__c, __r, __start, __start + __len); - return(__buffer + __len); -} - -template <class _CharT, class _Alloc> -size_t -rope<_CharT,_Alloc>::find(_CharT __pattern, size_t __start) const -{ - _Rope_find_char_char_consumer<_CharT> __c(__pattern); - _S_apply_to_pieces(__c, this->_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 <class _CharT, class _Alloc> -_CharT* -rope<_CharT,_Alloc>::_S_flatten(_RopeRep* __r, _CharT* __buffer) -{ - if (0 == __r) return __buffer; - switch(__r->_M_tag) { - case _Rope_constants::_S_concat: - { - _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 _Rope_constants::_S_leaf: - { - _RopeLeaf* __l = (_RopeLeaf*)__r; - return copy_n(__l->_M_data, __l->_M_size, __buffer).second; - } - case _Rope_constants::_S_function: - case _Rope_constants::_S_substringfn: - // We don't yet do anything with substring nodes. - // This needs to be fixed before ropefiles will work well. - { - _RopeFunction* __f = (_RopeFunction*)__r; - (*(__f->_M_fn))(0, __f->_M_size, __buffer); - return __buffer + __f->_M_size; - } - default: - return 0; + + template <class _CharT, class _Alloc> + _CharT* + rope<_CharT, _Alloc>:: + _S_flatten(_RopeRep* __r, size_t __start, size_t __len, + _CharT* __buffer) + { + _Rope_flatten_char_consumer<_CharT> __c(__buffer); + _S_apply_to_pieces(__c, __r, __start, __start + __len); + return(__buffer + __len); } -} + template <class _CharT, class _Alloc> + size_t + rope<_CharT, _Alloc>:: + find(_CharT __pattern, size_t __start) const + { + _Rope_find_char_char_consumer<_CharT> __c(__pattern); + _S_apply_to_pieces(__c, this->_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; + } -// This needs work for _CharT != char -template <class _CharT, class _Alloc> -void -rope<_CharT,_Alloc>::_S_dump(_RopeRep* __r, int __indent) -{ - for (int __i = 0; __i < __indent; __i++) putchar(' '); - if (0 == __r) { - printf("NULL\n"); return; + template <class _CharT, class _Alloc> + _CharT* + rope<_CharT, _Alloc>:: + _S_flatten(_RopeRep* __r, _CharT* __buffer) + { + if (0 == __r) + return __buffer; + switch(__r->_M_tag) + { + case __detail::_S_concat: + { + _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 __detail::_S_leaf: + { + _RopeLeaf* __l = (_RopeLeaf*)__r; + return copy_n(__l->_M_data, __l->_M_size, __buffer).second; + } + case __detail::_S_function: + case __detail::_S_substringfn: + // We don't yet do anything with substring nodes. + // This needs to be fixed before ropefiles will work well. + { + _RopeFunction* __f = (_RopeFunction*)__r; + (*(__f->_M_fn))(0, __f->_M_size, __buffer); + return __buffer + __f->_M_size; + } + default: + return 0; + } } - if (_Rope_constants::_S_concat == __r->_M_tag) { - _RopeConcatenation* __c = (_RopeConcatenation*)__r; - _RopeRep* __left = __c->_M_left; - _RopeRep* __right = __c->_M_right; -# ifdef __GC + // This needs work for _CharT != char + template <class _CharT, class _Alloc> + void + rope<_CharT, _Alloc>:: + _S_dump(_RopeRep* __r, int __indent) + { + for (int __i = 0; __i < __indent; __i++) + putchar(' '); + if (0 == __r) + { + printf("NULL\n"); + return; + } + if (_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->_M_depth, __r->_M_size, __r->_M_is_balanced? "" : "not"); -# else + __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", + "len = %ld, %s balanced)\n", __r, __r->_M_ref_count, __r->_M_depth, __r->_M_size, __r->_M_is_balanced? "" : "not"); -# endif - _S_dump(__left, __indent + 2); - _S_dump(__right, __indent + 2); - return; - } else { - char* __kind; - - switch (__r->_M_tag) { - case _Rope_constants::_S_leaf: - __kind = "Leaf"; - break; - case _Rope_constants::_S_function: - __kind = "Function"; - break; - case _Rope_constants::_S_substringfn: - __kind = "Function representing substring"; - break; - default: - __kind = "(corrupted kind field!)"; +#endif + _S_dump(__left, __indent + 2); + _S_dump(__right, __indent + 2); + return; } -# ifdef __GC + else + { + char* __kind; + + switch (__r->_M_tag) + { + case __detail::_S_leaf: + __kind = "Leaf"; + break; + case __detail::_S_function: + __kind = "Function"; + break; + case __detail::_S_substringfn: + __kind = "Function representing substring"; + break; + default: + __kind = "(corrupted kind field!)"; + } +#ifdef __GC printf("%s %p (depth = %d, len = %ld) ", __kind, __r, __r->_M_depth, __r->_M_size); -# else +#else printf("%s %p (rc = %ld, depth = %d, len = %ld) ", __kind, __r, __r->_M_ref_count, __r->_M_depth, __r->_M_size); -# endif - 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 { +#endif + 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 <class _CharT, class _Alloc> -const unsigned long -rope<_CharT,_Alloc>::_S_min_len[_Rope_constants::_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, -/* 18 */6765, /* 19 */10946, /* 20 */17711, /* 21 */28657, /* 22 */46368, -/* 23 */75025, /* 24 */121393, /* 25 */196418, /* 26 */317811, -/* 27 */514229, /* 28 */832040, /* 29 */1346269, /* 30 */2178309, -/* 31 */3524578, /* 32 */5702887, /* 33 */9227465, /* 34 */14930352, -/* 35 */24157817, /* 36 */39088169, /* 37 */63245986, /* 38 */102334155, -/* 39 */165580141, /* 40 */267914296, /* 41 */433494437, -/* 42 */701408733, /* 43 */1134903170, /* 44 */1836311903, -/* 45 */2971215073u }; -// These are Fibonacci numbers < 2**32. - -template <class _CharT, class _Alloc> -typename rope<_CharT,_Alloc>::_RopeRep* -rope<_CharT,_Alloc>::_S_balance(_RopeRep* __r) -{ - _RopeRep* __forest[_Rope_constants::_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 <= _Rope_constants::_S_max_rope_depth; ++__i) - __forest[__i] = 0; - try { - _S_add_to_forest(__r, __forest); - for (__i = 0; __i <= _Rope_constants::_S_max_rope_depth; ++__i) - if (0 != __forest[__i]) { -# ifndef __GC - _Self_destruct_ptr __old(__result); -# endif - __result = _S_concat(__forest[__i], __result); - __forest[__i]->_M_unref_nonnil(); -# if !defined(__GC) && defined(__EXCEPTIONS) - __forest[__i] = 0; -# endif - } - } - catch(...) - { - for(__i = 0; __i <= _Rope_constants::_S_max_rope_depth; __i++) - _S_unref(__forest[__i]); - __throw_exception_again; - } - - if (__result->_M_depth > _Rope_constants::_S_max_rope_depth) - __throw_length_error(__N("rope::_S_balance")); - return(__result); -} - -template <class _CharT, class _Alloc> -void -rope<_CharT,_Alloc>::_S_add_to_forest(_RopeRep* __r, _RopeRep** __forest) -{ - if (__r->_M_is_balanced) { - _S_add_leaf_to_forest(__r, __forest); - return; + template <class _CharT, class _Alloc> + const unsigned long + rope<_CharT, _Alloc>:: + _S_min_len[int(__detail::_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, + /* 18 */6765, /* 19 */10946, /* 20 */17711, /* 21 */28657, /* 22 */46368, + /* 23 */75025, /* 24 */121393, /* 25 */196418, /* 26 */317811, + /* 27 */514229, /* 28 */832040, /* 29 */1346269, /* 30 */2178309, + /* 31 */3524578, /* 32 */5702887, /* 33 */9227465, /* 34 */14930352, + /* 35 */24157817, /* 36 */39088169, /* 37 */63245986, /* 38 */102334155, + /* 39 */165580141, /* 40 */267914296, /* 41 */433494437, + /* 42 */701408733, /* 43 */1134903170, /* 44 */1836311903, + /* 45 */2971215073u }; + // These are Fibonacci numbers < 2**32. + + template <class _CharT, class _Alloc> + typename rope<_CharT, _Alloc>::_RopeRep* + rope<_CharT, _Alloc>:: + _S_balance(_RopeRep* __r) + { + _RopeRep* __forest[int(__detail::_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 <= int(__detail::_S_max_rope_depth); ++__i) + __forest[__i] = 0; + try + { + _S_add_to_forest(__r, __forest); + for (__i = 0; __i <= int(__detail::_S_max_rope_depth); ++__i) + if (0 != __forest[__i]) + { +#ifndef __GC + _Self_destruct_ptr __old(__result); +#endif + __result = _S_concat(__forest[__i], __result); + __forest[__i]->_M_unref_nonnil(); +#if !defined(__GC) && defined(__EXCEPTIONS) + __forest[__i] = 0; +#endif + } + } + catch(...) + { + for(__i = 0; __i <= int(__detail::_S_max_rope_depth); __i++) + _S_unref(__forest[__i]); + __throw_exception_again; + } + + if (__result->_M_depth > int(__detail::_S_max_rope_depth)) + __throw_length_error(__N("rope::_S_balance")); + return(__result); } + template <class _CharT, class _Alloc> + void + rope<_CharT, _Alloc>:: + _S_add_to_forest(_RopeRep* __r, _RopeRep** __forest) { - _RopeConcatenation* __c = (_RopeConcatenation*)__r; + if (__r->_M_is_balanced) + { + _S_add_leaf_to_forest(__r, __forest); + return; + } + { + _RopeConcatenation* __c = (_RopeConcatenation*)__r; + _S_add_to_forest(__c->_M_left, __forest); _S_add_to_forest(__c->_M_right, __forest); + } } -} -template <class _CharT, class _Alloc> -void -rope<_CharT,_Alloc>::_S_add_leaf_to_forest(_RopeRep* __r, _RopeRep** __forest) -{ - _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 >= _S_min_len[__i+1]/* not this bucket */; ++__i) { - if (0 != __forest[__i]) { -# ifndef __GC + template <class _CharT, class _Alloc> + void + rope<_CharT, _Alloc>:: + _S_add_leaf_to_forest(_RopeRep* __r, _RopeRep** __forest) + { + _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 >= _S_min_len[__i+1]/* not this bucket */; ++__i) + { + if (0 != __forest[__i]) + { +#ifndef __GC _Self_destruct_ptr __old(__too_tiny); -# endif - __too_tiny = _S_concat_and_set_balanced(__forest[__i], __too_tiny); - __forest[__i]->_M_unref_nonnil(); - __forest[__i] = 0; +#endif + __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); -# endif + { +#ifndef __GC + _Self_destruct_ptr __old(__too_tiny); +#endif __insertee = _S_concat_and_set_balanced(__too_tiny, __r); - } - // Too_tiny dead, and no longer included in refcount. - // Insertee is live and included. - for (;; ++__i) { - if (0 != __forest[__i]) { -# ifndef __GC + } + // Too_tiny dead, and no longer included in refcount. + // Insertee is live and included. + for (;; ++__i) + { + if (0 != __forest[__i]) + { +#ifndef __GC _Self_destruct_ptr __old(__insertee); -# endif - __insertee = _S_concat_and_set_balanced(__forest[__i], __insertee); - __forest[__i]->_M_unref_nonnil(); - __forest[__i] = 0; - } - if (__i == _Rope_constants::_S_max_rope_depth || - __insertee->_M_size < _S_min_len[__i+1]) { - __forest[__i] = __insertee; - // refcount is OK since __insertee is now dead. - return; +#endif + __insertee = _S_concat_and_set_balanced(__forest[__i], + __insertee); + __forest[__i]->_M_unref_nonnil(); + __forest[__i] = 0; + } + if (__i == int(__detail::_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 <class _CharT, class _Alloc> -_CharT -rope<_CharT,_Alloc>::_S_fetch(_RopeRep* __r, size_type __i) -{ - __GC_CONST _CharT* __cstr = __r->_M_c_string; - - if (0 != __cstr) return __cstr[__i]; - for(;;) { - switch(__r->_M_tag) { - case _Rope_constants::_S_concat: + + template <class _CharT, class _Alloc> + _CharT + rope<_CharT, _Alloc>:: + _S_fetch(_RopeRep* __r, size_type __i) + { + __GC_CONST _CharT* __cstr = __r->_M_c_string; + + if (0 != __cstr) + return __cstr[__i]; + for(;;) + { + switch(__r->_M_tag) { + case __detail::_S_concat: + { _RopeConcatenation* __c = (_RopeConcatenation*)__r; _RopeRep* __left = __c->_M_left; size_t __left_len = __left->_M_size; - - if (__i >= __left_len) { + + if (__i >= __left_len) + { __i -= __left_len; __r = __c->_M_right; - } else { - __r = __left; - } - } - break; - case _Rope_constants::_S_leaf: - { + } + else + __r = __left; + } + break; + case __detail::_S_leaf: + { _RopeLeaf* __l = (_RopeLeaf*)__r; return __l->_M_data[__i]; - } - case _Rope_constants::_S_function: - case _Rope_constants::_S_substringfn: - { + } + case __detail::_S_function: + case __detail::_S_substringfn: + { _RopeFunction* __f = (_RopeFunction*)__r; _CharT __result; - + (*(__f->_M_fn))(__i, 1, &__result); return __result; + } } - } + } } -} - -# ifndef __GC -// Return a uniquely referenced character slot for the given -// position, or 0 if that's not possible. -template <class _CharT, class _Alloc> -_CharT* -rope<_CharT,_Alloc>::_S_fetch_ptr(_RopeRep* __r, size_type __i) -{ - _RopeRep* __clrstack[_Rope_constants::_S_max_rope_depth]; - size_t __csptr = 0; - - for(;;) { - if (__r->_M_ref_count > 1) return 0; - switch(__r->_M_tag) { - case _Rope_constants::_S_concat: + +#ifndef __GC + // Return a uniquely referenced character slot for the given + // position, or 0 if that's not possible. + template <class _CharT, class _Alloc> + _CharT* + rope<_CharT, _Alloc>:: + _S_fetch_ptr(_RopeRep* __r, size_type __i) + { + _RopeRep* __clrstack[__detail::_S_max_rope_depth]; + size_t __csptr = 0; + + for(;;) + { + if (__r->_M_ref_count > 1) + return 0; + switch(__r->_M_tag) { + case __detail::_S_concat: + { _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) { + + if (__c->_M_c_string != 0) + __clrstack[__csptr++] = __c; + if (__i >= __left_len) + { __i -= __left_len; __r = __c->_M_right; - } else { - __r = __left; - } - } - break; - case _Rope_constants::_S_leaf: - { + } + else + __r = __left; + } + break; + case __detail::_S_leaf: + { _RopeLeaf* __l = (_RopeLeaf*)__r; if (__l->_M_c_string != __l->_M_data && __l->_M_c_string != 0) - __clrstack[__csptr++] = __l; - while (__csptr > 0) { + __clrstack[__csptr++] = __l; + while (__csptr > 0) + { -- __csptr; _RopeRep* __d = __clrstack[__csptr]; __d->_M_free_c_string(); __d->_M_c_string = 0; - } + } return __l->_M_data + __i; + } + case __detail::_S_function: + case __detail::_S_substringfn: + return 0; } - case _Rope_constants::_S_function: - case _Rope_constants::_S_substringfn: - return 0; - } + } } -} -# endif /* __GC */ - -// The following could be implemented trivially using -// lexicographical_compare_3way. -// We do a little more work to avoid dealing with rope iterators for -// flat strings. -template <class _CharT, class _Alloc> -int -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->_M_size; - __right_len = __right->_M_size; - if (_Rope_constants::_S_leaf == __left->_M_tag) { - _RopeLeaf* __l = (_RopeLeaf*) __left; - if (_Rope_constants::_S_leaf == __right->_M_tag) { - _RopeLeaf* __r = (_RopeLeaf*) __right; - return lexicographical_compare_3way( - __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); - return lexicographical_compare_3way( - __l->_M_data, __l->_M_data + __left_len, - __rstart, __rend); +#endif /* __GC */ + + // The following could be implemented trivially using + // lexicographical_compare_3way. + // We do a little more work to avoid dealing with rope iterators for + // flat strings. + template <class _CharT, class _Alloc> + int + 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->_M_size; + __right_len = __right->_M_size; + if (__detail::_S_leaf == __left->_M_tag) + { + _RopeLeaf* __l = (_RopeLeaf*) __left; + if (__detail::_S_leaf == __right->_M_tag) + { + _RopeLeaf* __r = (_RopeLeaf*) __right; + return lexicographical_compare_3way(__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); + return lexicographical_compare_3way(__l->_M_data, __l->_M_data + + __left_len, + __rstart, __rend); + } } - } else { - const_iterator __lstart(__left, 0); - const_iterator __lend(__left, __left_len); - if (_Rope_constants::_S_leaf == __right->_M_tag) { - _RopeLeaf* __r = (_RopeLeaf*) __right; - return lexicographical_compare_3way( - __lstart, __lend, - __r->_M_data, __r->_M_data + __right_len); - } else { - const_iterator __rstart(__right, 0); - const_iterator __rend(__right, __right_len); - return lexicographical_compare_3way( - __lstart, __lend, - __rstart, __rend); + else + { + const_iterator __lstart(__left, 0); + const_iterator __lend(__left, __left_len); + if (__detail::_S_leaf == __right->_M_tag) + { + _RopeLeaf* __r = (_RopeLeaf*) __right; + return lexicographical_compare_3way(__lstart, __lend, + __r->_M_data, __r->_M_data + + __right_len); + } + else + { + const_iterator __rstart(__right, 0); + const_iterator __rend(__right, __right_len); + return lexicographical_compare_3way(__lstart, __lend, + __rstart, __rend); + } } } -} - -// Assignment to reference proxies. -template <class _CharT, class _Alloc> -_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* __ptr = _My_rope::_S_fetch_ptr(__old, _M_pos); - if (0 != __ptr) { - *__ptr = __c; - return *this; + + // Assignment to reference proxies. + template <class _CharT, class _Alloc> + _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* __ptr = _My_rope::_S_fetch_ptr(__old, _M_pos); + if (0 != __ptr) + { + *__ptr = __c; + return *this; } -# endif - _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)); - - _RopeRep* __result = - _My_rope::_S_concat(__result_left, __right); -# ifndef __GC +#endif + _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)); + + _RopeRep* __result = _My_rope::_S_concat(__result_left, __right); +#ifndef __GC _RopeRep::_S_unref(__old); -# endif - _M_root->_M_tree_ptr = __result; - return *this; -} - -template <class _CharT, class _Alloc> -inline _Rope_char_ref_proxy<_CharT, _Alloc>::operator _CharT () const -{ - if (_M_current_valid) { +#endif + _M_root->_M_tree_ptr = __result; + return *this; + } + + template <class _CharT, class _Alloc> + inline _Rope_char_ref_proxy<_CharT, _Alloc>:: + operator _CharT() const + { + if (_M_current_valid) return _M_current; - } else { - return _My_rope::_S_fetch(_M_root->_M_tree_ptr, _M_pos); + else + return _My_rope::_S_fetch(_M_root->_M_tree_ptr, _M_pos); } -} -template <class _CharT, class _Alloc> -_Rope_char_ptr_proxy<_CharT, _Alloc> -_Rope_char_ref_proxy<_CharT, _Alloc>::operator& () const { - return _Rope_char_ptr_proxy<_CharT, _Alloc>(*this); -} - -template <class _CharT, class _Alloc> -rope<_CharT, _Alloc>::rope(size_t __n, _CharT __c, - const allocator_type& __a) -: _Base(__a) -{ - 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) { + + template <class _CharT, class _Alloc> + _Rope_char_ptr_proxy<_CharT, _Alloc> + _Rope_char_ref_proxy<_CharT, _Alloc>:: + operator&() const + { return _Rope_char_ptr_proxy<_CharT, _Alloc>(*this); } + + template <class _CharT, class _Alloc> + rope<_CharT, _Alloc>:: + rope(size_t __n, _CharT __c, const allocator_type& __a) + : _Base(__a) + { + 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 = this->_Data_allocate(_S_rounded_up_size(__rest)); - uninitialized_fill_n(__rest_buffer, __rest, __c); - _S_cond_store_eos(__rest_buffer[__rest]); - try { - __remainder = _S_new_RopeLeaf(__rest_buffer, __rest, __a); - } - catch(...) - { - _RopeRep::__STL_FREE_STRING(__rest_buffer, __rest, __a); - __throw_exception_again; - } - } - __remainder_rope._M_tree_ptr = __remainder; - if (__exponent != 0) { - _CharT* __base_buffer = - this->_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]); - try { - __base_leaf = _S_new_RopeLeaf(__base_buffer, - __exponentiate_threshold, __a); - } - catch(...) - { - _RopeRep::__STL_FREE_STRING(__base_buffer, - __exponentiate_threshold, __a); - __throw_exception_again; - } - __base_rope._M_tree_ptr = __base_leaf; - if (1 == __exponent) { - __result = __base_rope; - } else { - __result = power(__base_rope, __exponent, - _Rope_Concat_fn<_CharT,_Alloc>()); + else + { + __rest_buffer = this->_Data_allocate(_S_rounded_up_size(__rest)); + __uninitialized_fill_n_a(__rest_buffer, __rest, __c, + get_allocator()); + _S_cond_store_eos(__rest_buffer[__rest]); + try + { __remainder = _S_new_RopeLeaf(__rest_buffer, __rest, __a); } + catch(...) + { + _RopeRep::__STL_FREE_STRING(__rest_buffer, __rest, __a); + __throw_exception_again; + } } - if (0 != __remainder) { - __result += __remainder_rope; + __remainder_rope._M_tree_ptr = __remainder; + if (__exponent != 0) + { + _CharT* __base_buffer = + this->_Data_allocate(_S_rounded_up_size(__exponentiate_threshold)); + _RopeLeaf* __base_leaf; + rope __base_rope; + __uninitialized_fill_n_a(__base_buffer, __exponentiate_threshold, __c, + get_allocator()); + _S_cond_store_eos(__base_buffer[__exponentiate_threshold]); + try + { + __base_leaf = _S_new_RopeLeaf(__base_buffer, + __exponentiate_threshold, __a); + } + catch(...) + { + _RopeRep::__STL_FREE_STRING(__base_buffer, + __exponentiate_threshold, __a); + __throw_exception_again; + } + __base_rope._M_tree_ptr = __base_leaf; + if (1 == __exponent) + __result = __base_rope; + else + __result = power(__base_rope, __exponent, + _Rope_Concat_fn<_CharT, _Alloc>()); + + if (0 != __remainder) + __result += __remainder_rope; } - } else { + else __result = __remainder_rope; + + this->_M_tree_ptr = __result._M_tree_ptr; + this->_M_tree_ptr->_M_ref_nonnil(); } - this->_M_tree_ptr = __result._M_tree_ptr; - this->_M_tree_ptr->_M_ref_nonnil(); -} - -template<class _CharT, class _Alloc> - _CharT rope<_CharT,_Alloc>::_S_empty_c_str[1]; - -template<class _CharT, class _Alloc> -const _CharT* rope<_CharT,_Alloc>::c_str() const { - if (0 == this->_M_tree_ptr) { - _S_empty_c_str[0] = _S_eos((_CharT*)0); // Possibly redundant, - // but probably fast. - return _S_empty_c_str; - } - __gthread_mutex_lock (&this->_M_tree_ptr->_M_c_string_lock); - __GC_CONST _CharT* __result = this->_M_tree_ptr->_M_c_string; - if (0 == __result) - { - size_t __s = size(); - __result = this->_Data_allocate(__s + 1); - _S_flatten(this->_M_tree_ptr, __result); - __result[__s] = _S_eos((_CharT*)0); - this->_M_tree_ptr->_M_c_string = __result; - } - __gthread_mutex_unlock (&this->_M_tree_ptr->_M_c_string_lock); - return(__result); -} - -template<class _CharT, class _Alloc> -const _CharT* rope<_CharT,_Alloc>::replace_with_c_str() { - if (0 == this->_M_tree_ptr) { - _S_empty_c_str[0] = _S_eos((_CharT*)0); - return _S_empty_c_str; + + template<class _CharT, class _Alloc> + _CharT + rope<_CharT, _Alloc>::_S_empty_c_str[1]; + + template<class _CharT, class _Alloc> + const _CharT* + rope<_CharT, _Alloc>:: + c_str() const + { + if (0 == this->_M_tree_ptr) + { + _S_empty_c_str[0] = _S_eos((_CharT*)0); // Possibly redundant, + // but probably fast. + return _S_empty_c_str; + } + __gthread_mutex_lock (&this->_M_tree_ptr->_M_c_string_lock); + __GC_CONST _CharT* __result = this->_M_tree_ptr->_M_c_string; + if (0 == __result) + { + size_t __s = size(); + __result = this->_Data_allocate(__s + 1); + _S_flatten(this->_M_tree_ptr, __result); + __result[__s] = _S_eos((_CharT*)0); + this->_M_tree_ptr->_M_c_string = __result; + } + __gthread_mutex_unlock (&this->_M_tree_ptr->_M_c_string_lock); + return(__result); } - __GC_CONST _CharT* __old_c_string = this->_M_tree_ptr->_M_c_string; - if (_Rope_constants::_S_leaf == this->_M_tree_ptr->_M_tag - && 0 != __old_c_string) { + + template<class _CharT, class _Alloc> + const _CharT* rope<_CharT, _Alloc>:: + replace_with_c_str() + { + if (0 == this->_M_tree_ptr) + { + _S_empty_c_str[0] = _S_eos((_CharT*)0); + return _S_empty_c_str; + } + __GC_CONST _CharT* __old_c_string = this->_M_tree_ptr->_M_c_string; + if (__detail::_S_leaf == this->_M_tree_ptr->_M_tag + && 0 != __old_c_string) return(__old_c_string); + size_t __s = size(); + _CharT* __result = this->_Data_allocate(_S_rounded_up_size(__s)); + _S_flatten(this->_M_tree_ptr, __result); + __result[__s] = _S_eos((_CharT*)0); + this->_M_tree_ptr->_M_unref_nonnil(); + this->_M_tree_ptr = _S_new_RopeLeaf(__result, __s, + this->get_allocator()); + return(__result); + } + + // Algorithm specializations. More should be added. + + template<class _Rope_iterator> // was templated on CharT and Alloc + void // VC++ workaround + _Rope_rotate(_Rope_iterator __first, + _Rope_iterator __middle, + _Rope_iterator __last) + { + typedef typename _Rope_iterator::value_type _CharT; + typedef typename _Rope_iterator::_allocator_type _Alloc; + + 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; } - size_t __s = size(); - _CharT* __result = this->_Data_allocate(_S_rounded_up_size(__s)); - _S_flatten(this->_M_tree_ptr, __result); - __result[__s] = _S_eos((_CharT*)0); - this->_M_tree_ptr->_M_unref_nonnil(); - this->_M_tree_ptr = _S_new_RopeLeaf(__result, __s, this->get_allocator()); - return(__result); -} - -// Algorithm specializations. More should be added. - -template<class _Rope_iterator> // was templated on CharT and Alloc -void // VC++ workaround -_Rope_rotate(_Rope_iterator __first, - _Rope_iterator __middle, - _Rope_iterator __last) -{ - typedef typename _Rope_iterator::value_type _CharT; - typedef typename _Rope_iterator::_allocator_type _Alloc; - - 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; -} #if !defined(__GNUC__) -// Appears to confuse g++ -inline void rotate(_Rope_iterator<char,__STL_DEFAULT_ALLOCATOR(char)> __first, - _Rope_iterator<char,__STL_DEFAULT_ALLOCATOR(char)> __middle, - _Rope_iterator<char,__STL_DEFAULT_ALLOCATOR(char)> __last) { - _Rope_rotate(__first, __middle, __last); -} + // Appears to confuse g++ + inline void + rotate(_Rope_iterator<char, __STL_DEFAULT_ALLOCATOR(char)> __first, + _Rope_iterator<char, __STL_DEFAULT_ALLOCATOR(char)> __middle, + _Rope_iterator<char, __STL_DEFAULT_ALLOCATOR(char)> __last) + { _Rope_rotate(__first, __middle, __last); } #endif # if 0 -// Probably not useful for several reasons: -// - for SGIs 7.1 compiler and probably some others, -// this forces lots of rope<wchar_t, ...> instantiations, creating a -// code bloat and compile time problem. (Fixed in 7.2.) -// - 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<wchar_t,__STL_DEFAULT_ALLOCATOR(char)> __first, - _Rope_iterator<wchar_t,__STL_DEFAULT_ALLOCATOR(char)> __middle, - _Rope_iterator<wchar_t,__STL_DEFAULT_ALLOCATOR(char)> __last) { - _Rope_rotate(__first, __middle, __last); -} + // Probably not useful for several reasons: + // - for SGIs 7.1 compiler and probably some others, + // this forces lots of rope<wchar_t, ...> instantiations, creating a + // code bloat and compile time problem. (Fixed in 7.2.) + // - 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<wchar_t, __STL_DEFAULT_ALLOCATOR(char)> __first, + _Rope_iterator<wchar_t, __STL_DEFAULT_ALLOCATOR(char)> __middle, + _Rope_iterator<wchar_t, __STL_DEFAULT_ALLOCATOR(char)> __last) + { _Rope_rotate(__first, __middle, __last); } # endif -} // namespace __gnu_cxx - -// Local Variables: -// mode:C++ -// End: +_GLIBCXX_END_NAMESPACE diff --git a/contrib/libstdc++/include/ext/slist b/contrib/libstdc++/include/ext/slist index 4b5852030184..328a52e012f3 100644 --- a/contrib/libstdc++/include/ext/slist +++ b/contrib/libstdc++/include/ext/slist @@ -1,6 +1,6 @@ // Singly-linked list implementation -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2004, 2005 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -15,7 +15,7 @@ // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, // USA. // As a special exception, you may use this file as part of a free software @@ -43,8 +43,7 @@ /** @file ext/slist * This file is a GNU extension to the Standard C++ Library (possibly - * containing extensions from the HP/SGI STL subset). You should only - * include this header if you are using GCC 3 or later. + * containing extensions from the HP/SGI STL subset). */ #ifndef _SLIST @@ -56,851 +55,1027 @@ #include <bits/stl_uninitialized.h> #include <bits/concept_check.h> -namespace __gnu_cxx -{ -using std::size_t; -using std::ptrdiff_t; -using std::_Construct; -using std::_Destroy; -using std::allocator; - -struct _Slist_node_base -{ - _Slist_node_base* _M_next; -}; - -inline _Slist_node_base* -__slist_make_link(_Slist_node_base* __prev_node, - _Slist_node_base* __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) -{ - 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) -{ - 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) -{ - 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 void -__slist_splice_after(_Slist_node_base* __pos, _Slist_node_base* __head) -{ - _Slist_node_base* __before_last = __slist_previous(__head, 0); - if (__before_last != __head) { - _Slist_node_base* __after = __pos->_M_next; - __pos->_M_next = __head->_M_next; - __head->_M_next = 0; - __before_last->_M_next = __after; - } -} - -inline _Slist_node_base* __slist_reverse(_Slist_node_base* __node) -{ - _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; -} - -inline size_t __slist_size(_Slist_node_base* __node) -{ - size_t __result = 0; - for ( ; __node != 0; __node = __node->_M_next) - ++__result; - return __result; -} - -template <class _Tp> -struct _Slist_node : public _Slist_node_base -{ - _Tp _M_data; -}; - -struct _Slist_iterator_base -{ - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef std::forward_iterator_tag iterator_category; - - _Slist_node_base* _M_node; - - _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 _M_node == __x._M_node; - } - bool operator!=(const _Slist_iterator_base& __x) const { - return _M_node != __x._M_node; - } -}; +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) -template <class _Tp, class _Ref, class _Ptr> -struct _Slist_iterator : public _Slist_iterator_base -{ - typedef _Slist_iterator<_Tp, _Tp&, _Tp*> iterator; - typedef _Slist_iterator<_Tp, const _Tp&, const _Tp*> const_iterator; - typedef _Slist_iterator<_Tp, _Ref, _Ptr> _Self; + using std::size_t; + using std::ptrdiff_t; + using std::_Construct; + using std::_Destroy; + using std::allocator; + using std::__true_type; + using std::__false_type; - typedef _Tp value_type; - typedef _Ptr pointer; - typedef _Ref reference; - typedef _Slist_node<_Tp> _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 ((_Node*) _M_node)->_M_data; } - pointer operator->() const { return &(operator*()); } - - _Self& operator++() + struct _Slist_node_base { - _M_incr(); - return *this; - } - _Self operator++(int) + _Slist_node_base* _M_next; + }; + + inline _Slist_node_base* + __slist_make_link(_Slist_node_base* __prev_node, + _Slist_node_base* __new_node) { - _Self __tmp = *this; - _M_incr(); - return __tmp; - } -}; - -template <class _Tp, class _Alloc> -struct _Slist_base - : public _Alloc::template rebind<_Slist_node<_Tp> >::other -{ - typedef typename _Alloc::template rebind<_Slist_node<_Tp> >::other _Node_alloc; - typedef _Alloc allocator_type; - allocator_type get_allocator() const { - return *static_cast<const _Node_alloc*>(this); + __new_node->_M_next = __prev_node->_M_next; + __prev_node->_M_next = __new_node; + return __new_node; } - _Slist_base(const allocator_type& __a) - : _Node_alloc(__a) { this->_M_head._M_next = 0; } - ~_Slist_base() { _M_erase_after(&this->_M_head, 0); } - -protected: - _Slist_node_base _M_head; - - _Slist_node<_Tp>* _M_get_node() { return _Node_alloc::allocate(1); } - void _M_put_node(_Slist_node<_Tp>* __p) { _Node_alloc::deallocate(__p, 1); } - -protected: - _Slist_node_base* _M_erase_after(_Slist_node_base* __pos) + inline _Slist_node_base* + __slist_previous(_Slist_node_base* __head, + const _Slist_node_base* __node) { - _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; + while (__head && __head->_M_next != __node) + __head = __head->_M_next; + return __head; } - _Slist_node_base* _M_erase_after(_Slist_node_base*, _Slist_node_base*); -}; - -template <class _Tp, class _Alloc> -_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); + + inline const _Slist_node_base* + __slist_previous(const _Slist_node_base* __head, + const _Slist_node_base* __node) + { + while (__head && __head->_M_next != __node) + __head = __head->_M_next; + return __head; } - __before_first->_M_next = __last_node; - return __last_node; -} - -/** - * This is an SGI extension. - * @ingroup SGIextensions - * @doctodo -*/ -template <class _Tp, class _Alloc = allocator<_Tp> > -class slist : private _Slist_base<_Tp,_Alloc> -{ - // concept requirements - __glibcxx_class_requires(_Tp, _SGIAssignableConcept) - -private: - typedef _Slist_base<_Tp,_Alloc> _Base; -public: - 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 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 typename _Base::allocator_type allocator_type; - allocator_type get_allocator() const { return _Base::get_allocator(); } - -private: - typedef _Slist_node<_Tp> _Node; - typedef _Slist_node_base _Node_base; - typedef _Slist_iterator_base _Iterator_base; - - _Node* _M_create_node(const value_type& __x) { - _Node* __node = this->_M_get_node(); - try { - _Construct(&__node->_M_data, __x); - __node->_M_next = 0; - } - catch(...) + + 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) { - this->_M_put_node(__node); - __throw_exception_again; + _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; } - return __node; } - _Node* _M_create_node() { - _Node* __node = this->_M_get_node(); - try { - _Construct(&__node->_M_data); - __node->_M_next = 0; - } - catch(...) + inline void + __slist_splice_after(_Slist_node_base* __pos, _Slist_node_base* __head) + { + _Slist_node_base* __before_last = __slist_previous(__head, 0); + if (__before_last != __head) { - this->_M_put_node(__node); - __throw_exception_again; + _Slist_node_base* __after = __pos->_M_next; + __pos->_M_next = __head->_M_next; + __head->_M_next = 0; + __before_last->_M_next = __after; } - return __node; } -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(&this->_M_head, __n, __x); } - - explicit slist(size_type __n) : _Base(allocator_type()) - { _M_insert_after_fill(&this->_M_head, __n, value_type()); } - - // We don't need any dispatching tricks here, because _M_insert_after_range - // already does them. - template <class _InputIterator> - slist(_InputIterator __first, _InputIterator __last, - const allocator_type& __a = allocator_type()) : _Base(__a) - { _M_insert_after_range(&this->_M_head, __first, __last); } - - slist(const slist& __x) : _Base(__x.get_allocator()) - { _M_insert_after_range(&this->_M_head, __x.begin(), __x.end()); } - - slist& operator= (const slist& __x); - - ~slist() {} - -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) - { _M_fill_assign(__n, __val); } - - void _M_fill_assign(size_type __n, const _Tp& __val); - - template <class _InputIterator> - void assign(_InputIterator __first, _InputIterator __last) { - typedef typename _Is_integer<_InputIterator>::_Integral _Integral; - _M_assign_dispatch(__first, __last, _Integral()); + inline _Slist_node_base* + __slist_reverse(_Slist_node_base* __node) + { + _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 <class _Integer> - void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) - { _M_fill_assign((size_type) __n, (_Tp) __val); } - - template <class _InputIterator> - void _M_assign_dispatch(_InputIterator __first, _InputIterator __last, - __false_type); + inline size_t + __slist_size(_Slist_node_base* __node) + { + size_t __result = 0; + for (; __node != 0; __node = __node->_M_next) + ++__result; + return __result; + } -public: + template <class _Tp> + struct _Slist_node : public _Slist_node_base + { + _Tp _M_data; + }; - iterator begin() { return iterator((_Node*)this->_M_head._M_next); } - const_iterator begin() const - { return const_iterator((_Node*)this->_M_head._M_next);} + struct _Slist_iterator_base + { + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef std::forward_iterator_tag iterator_category; + + _Slist_node_base* _M_node; + + _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 _M_node == __x._M_node; } + + bool + operator!=(const _Slist_iterator_base& __x) const + { return _M_node != __x._M_node; } + }; + + template <class _Tp, class _Ref, class _Ptr> + struct _Slist_iterator : public _Slist_iterator_base + { + 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 _Tp value_type; + typedef _Ptr pointer; + typedef _Ref reference; + typedef _Slist_node<_Tp> _Node; + + explicit + _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 ((_Node*) _M_node)->_M_data; } + + pointer + operator->() const + { return &(operator*()); } + + _Self& + operator++() + { + _M_incr(); + return *this; + } - iterator end() { return iterator(0); } - const_iterator end() const { return const_iterator(0); } + _Self + operator++(int) + { + _Self __tmp = *this; + _M_incr(); + return __tmp; + } + }; + + template <class _Tp, class _Alloc> + struct _Slist_base + : public _Alloc::template rebind<_Slist_node<_Tp> >::other + { + typedef typename _Alloc::template rebind<_Slist_node<_Tp> >::other + _Node_alloc; + typedef _Alloc allocator_type; + + allocator_type + get_allocator() const + { return *static_cast<const _Node_alloc*>(this); } + + _Slist_base(const allocator_type& __a) + : _Node_alloc(__a) + { this->_M_head._M_next = 0; } + + ~_Slist_base() + { _M_erase_after(&this->_M_head, 0); } + + protected: + _Slist_node_base _M_head; + + _Slist_node<_Tp>* + _M_get_node() + { return _Node_alloc::allocate(1); } + + void + _M_put_node(_Slist_node<_Tp>* __p) + { _Node_alloc::deallocate(__p, 1); } + + 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; + get_allocator().destroy(&__next->_M_data); + _M_put_node(__next); + return __next_next; + } + _Slist_node_base* _M_erase_after(_Slist_node_base*, _Slist_node_base*); + }; + + template <class _Tp, class _Alloc> + _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; + get_allocator().destroy(&__tmp->_M_data); + _M_put_node(__tmp); + } + __before_first->_M_next = __last_node; + return __last_node; + } - // Experimental new feature: before_begin() returns a - // non-dereferenceable iterator that, when incremented, yields - // begin(). This iterator may be used as the argument to - // insert_after, erase_after, etc. Note that even for an empty - // slist, before_begin() is not the same iterator as end(). It - // is always necessary to increment before_begin() at least once to - // obtain end(). - iterator before_begin() { return iterator((_Node*) &this->_M_head); } - const_iterator before_begin() const - { return const_iterator((_Node*) &this->_M_head); } + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template <class _Tp, class _Alloc = allocator<_Tp> > + class slist : private _Slist_base<_Tp,_Alloc> + { + // concept requirements + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + + private: + typedef _Slist_base<_Tp,_Alloc> _Base; + + public: + 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 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 typename _Base::allocator_type allocator_type; + + allocator_type + get_allocator() const + { return _Base::get_allocator(); } + + private: + typedef _Slist_node<_Tp> _Node; + typedef _Slist_node_base _Node_base; + typedef _Slist_iterator_base _Iterator_base; + + _Node* + _M_create_node(const value_type& __x) + { + _Node* __node = this->_M_get_node(); + try + { + get_allocator().construct(&__node->_M_data, __x); + __node->_M_next = 0; + } + catch(...) + { + this->_M_put_node(__node); + __throw_exception_again; + } + return __node; + } - size_type size() const { return __slist_size(this->_M_head._M_next); } + _Node* + _M_create_node() + { + _Node* __node = this->_M_get_node(); + try + { + get_allocator().construct(&__node->_M_data, value_type()); + __node->_M_next = 0; + } + catch(...) + { + this->_M_put_node(__node); + __throw_exception_again; + } + return __node; + } - size_type max_size() const { return size_type(-1); } + 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(&this->_M_head, __n, __x); } + + explicit + slist(size_type __n) + : _Base(allocator_type()) + { _M_insert_after_fill(&this->_M_head, __n, value_type()); } + + // We don't need any dispatching tricks here, because + // _M_insert_after_range already does them. + template <class _InputIterator> + slist(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { _M_insert_after_range(&this->_M_head, __first, __last); } + + slist(const slist& __x) + : _Base(__x.get_allocator()) + { _M_insert_after_range(&this->_M_head, __x.begin(), __x.end()); } + + slist& + operator= (const slist& __x); + + ~slist() {} + + 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) + { _M_fill_assign(__n, __val); } + + void + _M_fill_assign(size_type __n, const _Tp& __val); + + template <class _InputIterator> + void + assign(_InputIterator __first, _InputIterator __last) + { + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } + + template <class _Integer> + void + _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { _M_fill_assign((size_type) __n, (_Tp) __val); } + + template <class _InputIterator> + void + _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type); + + public: + + iterator + begin() + { return iterator((_Node*)this->_M_head._M_next); } + + const_iterator + begin() const + { return const_iterator((_Node*)this->_M_head._M_next);} + + iterator + end() + { return iterator(0); } + + const_iterator + end() const + { return const_iterator(0); } + + // Experimental new feature: before_begin() returns a + // non-dereferenceable iterator that, when incremented, yields + // begin(). This iterator may be used as the argument to + // insert_after, erase_after, etc. Note that even for an empty + // slist, before_begin() is not the same iterator as end(). It + // is always necessary to increment before_begin() at least once to + // obtain end(). + iterator + before_begin() + { return iterator((_Node*) &this->_M_head); } + + const_iterator + before_begin() const + { return const_iterator((_Node*) &this->_M_head); } + + size_type + size() const + { return __slist_size(this->_M_head._M_next); } + + size_type + max_size() const + { return size_type(-1); } + + bool + empty() const + { return this->_M_head._M_next == 0; } + + void + swap(slist& __x) + { std::swap(this->_M_head._M_next, __x._M_head._M_next); } + + public: + + reference + front() + { return ((_Node*) this->_M_head._M_next)->_M_data; } + + const_reference + front() const + { return ((_Node*) this->_M_head._M_next)->_M_data; } + + void + push_front(const value_type& __x) + { __slist_make_link(&this->_M_head, _M_create_node(__x)); } + + void + push_front() + { __slist_make_link(&this->_M_head, _M_create_node()); } + + void + pop_front() + { + _Node* __node = (_Node*) this->_M_head._M_next; + this->_M_head._M_next = __node->_M_next; + get_allocator().destroy(&__node->_M_data); + this->_M_put_node(__node); + } - bool empty() const { return this->_M_head._M_next == 0; } + iterator + previous(const_iterator __pos) + { return iterator((_Node*) __slist_previous(&this->_M_head, + __pos._M_node)); } - void swap(slist& __x) - { std::swap(this->_M_head._M_next, __x._M_head._M_next); } + const_iterator + previous(const_iterator __pos) const + { return const_iterator((_Node*) __slist_previous(&this->_M_head, + __pos._M_node)); } -public: + private: + _Node* + _M_insert_after(_Node_base* __pos, const value_type& __x) + { return (_Node*) (__slist_make_link(__pos, _M_create_node(__x))); } - reference front() { return ((_Node*) this->_M_head._M_next)->_M_data; } - const_reference front() const - { return ((_Node*) this->_M_head._M_next)->_M_data; } - void push_front(const value_type& __x) { - __slist_make_link(&this->_M_head, _M_create_node(__x)); - } - void push_front() { __slist_make_link(&this->_M_head, _M_create_node()); } - void pop_front() { - _Node* __node = (_Node*) this->_M_head._M_next; - this->_M_head._M_next = __node->_M_next; - _Destroy(&__node->_M_data); - this->_M_put_node(__node); - } + _Node* + _M_insert_after(_Node_base* __pos) + { return (_Node*) (__slist_make_link(__pos, _M_create_node())); } - iterator previous(const_iterator __pos) { - return iterator((_Node*) __slist_previous(&this->_M_head, __pos._M_node)); - } - const_iterator previous(const_iterator __pos) const { - return const_iterator((_Node*) __slist_previous(&this->_M_head, - __pos._M_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)); + } -private: - _Node* _M_insert_after(_Node_base* __pos, const value_type& __x) { - return (_Node*) (__slist_make_link(__pos, _M_create_node(__x))); - } + // Check whether it's an integral type. If so, it's not an iterator. + template <class _InIterator> + void + _M_insert_after_range(_Node_base* __pos, + _InIterator __first, _InIterator __last) + { + typedef typename std::__is_integer<_InIterator>::__type _Integral; + _M_insert_after_range(__pos, __first, __last, _Integral()); + } + + template <class _Integer> + void + _M_insert_after_range(_Node_base* __pos, _Integer __n, _Integer __x, + __true_type) + { _M_insert_after_fill(__pos, __n, __x); } + + template <class _InIterator> + void + _M_insert_after_range(_Node_base* __pos, + _InIterator __first, _InIterator __last, + __false_type) + { + while (__first != __last) + { + __pos = __slist_make_link(__pos, _M_create_node(*__first)); + ++__first; + } + } + + public: + 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()); } + + void + insert_after(iterator __pos, size_type __n, const value_type& __x) + { _M_insert_after_fill(__pos._M_node, __n, __x); } + + // We don't need any dispatching tricks here, because + // _M_insert_after_range already does them. + template <class _InIterator> + void + insert_after(iterator __pos, _InIterator __first, _InIterator __last) + { _M_insert_after_range(__pos._M_node, __first, __last); } + + iterator + insert(iterator __pos, const value_type& __x) + { return iterator(_M_insert_after(__slist_previous(&this->_M_head, + __pos._M_node), + __x)); } + + iterator + insert(iterator __pos) + { return iterator(_M_insert_after(__slist_previous(&this->_M_head, + __pos._M_node), + value_type())); } + + void + insert(iterator __pos, size_type __n, const value_type& __x) + { _M_insert_after_fill(__slist_previous(&this->_M_head, __pos._M_node), + __n, __x); } + + // We don't need any dispatching tricks here, because + // _M_insert_after_range already does them. + template <class _InIterator> + void + insert(iterator __pos, _InIterator __first, _InIterator __last) + { _M_insert_after_range(__slist_previous(&this->_M_head, __pos._M_node), + __first, __last); } + + public: + iterator + erase_after(iterator __pos) + { return iterator((_Node*) this->_M_erase_after(__pos._M_node)); } + + iterator + erase_after(iterator __before_first, iterator __last) + { + return iterator((_Node*) this->_M_erase_after(__before_first._M_node, + __last._M_node)); + } - _Node* _M_insert_after(_Node_base* __pos) { - return (_Node*) (__slist_make_link(__pos, _M_create_node())); - } + iterator + erase(iterator __pos) + { + return iterator((_Node*) this->_M_erase_after + (__slist_previous(&this->_M_head, __pos._M_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)); - } + iterator + erase(iterator __first, iterator __last) + { + return iterator((_Node*) this->_M_erase_after + (__slist_previous(&this->_M_head, __first._M_node), + __last._M_node)); + } + + void + resize(size_type new_size, const _Tp& __x); + + void + resize(size_type new_size) + { resize(new_size, _Tp()); } + + void + clear() + { this->_M_erase_after(&this->_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) + { + if (__before_first != __before_last) + __slist_splice_after(__pos._M_node, __before_first._M_node, + __before_last._M_node); + } - // Check whether it's an integral type. If so, it's not an iterator. - template <class _InIterator> - void _M_insert_after_range(_Node_base* __pos, - _InIterator __first, _InIterator __last) { - typedef typename _Is_integer<_InIterator>::_Integral _Integral; - _M_insert_after_range(__pos, __first, __last, _Integral()); - } + // 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._M_node, + __prev._M_node, __prev._M_node->_M_next); } + + // Removes all of the elements from the list __x to *this, inserting + // them immediately after __pos. __x must not be *this. Complexity: + // linear in __x.size(). + void + splice_after(iterator __pos, slist& __x) + { __slist_splice_after(__pos._M_node, &__x._M_head); } + + // 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(&this->_M_head, __pos._M_node), + &__x._M_head, + __slist_previous(&__x._M_head, 0)); } + + // Linear in distance(begin(), __pos), and in distance(__x.begin(), __i). + void + splice(iterator __pos, slist& __x, iterator __i) + { __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node), + __slist_previous(&__x._M_head, __i._M_node), + __i._M_node); } + + // 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(&this->_M_head, __pos._M_node), + __slist_previous(&__x._M_head, __first._M_node), + __slist_previous(__first._M_node, + __last._M_node)); + } - template <class _Integer> - void _M_insert_after_range(_Node_base* __pos, _Integer __n, _Integer __x, - __true_type) { - _M_insert_after_fill(__pos, __n, __x); - } + public: + void + reverse() + { + if (this->_M_head._M_next) + this->_M_head._M_next = __slist_reverse(this->_M_head._M_next); + } - template <class _InIterator> - void _M_insert_after_range(_Node_base* __pos, - _InIterator __first, _InIterator __last, - __false_type) { - while (__first != __last) { - __pos = __slist_make_link(__pos, _M_create_node(*__first)); - ++__first; + void + remove(const _Tp& __val); + + void + unique(); + + void + merge(slist& __x); + + void + sort(); + + template <class _Predicate> + void + remove_if(_Predicate __pred); + + template <class _BinaryPredicate> + void + unique(_BinaryPredicate __pred); + + template <class _StrictWeakOrdering> + void + merge(slist&, _StrictWeakOrdering); + + template <class _StrictWeakOrdering> + void + sort(_StrictWeakOrdering __comp); + }; + + template <class _Tp, class _Alloc> + slist<_Tp, _Alloc>& + slist<_Tp, _Alloc>::operator=(const slist<_Tp, _Alloc>& __x) + { + if (&__x != this) + { + _Node_base* __p1 = &this->_M_head; + _Node* __n1 = (_Node*) this->_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) + this->_M_erase_after(__p1, 0); + else + _M_insert_after_range(__p1, const_iterator((_Node*)__n2), + const_iterator(0)); + } + return *this; } - } -public: - - 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()); - } - - void insert_after(iterator __pos, size_type __n, const value_type& __x) { - _M_insert_after_fill(__pos._M_node, __n, __x); - } - - // We don't need any dispatching tricks here, because _M_insert_after_range - // already does them. - template <class _InIterator> - void insert_after(iterator __pos, _InIterator __first, _InIterator __last) { - _M_insert_after_range(__pos._M_node, __first, __last); - } - - iterator insert(iterator __pos, const value_type& __x) { - return iterator(_M_insert_after(__slist_previous(&this->_M_head, - __pos._M_node), - __x)); - } - - iterator insert(iterator __pos) { - return iterator(_M_insert_after(__slist_previous(&this->_M_head, - __pos._M_node), - value_type())); - } - - void insert(iterator __pos, size_type __n, const value_type& __x) { - _M_insert_after_fill(__slist_previous(&this->_M_head, __pos._M_node), - __n, __x); - } - - // We don't need any dispatching tricks here, because _M_insert_after_range - // already does them. - template <class _InIterator> - void insert(iterator __pos, _InIterator __first, _InIterator __last) { - _M_insert_after_range(__slist_previous(&this->_M_head, __pos._M_node), - __first, __last); - } - -public: - iterator erase_after(iterator __pos) { - return iterator((_Node*) this->_M_erase_after(__pos._M_node)); - } - iterator erase_after(iterator __before_first, iterator __last) { - return iterator((_Node*) this->_M_erase_after(__before_first._M_node, - __last._M_node)); - } + template <class _Tp, class _Alloc> + void + slist<_Tp, _Alloc>::_M_fill_assign(size_type __n, const _Tp& __val) + { + _Node_base* __prev = &this->_M_head; + _Node* __node = (_Node*) this->_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 + this->_M_erase_after(__prev, 0); + } + + template <class _Tp, class _Alloc> + template <class _InputIterator> + void + slist<_Tp, _Alloc>::_M_assign_dispatch(_InputIterator __first, + _InputIterator __last, + __false_type) + { + _Node_base* __prev = &this->_M_head; + _Node* __node = (_Node*) this->_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 + this->_M_erase_after(__prev, 0); + } + + template <class _Tp, class _Alloc> + inline bool + operator==(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2) + { + typedef typename slist<_Tp,_Alloc>::const_iterator const_iterator; + const_iterator __end1 = _SL1.end(); + const_iterator __end2 = _SL2.end(); + + const_iterator __i1 = _SL1.begin(); + const_iterator __i2 = _SL2.begin(); + while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) + { + ++__i1; + ++__i2; + } + return __i1 == __end1 && __i2 == __end2; + } - iterator erase(iterator __pos) { - return (_Node*) this->_M_erase_after(__slist_previous(&this->_M_head, - __pos._M_node)); - } - iterator erase(iterator __first, iterator __last) { - return (_Node*) this->_M_erase_after( - __slist_previous(&this->_M_head, __first._M_node), __last._M_node); - } - void resize(size_type new_size, const _Tp& __x); - void resize(size_type new_size) { resize(new_size, _Tp()); } - void clear() { this->_M_erase_after(&this->_M_head, 0); } + template <class _Tp, class _Alloc> + inline bool + operator<(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2) + { return std::lexicographical_compare(_SL1.begin(), _SL1.end(), + _SL2.begin(), _SL2.end()); } + + template <class _Tp, class _Alloc> + inline bool + operator!=(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2) + { return !(_SL1 == _SL2); } + + template <class _Tp, class _Alloc> + inline bool + operator>(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2) + { return _SL2 < _SL1; } + + template <class _Tp, class _Alloc> + inline bool + operator<=(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2) + { return !(_SL2 < _SL1); } + + template <class _Tp, class _Alloc> + inline bool + operator>=(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2) + { return !(_SL1 < _SL2); } + + template <class _Tp, class _Alloc> + inline void + swap(slist<_Tp, _Alloc>& __x, slist<_Tp, _Alloc>& __y) + { __x.swap(__y); } + + template <class _Tp, class _Alloc> + void + slist<_Tp, _Alloc>::resize(size_type __len, const _Tp& __x) + { + _Node_base* __cur = &this->_M_head; + while (__cur->_M_next != 0 && __len > 0) + { + --__len; + __cur = __cur->_M_next; + } + if (__cur->_M_next) + this->_M_erase_after(__cur, 0); + else + _M_insert_after_fill(__cur, __len, __x); + } -public: - // Moves the range [__before_first + 1, __before_last + 1) to *this, - // inserting it immediately after __pos. This is constant time. - void splice_after(iterator __pos, - iterator __before_first, iterator __before_last) - { - if (__before_first != __before_last) - __slist_splice_after(__pos._M_node, __before_first._M_node, - __before_last._M_node); - } + template <class _Tp, class _Alloc> + void + slist<_Tp, _Alloc>::remove(const _Tp& __val) + { + _Node_base* __cur = &this->_M_head; + while (__cur && __cur->_M_next) + { + if (((_Node*) __cur->_M_next)->_M_data == __val) + this->_M_erase_after(__cur); + else + __cur = __cur->_M_next; + } + } - // 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._M_node, - __prev._M_node, __prev._M_node->_M_next); - } + template <class _Tp, class _Alloc> + void + slist<_Tp, _Alloc>::unique() + { + _Node_base* __cur = this->_M_head._M_next; + if (__cur) + { + while (__cur->_M_next) + { + if (((_Node*)__cur)->_M_data + == ((_Node*)(__cur->_M_next))->_M_data) + this->_M_erase_after(__cur); + else + __cur = __cur->_M_next; + } + } + } + template <class _Tp, class _Alloc> + void + slist<_Tp, _Alloc>::merge(slist<_Tp, _Alloc>& __x) + { + _Node_base* __n1 = &this->_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 (__x._M_head._M_next) + { + __n1->_M_next = __x._M_head._M_next; + __x._M_head._M_next = 0; + } + } - // Removes all of the elements from the list __x to *this, inserting - // them immediately after __pos. __x must not be *this. Complexity: - // linear in __x.size(). - void splice_after(iterator __pos, slist& __x) - { - __slist_splice_after(__pos._M_node, &__x._M_head); - } + template <class _Tp, class _Alloc> + void + slist<_Tp, _Alloc>::sort() + { + if (this->_M_head._M_next && this->_M_head._M_next->_M_next) + { + slist __carry; + slist __counter[64]; + int __fill = 0; + while (!empty()) + { + __slist_splice_after(&__carry._M_head, + &this->_M_head, this->_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; + } + + for (int __i = 1; __i < __fill; ++__i) + __counter[__i].merge(__counter[__i-1]); + this->swap(__counter[__fill-1]); + } + } - // 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(&this->_M_head, __pos._M_node), - &__x._M_head, __slist_previous(&__x._M_head, 0)); - } + template <class _Tp, class _Alloc> + template <class _Predicate> + void slist<_Tp, _Alloc>::remove_if(_Predicate __pred) + { + _Node_base* __cur = &this->_M_head; + while (__cur->_M_next) + { + if (__pred(((_Node*) __cur->_M_next)->_M_data)) + this->_M_erase_after(__cur); + else + __cur = __cur->_M_next; + } + } - // Linear in distance(begin(), __pos), and in distance(__x.begin(), __i). - void splice(iterator __pos, slist& __x, iterator __i) { - __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node), - __slist_previous(&__x._M_head, __i._M_node), - __i._M_node); - } + template <class _Tp, class _Alloc> + template <class _BinaryPredicate> + void + slist<_Tp, _Alloc>::unique(_BinaryPredicate __pred) + { + _Node* __cur = (_Node*) this->_M_head._M_next; + if (__cur) + { + while (__cur->_M_next) + { + if (__pred(((_Node*)__cur)->_M_data, + ((_Node*)(__cur->_M_next))->_M_data)) + this->_M_erase_after(__cur); + else + __cur = (_Node*) __cur->_M_next; + } + } + } - // 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(&this->_M_head, __pos._M_node), - __slist_previous(&__x._M_head, __first._M_node), - __slist_previous(__first._M_node, __last._M_node)); - } + template <class _Tp, class _Alloc> + template <class _StrictWeakOrdering> + void + slist<_Tp, _Alloc>::merge(slist<_Tp, _Alloc>& __x, + _StrictWeakOrdering __comp) + { + _Node_base* __n1 = &this->_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 (__x._M_head._M_next) + { + __n1->_M_next = __x._M_head._M_next; + __x._M_head._M_next = 0; + } + } -public: - void reverse() { - if (this->_M_head._M_next) - this->_M_head._M_next = __slist_reverse(this->_M_head._M_next); - } + template <class _Tp, class _Alloc> + template <class _StrictWeakOrdering> + void + slist<_Tp, _Alloc>::sort(_StrictWeakOrdering __comp) + { + if (this->_M_head._M_next && this->_M_head._M_next->_M_next) + { + slist __carry; + slist __counter[64]; + int __fill = 0; + while (!empty()) + { + __slist_splice_after(&__carry._M_head, + &this->_M_head, this->_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; + } + + for (int __i = 1; __i < __fill; ++__i) + __counter[__i].merge(__counter[__i-1], __comp); + this->swap(__counter[__fill-1]); + } + } - void remove(const _Tp& __val); - void unique(); - void merge(slist& __x); - void sort(); - - template <class _Predicate> - void remove_if(_Predicate __pred); - - template <class _BinaryPredicate> - void unique(_BinaryPredicate __pred); - - template <class _StrictWeakOrdering> - void merge(slist&, _StrictWeakOrdering); - - template <class _StrictWeakOrdering> - void sort(_StrictWeakOrdering __comp); -}; - -template <class _Tp, class _Alloc> -slist<_Tp,_Alloc>& slist<_Tp,_Alloc>::operator=(const slist<_Tp,_Alloc>& __x) -{ - if (&__x != this) { - _Node_base* __p1 = &this->_M_head; - _Node* __n1 = (_Node*) this->_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) - this->_M_erase_after(__p1, 0); - else - _M_insert_after_range(__p1, const_iterator((_Node*)__n2), - const_iterator(0)); - } - return *this; -} - -template <class _Tp, class _Alloc> -void slist<_Tp, _Alloc>::_M_fill_assign(size_type __n, const _Tp& __val) { - _Node_base* __prev = &this->_M_head; - _Node* __node = (_Node*) this->_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 - this->_M_erase_after(__prev, 0); -} - -template <class _Tp, class _Alloc> template <class _InputIterator> -void -slist<_Tp, _Alloc>::_M_assign_dispatch(_InputIterator __first, _InputIterator __last, - __false_type) -{ - _Node_base* __prev = &this->_M_head; - _Node* __node = (_Node*) this->_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 - this->_M_erase_after(__prev, 0); -} - -template <class _Tp, class _Alloc> -inline bool -operator==(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) -{ - typedef typename slist<_Tp,_Alloc>::const_iterator const_iterator; - const_iterator __end1 = _SL1.end(); - const_iterator __end2 = _SL2.end(); - - const_iterator __i1 = _SL1.begin(); - const_iterator __i2 = _SL2.begin(); - while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) { - ++__i1; - ++__i2; - } - return __i1 == __end1 && __i2 == __end2; -} - - -template <class _Tp, class _Alloc> -inline bool -operator<(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) -{ - return std::lexicographical_compare(_SL1.begin(), _SL1.end(), - _SL2.begin(), _SL2.end()); -} - -template <class _Tp, class _Alloc> -inline bool -operator!=(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) { - return !(_SL1 == _SL2); -} - -template <class _Tp, class _Alloc> -inline bool -operator>(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) { - return _SL2 < _SL1; -} - -template <class _Tp, class _Alloc> -inline bool -operator<=(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) { - return !(_SL2 < _SL1); -} - -template <class _Tp, class _Alloc> -inline bool -operator>=(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) { - return !(_SL1 < _SL2); -} - -template <class _Tp, class _Alloc> -inline void swap(slist<_Tp,_Alloc>& __x, slist<_Tp,_Alloc>& __y) { - __x.swap(__y); -} - - -template <class _Tp, class _Alloc> -void slist<_Tp,_Alloc>::resize(size_type __len, const _Tp& __x) -{ - _Node_base* __cur = &this->_M_head; - while (__cur->_M_next != 0 && __len > 0) { - --__len; - __cur = __cur->_M_next; - } - if (__cur->_M_next) - this->_M_erase_after(__cur, 0); - else - _M_insert_after_fill(__cur, __len, __x); -} - -template <class _Tp, class _Alloc> -void slist<_Tp,_Alloc>::remove(const _Tp& __val) -{ - _Node_base* __cur = &this->_M_head; - while (__cur && __cur->_M_next) { - if (((_Node*) __cur->_M_next)->_M_data == __val) - this->_M_erase_after(__cur); - else - __cur = __cur->_M_next; - } -} - -template <class _Tp, class _Alloc> -void slist<_Tp,_Alloc>::unique() -{ - _Node_base* __cur = this->_M_head._M_next; - if (__cur) { - while (__cur->_M_next) { - if (((_Node*)__cur)->_M_data == - ((_Node*)(__cur->_M_next))->_M_data) - this->_M_erase_after(__cur); - else - __cur = __cur->_M_next; - } - } -} - -template <class _Tp, class _Alloc> -void slist<_Tp,_Alloc>::merge(slist<_Tp,_Alloc>& __x) -{ - _Node_base* __n1 = &this->_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 (__x._M_head._M_next) { - __n1->_M_next = __x._M_head._M_next; - __x._M_head._M_next = 0; - } -} - -template <class _Tp, class _Alloc> -void slist<_Tp,_Alloc>::sort() -{ - if (this->_M_head._M_next && this->_M_head._M_next->_M_next) { - slist __carry; - slist __counter[64]; - int __fill = 0; - while (!empty()) { - __slist_splice_after(&__carry._M_head, - &this->_M_head, this->_M_head._M_next); - int __i = 0; - while (__i < __fill && !__counter[__i].empty()) { - __counter[__i].merge(__carry); - __carry.swap(__counter[__i]); - ++__i; +_GLIBCXX_END_NAMESPACE + +_GLIBCXX_BEGIN_NAMESPACE(std) + + // Specialization of insert_iterator so that insertions will be constant + // time rather than linear time. + template <class _Tp, class _Alloc> + class insert_iterator<__gnu_cxx::slist<_Tp, _Alloc> > + { + protected: + typedef __gnu_cxx::slist<_Tp, _Alloc> _Container; + _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) + { + if (__i == __x.begin()) + iter = __x.before_begin(); + else + iter = __x.previous(__i); } - __carry.swap(__counter[__i]); - if (__i == __fill) - ++__fill; - } - for (int __i = 1; __i < __fill; ++__i) - __counter[__i].merge(__counter[__i-1]); - this->swap(__counter[__fill-1]); - } -} - -template <class _Tp, class _Alloc> -template <class _Predicate> -void slist<_Tp,_Alloc>::remove_if(_Predicate __pred) -{ - _Node_base* __cur = &this->_M_head; - while (__cur->_M_next) { - if (__pred(((_Node*) __cur->_M_next)->_M_data)) - this->_M_erase_after(__cur); - else - __cur = __cur->_M_next; - } -} - -template <class _Tp, class _Alloc> template <class _BinaryPredicate> -void slist<_Tp,_Alloc>::unique(_BinaryPredicate __pred) -{ - _Node* __cur = (_Node*) this->_M_head._M_next; - if (__cur) { - while (__cur->_M_next) { - if (__pred(((_Node*)__cur)->_M_data, - ((_Node*)(__cur->_M_next))->_M_data)) - this->_M_erase_after(__cur); - else - __cur = (_Node*) __cur->_M_next; - } - } -} - -template <class _Tp, class _Alloc> template <class _StrictWeakOrdering> -void slist<_Tp,_Alloc>::merge(slist<_Tp,_Alloc>& __x, - _StrictWeakOrdering __comp) -{ - _Node_base* __n1 = &this->_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 (__x._M_head._M_next) { - __n1->_M_next = __x._M_head._M_next; - __x._M_head._M_next = 0; - } -} - -template <class _Tp, class _Alloc> template <class _StrictWeakOrdering> -void slist<_Tp,_Alloc>::sort(_StrictWeakOrdering __comp) -{ - if (this->_M_head._M_next && this->_M_head._M_next->_M_next) { - slist __carry; - slist __counter[64]; - int __fill = 0; - while (!empty()) { - __slist_splice_after(&__carry._M_head, - &this->_M_head, this->_M_head._M_next); - int __i = 0; - while (__i < __fill && !__counter[__i].empty()) { - __counter[__i].merge(__carry, __comp); - __carry.swap(__counter[__i]); - ++__i; + insert_iterator<_Container>& + operator=(const typename _Container::value_type& __value) + { + iter = container->insert_after(iter, __value); + return *this; } - __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]); - } -} - -} // namespace __gnu_cxx - -namespace std -{ -// Specialization of insert_iterator so that insertions will be constant -// time rather than linear time. - -template <class _Tp, class _Alloc> -class insert_iterator<__gnu_cxx::slist<_Tp, _Alloc> > { -protected: - typedef __gnu_cxx::slist<_Tp, _Alloc> _Container; - _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) { - if (__i == __x.begin()) - iter = __x.before_begin(); - else - iter = __x.previous(__i); - } + insert_iterator<_Container>& + operator*() + { return *this; } - insert_iterator<_Container>& - operator=(const typename _Container::value_type& __value) { - iter = container->insert_after(iter, __value); - return *this; - } - insert_iterator<_Container>& operator*() { return *this; } - insert_iterator<_Container>& operator++() { return *this; } - insert_iterator<_Container>& operator++(int) { return *this; } -}; + insert_iterator<_Container>& + operator++() + { return *this; } + + insert_iterator<_Container>& + operator++(int) + { return *this; } + }; -} // namespace std +_GLIBCXX_END_NAMESPACE #endif diff --git a/contrib/libstdc++/include/ext/sso_string_base.h b/contrib/libstdc++/include/ext/sso_string_base.h new file mode 100644 index 000000000000..c95b48ecd8d0 --- /dev/null +++ b/contrib/libstdc++/include/ext/sso_string_base.h @@ -0,0 +1,569 @@ +// Short-string-optimized versatile string base -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/** @file ext/sso_string_base.h + * This file is a GNU extension to the Standard C++ Library. + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _SSO_STRING_BASE_H +#define _SSO_STRING_BASE_H 1 + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + template<typename _CharT, typename _Traits, typename _Alloc> + class __sso_string_base + : protected __vstring_utility<_CharT, _Traits, _Alloc> + { + public: + typedef _Traits traits_type; + typedef typename _Traits::char_type value_type; + + typedef __vstring_utility<_CharT, _Traits, _Alloc> _Util_Base; + typedef typename _Util_Base::_CharT_alloc_type _CharT_alloc_type; + typedef typename _CharT_alloc_type::size_type size_type; + + private: + // Data Members: + typename _Util_Base::template _Alloc_hider<_CharT_alloc_type> + _M_dataplus; + size_type _M_string_length; + + enum { _S_local_capacity = 15 }; + + union + { + _CharT _M_local_data[_S_local_capacity + 1]; + size_type _M_allocated_capacity; + }; + + void + _M_data(_CharT* __p) + { _M_dataplus._M_p = __p; } + + void + _M_length(size_type __length) + { _M_string_length = __length; } + + void + _M_capacity(size_type __capacity) + { _M_allocated_capacity = __capacity; } + + bool + _M_is_local() const + { return _M_data() == _M_local_data; } + + // Create & Destroy + _CharT* + _M_create(size_type&, size_type); + + void + _M_dispose() + { + if (!_M_is_local()) + _M_destroy(_M_allocated_capacity); + } + + void + _M_destroy(size_type __size) throw() + { _M_get_allocator().deallocate(_M_data(), __size + 1); } + + // _M_construct_aux is used to implement the 21.3.1 para 15 which + // requires special behaviour if _InIterator is an integral type + template<typename _InIterator> + void + _M_construct_aux(_InIterator __beg, _InIterator __end, + std::__false_type) + { + typedef typename iterator_traits<_InIterator>::iterator_category _Tag; + _M_construct(__beg, __end, _Tag()); + } + + template<typename _InIterator> + void + _M_construct_aux(_InIterator __beg, _InIterator __end, + std::__true_type) + { _M_construct(static_cast<size_type>(__beg), + static_cast<value_type>(__end)); } + + template<typename _InIterator> + void + _M_construct(_InIterator __beg, _InIterator __end) + { + typedef typename std::__is_integer<_InIterator>::__type _Integral; + _M_construct_aux(__beg, __end, _Integral()); + } + + // For Input Iterators, used in istreambuf_iterators, etc. + template<typename _InIterator> + void + _M_construct(_InIterator __beg, _InIterator __end, + std::input_iterator_tag); + + // For forward_iterators up to random_access_iterators, used for + // string::iterator, _CharT*, etc. + template<typename _FwdIterator> + void + _M_construct(_FwdIterator __beg, _FwdIterator __end, + std::forward_iterator_tag); + + void + _M_construct(size_type __req, _CharT __c); + + public: + size_type + _M_max_size() const + { return (_M_get_allocator().max_size() - 1) / 2; } + + _CharT* + _M_data() const + { return _M_dataplus._M_p; } + + size_type + _M_length() const + { return _M_string_length; } + + size_type + _M_capacity() const + { + return _M_is_local() ? size_type(_S_local_capacity) + : _M_allocated_capacity; + } + + bool + _M_is_shared() const + { return false; } + + void + _M_set_leaked() { } + + void + _M_leak() { } + + void + _M_set_length(size_type __n) + { + _M_length(__n); + traits_type::assign(_M_data()[__n], _CharT()); + } + + __sso_string_base() + : _M_dataplus(_Alloc(), _M_local_data) + { _M_set_length(0); } + + __sso_string_base(const _Alloc& __a); + + __sso_string_base(const __sso_string_base& __rcs); + + __sso_string_base(size_type __n, _CharT __c, const _Alloc& __a); + + template<typename _InputIterator> + __sso_string_base(_InputIterator __beg, _InputIterator __end, + const _Alloc& __a); + + ~__sso_string_base() + { _M_dispose(); } + + _CharT_alloc_type& + _M_get_allocator() + { return _M_dataplus; } + + const _CharT_alloc_type& + _M_get_allocator() const + { return _M_dataplus; } + + void + _M_swap(__sso_string_base& __rcs); + + void + _M_assign(const __sso_string_base& __rcs); + + void + _M_reserve(size_type __res); + + void + _M_mutate(size_type __pos, size_type __len1, const _CharT* __s, + size_type __len2); + + void + _M_erase(size_type __pos, size_type __n); + + void + _M_clear() + { _M_set_length(0); } + + bool + _M_compare(const __sso_string_base&) const + { return false; } + }; + + template<typename _CharT, typename _Traits, typename _Alloc> + void + __sso_string_base<_CharT, _Traits, _Alloc>:: + _M_swap(__sso_string_base& __rcs) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 431. Swapping containers with unequal allocators. + std::__alloc_swap<_CharT_alloc_type>::_S_do_it(_M_get_allocator(), + __rcs._M_get_allocator()); + + if (_M_is_local()) + if (__rcs._M_is_local()) + { + if (_M_length() && __rcs._M_length()) + { + _CharT __tmp_data[_S_local_capacity + 1]; + traits_type::copy(__tmp_data, __rcs._M_local_data, + _S_local_capacity + 1); + traits_type::copy(__rcs._M_local_data, _M_local_data, + _S_local_capacity + 1); + traits_type::copy(_M_local_data, __tmp_data, + _S_local_capacity + 1); + } + else if (__rcs._M_length()) + { + traits_type::copy(_M_local_data, __rcs._M_local_data, + _S_local_capacity + 1); + _M_length(__rcs._M_length()); + __rcs._M_set_length(0); + return; + } + else if (_M_length()) + { + traits_type::copy(__rcs._M_local_data, _M_local_data, + _S_local_capacity + 1); + __rcs._M_length(_M_length()); + _M_set_length(0); + return; + } + } + else + { + const size_type __tmp_capacity = __rcs._M_allocated_capacity; + traits_type::copy(__rcs._M_local_data, _M_local_data, + _S_local_capacity + 1); + _M_data(__rcs._M_data()); + __rcs._M_data(__rcs._M_local_data); + _M_capacity(__tmp_capacity); + } + else + { + const size_type __tmp_capacity = _M_allocated_capacity; + if (__rcs._M_is_local()) + { + traits_type::copy(_M_local_data, __rcs._M_local_data, + _S_local_capacity + 1); + __rcs._M_data(_M_data()); + _M_data(_M_local_data); + } + else + { + _CharT* __tmp_ptr = _M_data(); + _M_data(__rcs._M_data()); + __rcs._M_data(__tmp_ptr); + _M_capacity(__rcs._M_allocated_capacity); + } + __rcs._M_capacity(__tmp_capacity); + } + + const size_type __tmp_length = _M_length(); + _M_length(__rcs._M_length()); + __rcs._M_length(__tmp_length); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + _CharT* + __sso_string_base<_CharT, _Traits, _Alloc>:: + _M_create(size_type& __capacity, size_type __old_capacity) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 83. String::npos vs. string::max_size() + if (__capacity > _M_max_size()) + std::__throw_length_error(__N("__sso_string_base::_M_create")); + + // The below implements an exponential growth policy, necessary to + // meet amortized linear time requirements of the library: see + // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html. + if (__capacity > __old_capacity && __capacity < 2 * __old_capacity) + { + __capacity = 2 * __old_capacity; + // Never allocate a string bigger than max_size. + if (__capacity > _M_max_size()) + __capacity = _M_max_size(); + } + + // NB: Need an array of char_type[__capacity], plus a terminating + // null char_type() element. + return _M_get_allocator().allocate(__capacity + 1); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + __sso_string_base<_CharT, _Traits, _Alloc>:: + __sso_string_base(const _Alloc& __a) + : _M_dataplus(__a, _M_local_data) + { _M_set_length(0); } + + template<typename _CharT, typename _Traits, typename _Alloc> + __sso_string_base<_CharT, _Traits, _Alloc>:: + __sso_string_base(const __sso_string_base& __rcs) + : _M_dataplus(__rcs._M_get_allocator(), _M_local_data) + { _M_construct(__rcs._M_data(), __rcs._M_data() + __rcs._M_length()); } + + template<typename _CharT, typename _Traits, typename _Alloc> + __sso_string_base<_CharT, _Traits, _Alloc>:: + __sso_string_base(size_type __n, _CharT __c, const _Alloc& __a) + : _M_dataplus(__a, _M_local_data) + { _M_construct(__n, __c); } + + template<typename _CharT, typename _Traits, typename _Alloc> + template<typename _InputIterator> + __sso_string_base<_CharT, _Traits, _Alloc>:: + __sso_string_base(_InputIterator __beg, _InputIterator __end, + const _Alloc& __a) + : _M_dataplus(__a, _M_local_data) + { _M_construct(__beg, __end); } + + // NB: This is the special case for Input Iterators, used in + // istreambuf_iterators, etc. + // Input Iterators have a cost structure very different from + // pointers, calling for a different coding style. + template<typename _CharT, typename _Traits, typename _Alloc> + template<typename _InIterator> + void + __sso_string_base<_CharT, _Traits, _Alloc>:: + _M_construct(_InIterator __beg, _InIterator __end, + std::input_iterator_tag) + { + size_type __len = 0; + size_type __capacity = size_type(_S_local_capacity); + + while (__beg != __end && __len < __capacity) + { + _M_data()[__len++] = *__beg; + ++__beg; + } + + try + { + while (__beg != __end) + { + if (__len == __capacity) + { + // Allocate more space. + __capacity = __len + 1; + _CharT* __another = _M_create(__capacity, __len); + _S_copy(__another, _M_data(), __len); + _M_dispose(); + _M_data(__another); + _M_capacity(__capacity); + } + _M_data()[__len++] = *__beg; + ++__beg; + } + } + catch(...) + { + _M_dispose(); + __throw_exception_again; + } + + _M_set_length(__len); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + template<typename _InIterator> + void + __sso_string_base<_CharT, _Traits, _Alloc>:: + _M_construct(_InIterator __beg, _InIterator __end, + std::forward_iterator_tag) + { + // NB: Not required, but considered best practice. + if (__builtin_expect(_S_is_null_pointer(__beg) && __beg != __end, 0)) + std::__throw_logic_error(__N("__sso_string_base::" + "_M_construct NULL not valid")); + + size_type __dnew = static_cast<size_type>(std::distance(__beg, __end)); + + if (__dnew > size_type(_S_local_capacity)) + { + _M_data(_M_create(__dnew, size_type(0))); + _M_capacity(__dnew); + } + + // Check for out_of_range and length_error exceptions. + try + { _S_copy_chars(_M_data(), __beg, __end); } + catch(...) + { + _M_dispose(); + __throw_exception_again; + } + + _M_set_length(__dnew); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + __sso_string_base<_CharT, _Traits, _Alloc>:: + _M_construct(size_type __n, _CharT __c) + { + if (__n > size_type(_S_local_capacity)) + { + _M_data(_M_create(__n, size_type(0))); + _M_capacity(__n); + } + + if (__n) + _S_assign(_M_data(), __n, __c); + + _M_set_length(__n); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + __sso_string_base<_CharT, _Traits, _Alloc>:: + _M_assign(const __sso_string_base& __rcs) + { + if (this != &__rcs) + { + const size_type __rsize = __rcs._M_length(); + const size_type __capacity = _M_capacity(); + + if (__rsize > __capacity) + { + size_type __new_capacity = __rsize; + _CharT* __tmp = _M_create(__new_capacity, __capacity); + _M_dispose(); + _M_data(__tmp); + _M_capacity(__new_capacity); + } + + if (__rsize) + _S_copy(_M_data(), __rcs._M_data(), __rsize); + + _M_set_length(__rsize); + } + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + __sso_string_base<_CharT, _Traits, _Alloc>:: + _M_reserve(size_type __res) + { + // Make sure we don't shrink below the current size. + if (__res < _M_length()) + __res = _M_length(); + + const size_type __capacity = _M_capacity(); + if (__res != __capacity) + { + if (__res > __capacity + || __res > size_type(_S_local_capacity)) + { + _CharT* __tmp = _M_create(__res, __capacity); + _S_copy(__tmp, _M_data(), _M_length() + 1); + _M_dispose(); + _M_data(__tmp); + _M_capacity(__res); + } + else if (!_M_is_local()) + { + _S_copy(_M_local_data, _M_data(), _M_length() + 1); + _M_destroy(__capacity); + _M_data(_M_local_data); + } + } + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + __sso_string_base<_CharT, _Traits, _Alloc>:: + _M_mutate(size_type __pos, size_type __len1, const _CharT* __s, + const size_type __len2) + { + const size_type __how_much = _M_length() - __pos - __len1; + + size_type __new_capacity = _M_length() + __len2 - __len1; + _CharT* __r = _M_create(__new_capacity, _M_capacity()); + + if (__pos) + _S_copy(__r, _M_data(), __pos); + if (__s && __len2) + _S_copy(__r + __pos, __s, __len2); + if (__how_much) + _S_copy(__r + __pos + __len2, + _M_data() + __pos + __len1, __how_much); + + _M_dispose(); + _M_data(__r); + _M_capacity(__new_capacity); + } + + template<typename _CharT, typename _Traits, typename _Alloc> + void + __sso_string_base<_CharT, _Traits, _Alloc>:: + _M_erase(size_type __pos, size_type __n) + { + const size_type __how_much = _M_length() - __pos - __n; + + if (__how_much && __n) + _S_move(_M_data() + __pos, _M_data() + __pos + __n, + __how_much); + + _M_set_length(_M_length() - __n); + } + + template<> + inline bool + __sso_string_base<char, std::char_traits<char>, + std::allocator<char> >:: + _M_compare(const __sso_string_base& __rcs) const + { + if (this == &__rcs) + return true; + return false; + } + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + inline bool + __sso_string_base<wchar_t, std::char_traits<wchar_t>, + std::allocator<wchar_t> >:: + _M_compare(const __sso_string_base& __rcs) const + { + if (this == &__rcs) + return true; + return false; + } +#endif + +_GLIBCXX_END_NAMESPACE + +#endif /* _SSO_STRING_BASE_H */ diff --git a/contrib/libstdc++/include/ext/stdio_filebuf.h b/contrib/libstdc++/include/ext/stdio_filebuf.h index cc229728fa8a..312a21771110 100644 --- a/contrib/libstdc++/include/ext/stdio_filebuf.h +++ b/contrib/libstdc++/include/ext/stdio_filebuf.h @@ -1,6 +1,6 @@ // File descriptor layer for filebuf -*- C++ -*- -// Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. +// Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -15,7 +15,7 @@ // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, // USA. // As a special exception, you may use this file as part of a free software @@ -38,10 +38,9 @@ #include <fstream> -namespace __gnu_cxx -{ +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + /** - * @class stdio_filebuf ext/stdio_filebuf.h <ext/stdio_filebuf.h> * @brief Provides a layer of compatibility for C/POSIX. * * This GNU extension provides extensions for working with standard C @@ -157,6 +156,7 @@ namespace __gnu_cxx this->_M_set_buffer(-1); } } -} // namespace __gnu_cxx + +_GLIBCXX_END_NAMESPACE #endif diff --git a/contrib/libstdc++/include/ext/stdio_sync_filebuf.h b/contrib/libstdc++/include/ext/stdio_sync_filebuf.h index 367d310b4b04..f0ec12c3a695 100644 --- a/contrib/libstdc++/include/ext/stdio_sync_filebuf.h +++ b/contrib/libstdc++/include/ext/stdio_sync_filebuf.h @@ -1,6 +1,6 @@ // Iostreams wrapper for stdio FILE* -*- C++ -*- -// Copyright (C) 2003, 2004 Free Software Foundation, Inc. +// Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -15,7 +15,7 @@ // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, // USA. // As a special exception, you may use this file as part of a free software @@ -27,7 +27,7 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -/** @file ext/stdiostream.h +/** @file ext/stdio_sync_filebuf.h * This file is a GNU extension to the Standard C++ Library. */ @@ -44,8 +44,9 @@ #include <cwchar> #endif -namespace __gnu_cxx -{ +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + /// @brief class stdio_sync_filebuf. template<typename _CharT, typename _Traits = std::char_traits<_CharT> > class stdio_sync_filebuf : public std::basic_streambuf<_CharT, _Traits> { @@ -276,6 +277,7 @@ namespace __gnu_cxx extern template class stdio_sync_filebuf<wchar_t>; #endif #endif -} // namespace __gnu_cxx + +_GLIBCXX_END_NAMESPACE #endif diff --git a/contrib/libstdc++/include/ext/throw_allocator.h b/contrib/libstdc++/include/ext/throw_allocator.h new file mode 100644 index 000000000000..112fb739d705 --- /dev/null +++ b/contrib/libstdc++/include/ext/throw_allocator.h @@ -0,0 +1,426 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 59 Temple Place - Suite 330, Boston, +// MA 02111-1307, USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice +// and this permission notice appear in supporting documentation. None +// of the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied +// warranty. + +/** @file ext/vstring.h + * This file is a GNU extension to the Standard C++ Library. + * + * Contains an exception-throwing allocator, useful for testing + * exception safety. In addition, allocation addresses are stored and + * sanity checked. + */ + +/** + * @file throw_allocator.h + */ + +#ifndef _THROW_ALLOCATOR_H +#define _THROW_ALLOCATOR_H 1 + +#include <cmath> +#include <map> +#include <set> +#include <string> +#include <ostream> +#include <stdexcept> +#include <utility> +#include <tr1/random> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + class twister_rand_gen + { + public: + twister_rand_gen(unsigned int seed = + static_cast<unsigned int>(std::time(0))); + + void + init(unsigned int); + + double + get_prob(); + + private: + std::tr1::mt19937 _M_generator; + }; + + + struct forced_exception_error : public std::exception + { }; + + class throw_allocator_base + { + public: + void + init(unsigned long seed); + + static void + set_throw_prob(double throw_prob); + + static double + get_throw_prob(); + + static void + set_label(size_t l); + + static bool + empty(); + + struct group_throw_prob_adjustor + { + group_throw_prob_adjustor(size_t size) + : _M_throw_prob_orig(_S_throw_prob) + { + _S_throw_prob = + 1 - ::pow(double(1 - _S_throw_prob), double(0.5 / (size + 1))); + } + + ~group_throw_prob_adjustor() + { _S_throw_prob = _M_throw_prob_orig; } + + private: + const double _M_throw_prob_orig; + }; + + struct zero_throw_prob_adjustor + { + zero_throw_prob_adjustor() : _M_throw_prob_orig(_S_throw_prob) + { _S_throw_prob = 0; } + + ~zero_throw_prob_adjustor() + { _S_throw_prob = _M_throw_prob_orig; } + + private: + const double _M_throw_prob_orig; + }; + + protected: + static void + insert(void*, size_t); + + static void + erase(void*, size_t); + + static void + throw_conditionally(); + + // See if a particular address and size has been allocated by this + // allocator. + static void + check_allocated(void*, size_t); + + // See if a given label has been allocated by this allocator. + static void + check_allocated(size_t); + + private: + typedef std::pair<size_t, size_t> alloc_data_type; + typedef std::map<void*, alloc_data_type> map_type; + typedef map_type::value_type entry_type; + typedef map_type::const_iterator const_iterator; + typedef map_type::const_reference const_reference; + + friend std::ostream& + operator<<(std::ostream&, const throw_allocator_base&); + + static entry_type + make_entry(void*, size_t); + + static void + print_to_string(std::string&); + + static void + print_to_string(std::string&, const_reference); + + static twister_rand_gen _S_g; + static map_type _S_map; + static double _S_throw_prob; + static size_t _S_label; + }; + + + template<typename T> + class throw_allocator : public throw_allocator_base + { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef T value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + + + template<typename U> + struct rebind + { + typedef throw_allocator<U> other; + }; + + throw_allocator() throw() { } + + throw_allocator(const throw_allocator&) throw() { } + + template<typename U> + throw_allocator(const throw_allocator<U>&) throw() { } + + ~throw_allocator() throw() { } + + size_type + max_size() const throw() + { return std::allocator<value_type>().max_size(); } + + pointer + allocate(size_type num, std::allocator<void>::const_pointer hint = 0) + { + throw_conditionally(); + value_type* const a = std::allocator<value_type>().allocate(num, hint); + insert(a, sizeof(value_type) * num); + return a; + } + + void + construct(pointer p, const T& val) + { return std::allocator<value_type>().construct(p, val); } + + void + destroy(pointer p) + { std::allocator<value_type>().destroy(p); } + + void + deallocate(pointer p, size_type num) + { + erase(p, sizeof(value_type) * num); + std::allocator<value_type>().deallocate(p, num); + } + + void + check_allocated(pointer p, size_type num) + { throw_allocator_base::check_allocated(p, sizeof(value_type) * num); } + + void + check_allocated(size_type label) + { throw_allocator_base::check_allocated(label); } + }; + + template<typename T> + inline bool + operator==(const throw_allocator<T>&, const throw_allocator<T>&) + { return true; } + + template<typename T> + inline bool + operator!=(const throw_allocator<T>&, const throw_allocator<T>&) + { return false; } + + std::ostream& + operator<<(std::ostream& os, const throw_allocator_base& alloc) + { + std::string error; + throw_allocator_base::print_to_string(error); + os << error; + return os; + } + + // XXX Should be in .cc. + twister_rand_gen:: + twister_rand_gen(unsigned int seed) : _M_generator(seed) { } + + void + twister_rand_gen:: + init(unsigned int seed) + { _M_generator.seed(seed); } + + double + twister_rand_gen:: + get_prob() + { + const double eng_min = _M_generator.min(); + const double eng_range = + static_cast<const double>(_M_generator.max() - eng_min); + + const double eng_res = + static_cast<const double>(_M_generator() - eng_min); + + const double ret = eng_res / eng_range; + _GLIBCXX_DEBUG_ASSERT(ret >= 0 && ret <= 1); + return ret; + } + + twister_rand_gen throw_allocator_base::_S_g; + + throw_allocator_base::map_type + throw_allocator_base::_S_map; + + double throw_allocator_base::_S_throw_prob; + + size_t throw_allocator_base::_S_label = 0; + + throw_allocator_base::entry_type + throw_allocator_base::make_entry(void* p, size_t size) + { return std::make_pair(p, alloc_data_type(_S_label, size)); } + + void + throw_allocator_base::init(unsigned long seed) + { _S_g.init(seed); } + + void + throw_allocator_base::set_throw_prob(double throw_prob) + { _S_throw_prob = throw_prob; } + + double + throw_allocator_base::get_throw_prob() + { return _S_throw_prob; } + + void + throw_allocator_base::set_label(size_t l) + { _S_label = l; } + + void + throw_allocator_base::insert(void* p, size_t size) + { + const_iterator found_it = _S_map.find(p); + if (found_it != _S_map.end()) + { + std::string error("throw_allocator_base::insert"); + error += "double insert!"; + error += '\n'; + print_to_string(error, make_entry(p, size)); + print_to_string(error, *found_it); + throw std::logic_error(error); + } + _S_map.insert(make_entry(p, size)); + } + + bool + throw_allocator_base::empty() + { return _S_map.empty(); } + + void + throw_allocator_base::erase(void* p, size_t size) + { + check_allocated(p, size); + _S_map.erase(p); + } + + void + throw_allocator_base::check_allocated(void* p, size_t size) + { + const_iterator found_it = _S_map.find(p); + if (found_it == _S_map.end()) + { + std::string error("throw_allocator_base::check_allocated by value "); + error += "null erase!"; + error += '\n'; + print_to_string(error, make_entry(p, size)); + throw std::logic_error(error); + } + + if (found_it->second.second != size) + { + std::string error("throw_allocator_base::check_allocated by value "); + error += "wrong-size erase!"; + error += '\n'; + print_to_string(error, make_entry(p, size)); + print_to_string(error, *found_it); + throw std::logic_error(error); + } + } + + void + throw_allocator_base::check_allocated(size_t label) + { + std::string found; + const_iterator it = _S_map.begin(); + while (it != _S_map.end()) + { + if (it->second.first == label) + print_to_string(found, *it); + ++it; + } + + if (!found.empty()) + { + std::string error("throw_allocator_base::check_allocated by label "); + error += '\n'; + error += found; + throw std::logic_error(error); + } + } + + void + throw_allocator_base::throw_conditionally() + { + if (_S_g.get_prob() < _S_throw_prob) + throw forced_exception_error(); + } + + void + throw_allocator_base::print_to_string(std::string& s) + { + const_iterator begin = throw_allocator_base::_S_map.begin(); + const_iterator end = throw_allocator_base::_S_map.end(); + for (; begin != end; ++begin) + print_to_string(s, *begin); + } + + void + throw_allocator_base::print_to_string(std::string& s, const_reference ref) + { + char buf[40]; + const char tab('\t'); + s += "address: "; + sprintf(buf, "%p", ref.first); + s += buf; + s += tab; + s += "label: "; + sprintf(buf, "%u", ref.second.first); + s += buf; + s += tab; + s += "size: "; + sprintf(buf, "%u", ref.second.second); + s += buf; + s += '\n'; + } + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/contrib/libstdc++/include/ext/type_traits.h b/contrib/libstdc++/include/ext/type_traits.h new file mode 100644 index 000000000000..31a7e9bddebc --- /dev/null +++ b/contrib/libstdc++/include/ext/type_traits.h @@ -0,0 +1,153 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later +// version. + +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +/** @file ext/type_traits.h + * This file is a GNU extension to the Standard C++ Library. + */ + +#ifndef _EXT_TYPE_TRAITS +#define _EXT_TYPE_TRAITS 1 + +#pragma GCC system_header + +#include <cstddef> +#include <utility> +#include <bits/cpp_type_traits.h> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + // Define a nested type if some predicate holds. + template<bool, typename> + struct __enable_if + { }; + + template<typename _Tp> + struct __enable_if<true, _Tp> + { typedef _Tp __type; }; + + + // Conditional expression for types. If true, first, if false, second. + template<bool _Cond, typename _Iftrue, typename _Iffalse> + struct __conditional_type + { typedef _Iftrue __type; }; + + template<typename _Iftrue, typename _Iffalse> + struct __conditional_type<false, _Iftrue, _Iffalse> + { typedef _Iffalse __type; }; + + + // Given an integral builtin type, return the corresponding unsigned type. + template<typename _Tp> + struct __add_unsigned + { + private: + typedef __enable_if<std::__is_integer<_Tp>::__value, _Tp> __if_type; + + public: + typedef typename __if_type::__type __type; + }; + + template<> + struct __add_unsigned<char> + { typedef unsigned char __type; }; + + template<> + struct __add_unsigned<signed char> + { typedef unsigned char __type; }; + + template<> + struct __add_unsigned<short> + { typedef unsigned short __type; }; + + template<> + struct __add_unsigned<int> + { typedef unsigned int __type; }; + + template<> + struct __add_unsigned<long> + { typedef unsigned long __type; }; + + template<> + struct __add_unsigned<long long> + { typedef unsigned long long __type; }; + + // Declare but don't define. + template<> + struct __add_unsigned<bool>; + + template<> + struct __add_unsigned<wchar_t>; + + + // Given an integral builtin type, return the corresponding signed type. + template<typename _Tp> + struct __remove_unsigned + { + private: + typedef __enable_if<std::__is_integer<_Tp>::__value, _Tp> __if_type; + + public: + typedef typename __if_type::__type __type; + }; + + template<> + struct __remove_unsigned<char> + { typedef signed char __type; }; + + template<> + struct __remove_unsigned<unsigned char> + { typedef signed char __type; }; + + template<> + struct __remove_unsigned<unsigned short> + { typedef short __type; }; + + template<> + struct __remove_unsigned<unsigned int> + { typedef int __type; }; + + template<> + struct __remove_unsigned<unsigned long> + { typedef long __type; }; + + template<> + struct __remove_unsigned<unsigned long long> + { typedef long long __type; }; + + // Declare but don't define. + template<> + struct __remove_unsigned<bool>; + + template<> + struct __remove_unsigned<wchar_t>; + +_GLIBCXX_END_NAMESPACE + +#endif diff --git a/contrib/libstdc++/include/ext/typelist.h b/contrib/libstdc++/include/ext/typelist.h new file mode 100644 index 000000000000..1c99783923d6 --- /dev/null +++ b/contrib/libstdc++/include/ext/typelist.h @@ -0,0 +1,473 @@ +// -*- C++ -*- + +// Copyright (C) 2005, 2006 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. + +// Permission to use, copy, modify, sell, and distribute this software +// is hereby granted without fee, provided that the above copyright +// notice appears in all copies, and that both that copyright notice and +// this permission notice appear in supporting documentation. None of +// the above authors, nor IBM Haifa Research Laboratories, make any +// representation about the suitability of this software for any +// purpose. It is provided "as is" without express or implied warranty. + +/** + * @file typelist.h + * Contains typelist_chain definitions. + * Typelists are an idea by Andrei Alexandrescu. + */ + +#ifndef _TYPELIST_H +#define _TYPELIST_H 1 + +#include <ext/type_traits.h> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + +namespace typelist +{ + struct null_type { }; + + template<typename Root> + struct node + { + typedef Root root; + }; + + // Forward declarations of functors. + template<typename Hd, typename Typelist> + struct chain + { + typedef Hd head; + typedef Typelist tail; + }; + + template<typename Fn, class Typelist> + void + apply(Fn&, Typelist); + + template<typename Typelist0, typename Typelist1> + struct append; + + template<typename Typelist_Typelist> + struct append_typelist; + + template<typename Typelist, typename T> + struct contains; + + template<typename Typelist, template<typename T> class Pred> + struct filter; + + template<typename Typelist, int i> + struct at_index; + + template<typename Typelist, template<typename T> class Transform> + struct transform; + + template<typename Typelist_Typelist> + struct flatten; + + template<typename Typelist> + struct from_first; + + template<typename T1> + struct create1; + + template<typename T1, typename T2> + struct create2; + + template<typename T1, typename T2, typename T3> + struct create3; + + template<typename T1, typename T2, typename T3, typename T4> + struct create4; + + template<typename T1, typename T2, typename T3, typename T4, typename T5> + struct create5; + + template<typename T1, typename T2, typename T3, + typename T4, typename T5, typename T6> + struct create6; +} // namespace typelist + +_GLIBCXX_END_NAMESPACE + + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + +namespace typelist +{ +namespace detail +{ + template<typename Fn, typename Typelist_Chain> + struct apply_; + + template<typename Fn, typename Hd, typename Tl> + struct apply_<Fn, chain<Hd, Tl> > + { + void + operator() (Fn& f) + { + f.operator()(Hd()); + apply_<Fn, Tl> next; + next(f); + } + }; + + template<typename Fn> + struct apply_<Fn, null_type> + { + void + operator()(Fn&) { } + }; + + template<typename Typelist_Chain0, typename Typelist_Chain1> + struct append_; + + template<typename Hd, typename Tl, typename Typelist_Chain> + struct append_<chain<Hd, Tl>, Typelist_Chain> + { + private: + typedef append_<Tl, Typelist_Chain> append_type; + + public: + typedef chain<Hd, typename append_type::type> type; + }; + + template<typename Typelist_Chain> + struct append_<null_type, Typelist_Chain> + { + typedef Typelist_Chain type; + }; + + template<typename Typelist_Chain> + struct append_<Typelist_Chain, null_type> + { + typedef Typelist_Chain type; + }; + + template<> + struct append_<null_type, null_type> + { + typedef null_type type; + }; + + template<typename Typelist_Typelist_Chain> + struct append_typelist_; + + template<typename Hd> + struct append_typelist_<chain<Hd, null_type> > + { + typedef chain<Hd, null_type> type; + }; + + template<typename Hd, typename Tl> + struct append_typelist_<chain< Hd, Tl> > + { + private: + typedef typename append_typelist_<Tl>::type rest_type; + + public: + typedef typename append<Hd, node<rest_type> >::type::root type; + }; + + template<typename Typelist_Chain, typename T> + struct contains_; + + template<typename T> + struct contains_<null_type, T> + { + enum + { + value = false + }; + }; + + template<typename Hd, typename Tl, typename T> + struct contains_<chain<Hd, Tl>, T> + { + enum + { + value = contains_<Tl, T>::value + }; + }; + + template<typename Tl, typename T> + struct contains_<chain<T, Tl>, T> + { + enum + { + value = true + }; + }; + + template<typename Typelist_Chain, template<typename T> class Pred> + struct chain_filter_; + + template<template<typename T> class Pred> + struct chain_filter_<null_type, Pred> + { + typedef null_type type; + }; + + template<typename Hd, typename Tl, template<typename T> class Pred> + struct chain_filter_<chain<Hd, Tl>, Pred> + { + private: + enum + { + include_hd = Pred<Hd>::value + }; + + typedef typename chain_filter_<Tl, Pred>::type rest_type; + typedef chain<Hd, rest_type> chain_type; + + public: + typedef typename __conditional_type<include_hd, chain_type, rest_type>::__type type; + }; + + template<typename Typelist_Chain, int i> + struct chain_at_index_; + + template<typename Hd, typename Tl> + struct chain_at_index_<chain<Hd, Tl>, 0> + { + typedef Hd type; + }; + + template<typename Hd, typename Tl, int i> + struct chain_at_index_<chain<Hd, Tl>, i> + { + typedef typename chain_at_index_<Tl, i - 1>::type type; + }; + + template<class Typelist_Chain, template<typename T> class Transform> + struct chain_transform_; + + template<template<typename T> class Transform> + struct chain_transform_<null_type, Transform> + { + typedef null_type type; + }; + + template<class Hd, class Tl, template<typename T> class Transform> + struct chain_transform_<chain<Hd, Tl>, Transform> + { + private: + typedef typename chain_transform_<Tl, Transform>::type rest_type; + typedef typename Transform<Hd>::type transform_type; + + public: + typedef chain<transform_type, rest_type> type; + }; + + template<typename Typelist_Typelist_Chain> + struct chain_flatten_; + + template<typename Hd_Tl> + struct chain_flatten_<chain<Hd_Tl, null_type> > + { + typedef typename Hd_Tl::root type; + }; + + template<typename Hd_Typelist, class Tl_Typelist> + struct chain_flatten_<chain<Hd_Typelist, Tl_Typelist> > + { + private: + typedef typename chain_flatten_<Tl_Typelist>::type rest_type; + typedef append<Hd_Typelist, node<rest_type> > append_type; + public: + typedef typename append_type::type::root type; + }; +} // namespace detail +} // namespace typelist + +_GLIBCXX_END_NAMESPACE + +#define _GLIBCXX_TYPELIST_CHAIN1(X0) __gnu_cxx::typelist::chain<X0, __gnu_cxx::typelist::null_type> +#define _GLIBCXX_TYPELIST_CHAIN2(X0, X1) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN1(X1) > +#define _GLIBCXX_TYPELIST_CHAIN3(X0, X1, X2) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN2(X1, X2) > +#define _GLIBCXX_TYPELIST_CHAIN4(X0, X1, X2, X3) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN3(X1, X2, X3) > +#define _GLIBCXX_TYPELIST_CHAIN5(X0, X1, X2, X3, X4) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN4(X1, X2, X3, X4) > +#define _GLIBCXX_TYPELIST_CHAIN6(X0, X1, X2, X3, X4, X5) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN5(X1, X2, X3, X4, X5) > +#define _GLIBCXX_TYPELIST_CHAIN7(X0, X1, X2, X3, X4, X5, X6) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN6(X1, X2, X3, X4, X5, X6) > +#define _GLIBCXX_TYPELIST_CHAIN8(X0, X1, X2, X3, X4, X5, X6, X7) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN7(X1, X2, X3, X4, X5, X6, X7) > +#define _GLIBCXX_TYPELIST_CHAIN9(X0, X1, X2, X3, X4, X5, X6, X7, X8) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN8(X1, X2, X3, X4, X5, X6, X7, X8) > +#define _GLIBCXX_TYPELIST_CHAIN10(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN9(X1, X2, X3, X4, X5, X6, X7, X8, X9) > +#define _GLIBCXX_TYPELIST_CHAIN11(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN10(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10) > +#define _GLIBCXX_TYPELIST_CHAIN12(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN11(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11) > +#define _GLIBCXX_TYPELIST_CHAIN13(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN12(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12) > +#define _GLIBCXX_TYPELIST_CHAIN14(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN13(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13) > +#define _GLIBCXX_TYPELIST_CHAIN15(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN14(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14) > + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + +namespace typelist +{ + template<typename Fn, class Typelist> + void + apply(Fn& fn, Typelist) + { + detail::apply_<Fn, typename Typelist::root> a; + a(fn); + } + + template<typename Typelist0, typename Typelist1> + struct append + { + private: + typedef typename Typelist0::root root0_type; + typedef typename Typelist1::root root1_type; + typedef detail::append_<root0_type, root1_type> append_type; + + public: + typedef node<typename append_type::type> type; + }; + + template<typename Typelist_Typelist> + struct append_typelist + { + private: + typedef typename Typelist_Typelist::root root_type; + typedef detail::append_typelist_<root_type> append_type; + + public: + typedef node<typename append_type::type> type; + }; + + template<typename Typelist, typename T> + struct contains + { + private: + typedef typename Typelist::root root_type; + + public: + enum + { + value = detail::contains_<root_type, T>::value + }; + }; + + template<typename Typelist, template<typename T> class Pred> + struct filter + { + private: + typedef typename Typelist::root root_type; + typedef detail::chain_filter_<root_type, Pred> filter_type; + + public: + typedef node<typename filter_type::type> type; + }; + + template<typename Typelist, int i> + struct at_index + { + private: + typedef typename Typelist::root root_type; + typedef detail::chain_at_index_<root_type, i> index_type; + + public: + typedef typename index_type::type type; + }; + + template<typename Typelist, template<typename T> class Transform> + struct transform + { + private: + typedef typename Typelist::root root_type; + typedef detail::chain_transform_<root_type, Transform> transform_type; + + public: + typedef node<typename transform_type::type> type; + }; + + template<typename Typelist_Typelist> + struct flatten + { + private: + typedef typename Typelist_Typelist::root root_type; + typedef typename detail::chain_flatten_<root_type>::type flatten_type; + + public: + typedef node<flatten_type> type; + }; + + template<typename Typelist> + struct from_first + { + private: + typedef typename at_index<Typelist, 0>::type first_type; + + public: + typedef node<chain<first_type, null_type> > type; + }; + + template<typename T1> + struct create1 + { + typedef node<_GLIBCXX_TYPELIST_CHAIN1(T1)> type; + }; + + template<typename T1, typename T2> + struct create2 + { + typedef node<_GLIBCXX_TYPELIST_CHAIN2(T1,T2)> type; + }; + + template<typename T1, typename T2, typename T3> + struct create3 + { + typedef node<_GLIBCXX_TYPELIST_CHAIN3(T1,T2,T3)> type; + }; + + template<typename T1, typename T2, typename T3, typename T4> + struct create4 + { + typedef node<_GLIBCXX_TYPELIST_CHAIN4(T1,T2,T3,T4)> type; + }; + + template<typename T1, typename T2, typename T3, + typename T4, typename T5> + struct create5 + { + typedef node<_GLIBCXX_TYPELIST_CHAIN5(T1,T2,T3,T4,T5)> type; + }; + + template<typename T1, typename T2, typename T3, + typename T4, typename T5, typename T6> + struct create6 + { + typedef node<_GLIBCXX_TYPELIST_CHAIN6(T1,T2,T3,T4,T5,T6)> type; + }; +} // namespace typelist +_GLIBCXX_END_NAMESPACE + + +#endif + diff --git a/contrib/libstdc++/include/ext/vstring.h b/contrib/libstdc++/include/ext/vstring.h new file mode 100644 index 000000000000..79265b9cc6db --- /dev/null +++ b/contrib/libstdc++/include/ext/vstring.h @@ -0,0 +1,2198 @@ +// Versatile string -*- C++ -*- + +// Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/** @file ext/vstring.h + * This file is a GNU extension to the Standard C++ Library. + */ + +#ifndef _VSTRING_H +#define _VSTRING_H 1 + +#pragma GCC system_header + +#include <ext/vstring_util.h> +#include <ext/rc_string_base.h> +#include <ext/sso_string_base.h> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + /** + * @class __versa_string vstring.h + * @brief Managing sequences of characters and character-like objects. + */ + + // Template class __versa_string + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + class __versa_string + : private _Base<_CharT, _Traits, _Alloc> + { + typedef _Base<_CharT, _Traits, _Alloc> __vstring_base; + typedef typename __vstring_base::_CharT_alloc_type _CharT_alloc_type; + + // Types: + public: + typedef _Traits traits_type; + typedef typename _Traits::char_type value_type; + typedef _Alloc allocator_type; + typedef typename _CharT_alloc_type::size_type size_type; + typedef typename _CharT_alloc_type::difference_type difference_type; + typedef typename _CharT_alloc_type::reference reference; + typedef typename _CharT_alloc_type::const_reference const_reference; + typedef typename _CharT_alloc_type::pointer pointer; + typedef typename _CharT_alloc_type::const_pointer const_pointer; + typedef __gnu_cxx::__normal_iterator<pointer, __versa_string> iterator; + typedef __gnu_cxx::__normal_iterator<const_pointer, __versa_string> + const_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + typedef std::reverse_iterator<iterator> reverse_iterator; + + // Data Member (public): + /// Value returned by various member functions when they fail. + static const size_type npos = static_cast<size_type>(-1); + + private: + size_type + _M_check(size_type __pos, const char* __s) const + { + if (__pos > this->size()) + std::__throw_out_of_range(__N(__s)); + return __pos; + } + + void + _M_check_length(size_type __n1, size_type __n2, const char* __s) const + { + if (this->max_size() - (this->size() - __n1) < __n2) + std::__throw_length_error(__N(__s)); + } + + // NB: _M_limit doesn't check for a bad __pos value. + size_type + _M_limit(size_type __pos, size_type __off) const + { + const bool __testoff = __off < this->size() - __pos; + return __testoff ? __off : this->size() - __pos; + } + + // True if _Rep and source do not overlap. + bool + _M_disjunct(const _CharT* __s) const + { + return (std::less<const _CharT*>()(__s, this->_M_data()) + || std::less<const _CharT*>()(this->_M_data() + + this->size(), __s)); + } + + // For the internal use we have functions similar to `begin'/`end' + // but they do not call _M_leak. + iterator + _M_ibegin() const + { return iterator(this->_M_data()); } + + iterator + _M_iend() const + { return iterator(this->_M_data() + this->_M_length()); } + + public: + // Construct/copy/destroy: + // NB: We overload ctors in some cases instead of using default + // arguments, per 17.4.4.4 para. 2 item 2. + + /** + * @brief Default constructor creates an empty string. + */ + __versa_string() + : __vstring_base() { } + + /** + * @brief Construct an empty string using allocator @a a. + */ + explicit + __versa_string(const _Alloc& __a) + : __vstring_base(__a) { } + + // NB: per LWG issue 42, semantics different from IS: + /** + * @brief Construct string with copy of value of @a str. + * @param str Source string. + */ + __versa_string(const __versa_string& __str) + : __vstring_base(__str) { } + + /** + * @brief Construct string as copy of a substring. + * @param str Source string. + * @param pos Index of first character to copy from. + * @param n Number of characters to copy (default remainder). + */ + __versa_string(const __versa_string& __str, size_type __pos, + size_type __n = npos) + : __vstring_base(__str._M_data() + + __str._M_check(__pos, + "__versa_string::__versa_string"), + __str._M_data() + __str._M_limit(__pos, __n) + + __pos, _Alloc()) { } + + /** + * @brief Construct string as copy of a substring. + * @param str Source string. + * @param pos Index of first character to copy from. + * @param n Number of characters to copy. + * @param a Allocator to use. + */ + __versa_string(const __versa_string& __str, size_type __pos, + size_type __n, const _Alloc& __a) + : __vstring_base(__str._M_data() + + __str._M_check(__pos, + "__versa_string::__versa_string"), + __str._M_data() + __str._M_limit(__pos, __n) + + __pos, __a) { } + + /** + * @brief Construct string initialized by a character array. + * @param s Source character array. + * @param n Number of characters to copy. + * @param a Allocator to use (default is default allocator). + * + * NB: @a s must have at least @a n characters, '\0' has no special + * meaning. + */ + __versa_string(const _CharT* __s, size_type __n, + const _Alloc& __a = _Alloc()) + : __vstring_base(__s, __s + __n, __a) { } + + /** + * @brief Construct string as copy of a C string. + * @param s Source C string. + * @param a Allocator to use (default is default allocator). + */ + __versa_string(const _CharT* __s, const _Alloc& __a = _Alloc()) + : __vstring_base(__s, __s ? __s + traits_type::length(__s) : + __s + npos, __a) { } + + /** + * @brief Construct string as multiple characters. + * @param n Number of characters. + * @param c Character to use. + * @param a Allocator to use (default is default allocator). + */ + __versa_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc()) + : __vstring_base(__n, __c, __a) { } + + /** + * @brief Construct string as copy of a range. + * @param beg Start of range. + * @param end End of range. + * @param a Allocator to use (default is default allocator). + */ + template<class _InputIterator> + __versa_string(_InputIterator __beg, _InputIterator __end, + const _Alloc& __a = _Alloc()) + : __vstring_base(__beg, __end, __a) { } + + /** + * @brief Destroy the string instance. + */ + ~__versa_string() { } + + /** + * @brief Assign the value of @a str to this string. + * @param str Source string. + */ + __versa_string& + operator=(const __versa_string& __str) + { return this->assign(__str); } + + /** + * @brief Copy contents of @a s into this string. + * @param s Source null-terminated string. + */ + __versa_string& + operator=(const _CharT* __s) + { return this->assign(__s); } + + /** + * @brief Set value to string of length 1. + * @param c Source character. + * + * Assigning to a character makes this string length 1 and + * (*this)[0] == @a c. + */ + __versa_string& + operator=(_CharT __c) + { + this->assign(1, __c); + return *this; + } + + // Iterators: + /** + * Returns a read/write iterator that points to the first character in + * the %string. Unshares the string. + */ + iterator + begin() + { + this->_M_leak(); + return iterator(this->_M_data()); + } + + /** + * Returns a read-only (constant) iterator that points to the first + * character in the %string. + */ + const_iterator + begin() const + { return const_iterator(this->_M_data()); } + + /** + * Returns a read/write iterator that points one past the last + * character in the %string. Unshares the string. + */ + iterator + end() + { + this->_M_leak(); + return iterator(this->_M_data() + this->size()); + } + + /** + * Returns a read-only (constant) iterator that points one past the + * last character in the %string. + */ + const_iterator + end() const + { return const_iterator(this->_M_data() + this->size()); } + + /** + * Returns a read/write reverse iterator that points to the last + * character in the %string. Iteration is done in reverse element + * order. Unshares the string. + */ + reverse_iterator + rbegin() + { return reverse_iterator(this->end()); } + + /** + * Returns a read-only (constant) reverse iterator that points + * to the last character in the %string. Iteration is done in + * reverse element order. + */ + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(this->end()); } + + /** + * Returns a read/write reverse iterator that points to one before the + * first character in the %string. Iteration is done in reverse + * element order. Unshares the string. + */ + reverse_iterator + rend() + { return reverse_iterator(this->begin()); } + + /** + * Returns a read-only (constant) reverse iterator that points + * to one before the first character in the %string. Iteration + * is done in reverse element order. + */ + const_reverse_iterator + rend() const + { return const_reverse_iterator(this->begin()); } + + public: + // Capacity: + /// Returns the number of characters in the string, not including any + /// null-termination. + size_type + size() const + { return this->_M_length(); } + + /// Returns the number of characters in the string, not including any + /// null-termination. + size_type + length() const + { return this->_M_length(); } + + /// Returns the size() of the largest possible %string. + size_type + max_size() const + { return this->_M_max_size(); } + + /** + * @brief Resizes the %string to the specified number of characters. + * @param n Number of characters the %string should contain. + * @param c Character to fill any new elements. + * + * This function will %resize the %string to the specified + * number of characters. If the number is smaller than the + * %string's current size the %string is truncated, otherwise + * the %string is extended and new elements are set to @a c. + */ + void + resize(size_type __n, _CharT __c); + + /** + * @brief Resizes the %string to the specified number of characters. + * @param n Number of characters the %string should contain. + * + * This function will resize the %string to the specified length. If + * the new size is smaller than the %string's current size the %string + * is truncated, otherwise the %string is extended and new characters + * are default-constructed. For basic types such as char, this means + * setting them to 0. + */ + void + resize(size_type __n) + { this->resize(__n, _CharT()); } + + /** + * Returns the total number of characters that the %string can hold + * before needing to allocate more memory. + */ + size_type + capacity() const + { return this->_M_capacity(); } + + /** + * @brief Attempt to preallocate enough memory for specified number of + * characters. + * @param res_arg Number of characters required. + * @throw std::length_error If @a res_arg exceeds @c max_size(). + * + * This function attempts to reserve enough memory for the + * %string to hold the specified number of characters. If the + * number requested is more than max_size(), length_error is + * thrown. + * + * The advantage of this function is that if optimal code is a + * necessity and the user can determine the string length that will be + * required, the user can reserve the memory in %advance, and thus + * prevent a possible reallocation of memory and copying of %string + * data. + */ + void + reserve(size_type __res_arg = 0) + { this->_M_reserve(__res_arg); } + + /** + * Erases the string, making it empty. + */ + void + clear() + { this->_M_clear(); } + + /** + * Returns true if the %string is empty. Equivalent to *this == "". + */ + bool + empty() const + { return this->size() == 0; } + + // Element access: + /** + * @brief Subscript access to the data contained in the %string. + * @param pos The index of the character to access. + * @return Read-only (constant) reference to the character. + * + * This operator allows for easy, array-style, data access. + * Note that data access with this operator is unchecked and + * out_of_range lookups are not defined. (For checked lookups + * see at().) + */ + const_reference + operator[] (size_type __pos) const + { + _GLIBCXX_DEBUG_ASSERT(__pos <= this->size()); + return this->_M_data()[__pos]; + } + + /** + * @brief Subscript access to the data contained in the %string. + * @param pos The index of the character to access. + * @return Read/write reference to the character. + * + * This operator allows for easy, array-style, data access. + * Note that data access with this operator is unchecked and + * out_of_range lookups are not defined. (For checked lookups + * see at().) Unshares the string. + */ + reference + operator[](size_type __pos) + { + // allow pos == size() as v3 extension: + _GLIBCXX_DEBUG_ASSERT(__pos <= this->size()); + // but be strict in pedantic mode: + _GLIBCXX_DEBUG_PEDASSERT(__pos < this->size()); + this->_M_leak(); + return this->_M_data()[__pos]; + } + + /** + * @brief Provides access to the data contained in the %string. + * @param n The index of the character to access. + * @return Read-only (const) reference to the character. + * @throw std::out_of_range If @a n is an invalid index. + * + * This function provides for safer data access. The parameter is + * first checked that it is in the range of the string. The function + * throws out_of_range if the check fails. + */ + const_reference + at(size_type __n) const + { + if (__n >= this->size()) + std::__throw_out_of_range(__N("__versa_string::at")); + return this->_M_data()[__n]; + } + + /** + * @brief Provides access to the data contained in the %string. + * @param n The index of the character to access. + * @return Read/write reference to the character. + * @throw std::out_of_range If @a n is an invalid index. + * + * This function provides for safer data access. The parameter is + * first checked that it is in the range of the string. The function + * throws out_of_range if the check fails. Success results in + * unsharing the string. + */ + reference + at(size_type __n) + { + if (__n >= this->size()) + std::__throw_out_of_range(__N("__versa_string::at")); + this->_M_leak(); + return this->_M_data()[__n]; + } + + // Modifiers: + /** + * @brief Append a string to this string. + * @param str The string to append. + * @return Reference to this string. + */ + __versa_string& + operator+=(const __versa_string& __str) + { return this->append(__str); } + + /** + * @brief Append a C string. + * @param s The C string to append. + * @return Reference to this string. + */ + __versa_string& + operator+=(const _CharT* __s) + { return this->append(__s); } + + /** + * @brief Append a character. + * @param c The character to append. + * @return Reference to this string. + */ + __versa_string& + operator+=(_CharT __c) + { + this->push_back(__c); + return *this; + } + + /** + * @brief Append a string to this string. + * @param str The string to append. + * @return Reference to this string. + */ + __versa_string& + append(const __versa_string& __str) + { return _M_append(__str._M_data(), __str.size()); } + + /** + * @brief Append a substring. + * @param str The string to append. + * @param pos Index of the first character of str to append. + * @param n The number of characters to append. + * @return Reference to this string. + * @throw std::out_of_range if @a pos is not a valid index. + * + * This function appends @a n characters from @a str starting at @a pos + * to this string. If @a n is is larger than the number of available + * characters in @a str, the remainder of @a str is appended. + */ + __versa_string& + append(const __versa_string& __str, size_type __pos, size_type __n) + { return _M_append(__str._M_data() + + __str._M_check(__pos, "__versa_string::append"), + __str._M_limit(__pos, __n)); } + + /** + * @brief Append a C substring. + * @param s The C string to append. + * @param n The number of characters to append. + * @return Reference to this string. + */ + __versa_string& + append(const _CharT* __s, size_type __n) + { + __glibcxx_requires_string_len(__s, __n); + _M_check_length(size_type(0), __n, "__versa_string::append"); + return _M_append(__s, __n); + } + + /** + * @brief Append a C string. + * @param s The C string to append. + * @return Reference to this string. + */ + __versa_string& + append(const _CharT* __s) + { + __glibcxx_requires_string(__s); + const size_type __n = traits_type::length(__s); + _M_check_length(size_type(0), __n, "__versa_string::append"); + return _M_append(__s, __n); + } + + /** + * @brief Append multiple characters. + * @param n The number of characters to append. + * @param c The character to use. + * @return Reference to this string. + * + * Appends n copies of c to this string. + */ + __versa_string& + append(size_type __n, _CharT __c) + { return _M_replace_aux(this->size(), size_type(0), __n, __c); } + + /** + * @brief Append a range of characters. + * @param first Iterator referencing the first character to append. + * @param last Iterator marking the end of the range. + * @return Reference to this string. + * + * Appends characters in the range [first,last) to this string. + */ + template<class _InputIterator> + __versa_string& + append(_InputIterator __first, _InputIterator __last) + { return this->replace(_M_iend(), _M_iend(), __first, __last); } + + /** + * @brief Append a single character. + * @param c Character to append. + */ + void + push_back(_CharT __c) + { + const size_type __size = this->size(); + if (__size + 1 > this->capacity() || this->_M_is_shared()) + this->_M_mutate(__size, size_type(0), 0, size_type(1)); + traits_type::assign(this->_M_data()[__size], __c); + this->_M_set_length(__size + 1); + } + + /** + * @brief Set value to contents of another string. + * @param str Source string to use. + * @return Reference to this string. + */ + __versa_string& + assign(const __versa_string& __str) + { + this->_M_assign(__str); + return *this; + } + + /** + * @brief Set value to a substring of a string. + * @param str The string to use. + * @param pos Index of the first character of str. + * @param n Number of characters to use. + * @return Reference to this string. + * @throw std::out_of_range if @a pos is not a valid index. + * + * This function sets this string to the substring of @a str consisting + * of @a n characters at @a pos. If @a n is is larger than the number + * of available characters in @a str, the remainder of @a str is used. + */ + __versa_string& + assign(const __versa_string& __str, size_type __pos, size_type __n) + { return _M_replace(size_type(0), this->size(), __str._M_data() + + __str._M_check(__pos, "__versa_string::assign"), + __str._M_limit(__pos, __n)); } + + /** + * @brief Set value to a C substring. + * @param s The C string to use. + * @param n Number of characters to use. + * @return Reference to this string. + * + * This function sets the value of this string to the first @a n + * characters of @a s. If @a n is is larger than the number of + * available characters in @a s, the remainder of @a s is used. + */ + __versa_string& + assign(const _CharT* __s, size_type __n) + { + __glibcxx_requires_string_len(__s, __n); + return _M_replace(size_type(0), this->size(), __s, __n); + } + + /** + * @brief Set value to contents of a C string. + * @param s The C string to use. + * @return Reference to this string. + * + * This function sets the value of this string to the value of @a s. + * The data is copied, so there is no dependence on @a s once the + * function returns. + */ + __versa_string& + assign(const _CharT* __s) + { + __glibcxx_requires_string(__s); + return _M_replace(size_type(0), this->size(), __s, + traits_type::length(__s)); + } + + /** + * @brief Set value to multiple characters. + * @param n Length of the resulting string. + * @param c The character to use. + * @return Reference to this string. + * + * This function sets the value of this string to @a n copies of + * character @a c. + */ + __versa_string& + assign(size_type __n, _CharT __c) + { return _M_replace_aux(size_type(0), this->size(), __n, __c); } + + /** + * @brief Set value to a range of characters. + * @param first Iterator referencing the first character to append. + * @param last Iterator marking the end of the range. + * @return Reference to this string. + * + * Sets value of string to characters in the range [first,last). + */ + template<class _InputIterator> + __versa_string& + assign(_InputIterator __first, _InputIterator __last) + { return this->replace(_M_ibegin(), _M_iend(), __first, __last); } + + /** + * @brief Insert multiple characters. + * @param p Iterator referencing location in string to insert at. + * @param n Number of characters to insert + * @param c The character to insert. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Inserts @a n copies of character @a c starting at the position + * referenced by iterator @a p. If adding characters causes the length + * to exceed max_size(), length_error is thrown. The value of the + * string doesn't change if an error is thrown. + */ + void + insert(iterator __p, size_type __n, _CharT __c) + { this->replace(__p, __p, __n, __c); } + + /** + * @brief Insert a range of characters. + * @param p Iterator referencing location in string to insert at. + * @param beg Start of range. + * @param end End of range. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Inserts characters in range [beg,end). If adding characters causes + * the length to exceed max_size(), length_error is thrown. The value + * of the string doesn't change if an error is thrown. + */ + template<class _InputIterator> + void + insert(iterator __p, _InputIterator __beg, _InputIterator __end) + { this->replace(__p, __p, __beg, __end); } + + /** + * @brief Insert value of a string. + * @param pos1 Iterator referencing location in string to insert at. + * @param str The string to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Inserts value of @a str starting at @a pos1. If adding characters + * causes the length to exceed max_size(), length_error is thrown. The + * value of the string doesn't change if an error is thrown. + */ + __versa_string& + insert(size_type __pos1, const __versa_string& __str) + { return this->replace(__pos1, size_type(0), + __str._M_data(), __str.size()); } + + /** + * @brief Insert a substring. + * @param pos1 Iterator referencing location in string to insert at. + * @param str The string to insert. + * @param pos2 Start of characters in str to insert. + * @param n Number of characters to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * @throw std::out_of_range If @a pos1 > size() or + * @a pos2 > @a str.size(). + * + * Starting at @a pos1, insert @a n character of @a str beginning with + * @a pos2. If adding characters causes the length to exceed + * max_size(), length_error is thrown. If @a pos1 is beyond the end of + * this string or @a pos2 is beyond the end of @a str, out_of_range is + * thrown. The value of the string doesn't change if an error is + * thrown. + */ + __versa_string& + insert(size_type __pos1, const __versa_string& __str, + size_type __pos2, size_type __n) + { return this->replace(__pos1, size_type(0), __str._M_data() + + __str._M_check(__pos2, "__versa_string::insert"), + __str._M_limit(__pos2, __n)); } + + /** + * @brief Insert a C substring. + * @param pos Iterator referencing location in string to insert at. + * @param s The C string to insert. + * @param n The number of characters to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * @throw std::out_of_range If @a pos is beyond the end of this + * string. + * + * Inserts the first @a n characters of @a s starting at @a pos. If + * adding characters causes the length to exceed max_size(), + * length_error is thrown. If @a pos is beyond end(), out_of_range is + * thrown. The value of the string doesn't change if an error is + * thrown. + */ + __versa_string& + insert(size_type __pos, const _CharT* __s, size_type __n) + { return this->replace(__pos, size_type(0), __s, __n); } + + /** + * @brief Insert a C string. + * @param pos Iterator referencing location in string to insert at. + * @param s The C string to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * @throw std::out_of_range If @a pos is beyond the end of this + * string. + * + * Inserts the first @a n characters of @a s starting at @a pos. If + * adding characters causes the length to exceed max_size(), + * length_error is thrown. If @a pos is beyond end(), out_of_range is + * thrown. The value of the string doesn't change if an error is + * thrown. + */ + __versa_string& + insert(size_type __pos, const _CharT* __s) + { + __glibcxx_requires_string(__s); + return this->replace(__pos, size_type(0), __s, + traits_type::length(__s)); + } + + /** + * @brief Insert multiple characters. + * @param pos Index in string to insert at. + * @param n Number of characters to insert + * @param c The character to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * @throw std::out_of_range If @a pos is beyond the end of this + * string. + * + * Inserts @a n copies of character @a c starting at index @a pos. If + * adding characters causes the length to exceed max_size(), + * length_error is thrown. If @a pos > length(), out_of_range is + * thrown. The value of the string doesn't change if an error is + * thrown. + */ + __versa_string& + insert(size_type __pos, size_type __n, _CharT __c) + { return _M_replace_aux(_M_check(__pos, "__versa_string::insert"), + size_type(0), __n, __c); } + + /** + * @brief Insert one character. + * @param p Iterator referencing position in string to insert at. + * @param c The character to insert. + * @return Iterator referencing newly inserted char. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Inserts character @a c at position referenced by @a p. If adding + * character causes the length to exceed max_size(), length_error is + * thrown. If @a p is beyond end of string, out_of_range is thrown. + * The value of the string doesn't change if an error is thrown. + */ + iterator + insert(iterator __p, _CharT __c) + { + _GLIBCXX_DEBUG_PEDASSERT(__p >= _M_ibegin() && __p <= _M_iend()); + const size_type __pos = __p - _M_ibegin(); + _M_replace_aux(__pos, size_type(0), size_type(1), __c); + this->_M_set_leaked(); + return iterator(this->_M_data() + __pos); + } + + /** + * @brief Remove characters. + * @param pos Index of first character to remove (default 0). + * @param n Number of characters to remove (default remainder). + * @return Reference to this string. + * @throw std::out_of_range If @a pos is beyond the end of this + * string. + * + * Removes @a n characters from this string starting at @a pos. The + * length of the string is reduced by @a n. If there are < @a n + * characters to remove, the remainder of the string is truncated. If + * @a p is beyond end of string, out_of_range is thrown. The value of + * the string doesn't change if an error is thrown. + */ + __versa_string& + erase(size_type __pos = 0, size_type __n = npos) + { + this->_M_erase(_M_check(__pos, "__versa_string::erase"), + _M_limit(__pos, __n)); + return *this; + } + + /** + * @brief Remove one character. + * @param position Iterator referencing the character to remove. + * @return iterator referencing same location after removal. + * + * Removes the character at @a position from this string. The value + * of the string doesn't change if an error is thrown. + */ + iterator + erase(iterator __position) + { + _GLIBCXX_DEBUG_PEDASSERT(__position >= _M_ibegin() + && __position < _M_iend()); + const size_type __pos = __position - _M_ibegin(); + this->_M_erase(__pos, size_type(1)); + this->_M_set_leaked(); + return iterator(this->_M_data() + __pos); + } + + /** + * @brief Remove a range of characters. + * @param first Iterator referencing the first character to remove. + * @param last Iterator referencing the end of the range. + * @return Iterator referencing location of first after removal. + * + * Removes the characters in the range [first,last) from this string. + * The value of the string doesn't change if an error is thrown. + */ + iterator + erase(iterator __first, iterator __last) + { + _GLIBCXX_DEBUG_PEDASSERT(__first >= _M_ibegin() && __first <= __last + && __last <= _M_iend()); + const size_type __pos = __first - _M_ibegin(); + this->_M_erase(__pos, __last - __first); + this->_M_set_leaked(); + return iterator(this->_M_data() + __pos); + } + + /** + * @brief Replace characters with value from another string. + * @param pos Index of first character to replace. + * @param n Number of characters to be replaced. + * @param str String to insert. + * @return Reference to this string. + * @throw std::out_of_range If @a pos is beyond the end of this + * string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [pos,pos+n) from this string. + * In place, the value of @a str is inserted. If @a pos is beyond end + * of string, out_of_range is thrown. If the length of the result + * exceeds max_size(), length_error is thrown. The value of the string + * doesn't change if an error is thrown. + */ + __versa_string& + replace(size_type __pos, size_type __n, const __versa_string& __str) + { return this->replace(__pos, __n, __str._M_data(), __str.size()); } + + /** + * @brief Replace characters with value from another string. + * @param pos1 Index of first character to replace. + * @param n1 Number of characters to be replaced. + * @param str String to insert. + * @param pos2 Index of first character of str to use. + * @param n2 Number of characters from str to use. + * @return Reference to this string. + * @throw std::out_of_range If @a pos1 > size() or @a pos2 > + * str.size(). + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [pos1,pos1 + n) from this + * string. In place, the value of @a str is inserted. If @a pos is + * beyond end of string, out_of_range is thrown. If the length of the + * result exceeds max_size(), length_error is thrown. The value of the + * string doesn't change if an error is thrown. + */ + __versa_string& + replace(size_type __pos1, size_type __n1, const __versa_string& __str, + size_type __pos2, size_type __n2) + { + return this->replace(__pos1, __n1, __str._M_data() + + __str._M_check(__pos2, + "__versa_string::replace"), + __str._M_limit(__pos2, __n2)); + } + + /** + * @brief Replace characters with value of a C substring. + * @param pos Index of first character to replace. + * @param n1 Number of characters to be replaced. + * @param s C string to insert. + * @param n2 Number of characters from @a s to use. + * @return Reference to this string. + * @throw std::out_of_range If @a pos1 > size(). + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [pos,pos + n1) from this string. + * In place, the first @a n2 characters of @a s are inserted, or all + * of @a s if @a n2 is too large. If @a pos is beyond end of string, + * out_of_range is thrown. If the length of result exceeds max_size(), + * length_error is thrown. The value of the string doesn't change if + * an error is thrown. + */ + __versa_string& + replace(size_type __pos, size_type __n1, const _CharT* __s, + size_type __n2) + { + __glibcxx_requires_string_len(__s, __n2); + return _M_replace(_M_check(__pos, "__versa_string::replace"), + _M_limit(__pos, __n1), __s, __n2); + } + + /** + * @brief Replace characters with value of a C string. + * @param pos Index of first character to replace. + * @param n1 Number of characters to be replaced. + * @param s C string to insert. + * @return Reference to this string. + * @throw std::out_of_range If @a pos > size(). + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [pos,pos + n1) from this string. + * In place, the first @a n characters of @a s are inserted. If @a + * pos is beyond end of string, out_of_range is thrown. If the length + * of result exceeds max_size(), length_error is thrown. The value of + * the string doesn't change if an error is thrown. + */ + __versa_string& + replace(size_type __pos, size_type __n1, const _CharT* __s) + { + __glibcxx_requires_string(__s); + return this->replace(__pos, __n1, __s, traits_type::length(__s)); + } + + /** + * @brief Replace characters with multiple characters. + * @param pos Index of first character to replace. + * @param n1 Number of characters to be replaced. + * @param n2 Number of characters to insert. + * @param c Character to insert. + * @return Reference to this string. + * @throw std::out_of_range If @a pos > size(). + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [pos,pos + n1) from this string. + * In place, @a n2 copies of @a c are inserted. If @a pos is beyond + * end of string, out_of_range is thrown. If the length of result + * exceeds max_size(), length_error is thrown. The value of the string + * doesn't change if an error is thrown. + */ + __versa_string& + replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c) + { return _M_replace_aux(_M_check(__pos, "__versa_string::replace"), + _M_limit(__pos, __n1), __n2, __c); } + + /** + * @brief Replace range of characters with string. + * @param i1 Iterator referencing start of range to replace. + * @param i2 Iterator referencing end of range to replace. + * @param str String value to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [i1,i2). In place, the value of + * @a str is inserted. If the length of result exceeds max_size(), + * length_error is thrown. The value of the string doesn't change if + * an error is thrown. + */ + __versa_string& + replace(iterator __i1, iterator __i2, const __versa_string& __str) + { return this->replace(__i1, __i2, __str._M_data(), __str.size()); } + + /** + * @brief Replace range of characters with C substring. + * @param i1 Iterator referencing start of range to replace. + * @param i2 Iterator referencing end of range to replace. + * @param s C string value to insert. + * @param n Number of characters from s to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [i1,i2). In place, the first @a + * n characters of @a s are inserted. If the length of result exceeds + * max_size(), length_error is thrown. The value of the string doesn't + * change if an error is thrown. + */ + __versa_string& + replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __s, __n); + } + + /** + * @brief Replace range of characters with C string. + * @param i1 Iterator referencing start of range to replace. + * @param i2 Iterator referencing end of range to replace. + * @param s C string value to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [i1,i2). In place, the + * characters of @a s are inserted. If the length of result exceeds + * max_size(), length_error is thrown. The value of the string doesn't + * change if an error is thrown. + */ + __versa_string& + replace(iterator __i1, iterator __i2, const _CharT* __s) + { + __glibcxx_requires_string(__s); + return this->replace(__i1, __i2, __s, traits_type::length(__s)); + } + + /** + * @brief Replace range of characters with multiple characters + * @param i1 Iterator referencing start of range to replace. + * @param i2 Iterator referencing end of range to replace. + * @param n Number of characters to insert. + * @param c Character to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [i1,i2). In place, @a n copies + * of @a c are inserted. If the length of result exceeds max_size(), + * length_error is thrown. The value of the string doesn't change if + * an error is thrown. + */ + __versa_string& + replace(iterator __i1, iterator __i2, size_type __n, _CharT __c) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __c); + } + + /** + * @brief Replace range of characters with range. + * @param i1 Iterator referencing start of range to replace. + * @param i2 Iterator referencing end of range to replace. + * @param k1 Iterator referencing start of range to insert. + * @param k2 Iterator referencing end of range to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [i1,i2). In place, characters + * in the range [k1,k2) are inserted. If the length of result exceeds + * max_size(), length_error is thrown. The value of the string doesn't + * change if an error is thrown. + */ + template<class _InputIterator> + __versa_string& + replace(iterator __i1, iterator __i2, + _InputIterator __k1, _InputIterator __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + __glibcxx_requires_valid_range(__k1, __k2); + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + return _M_replace_dispatch(__i1, __i2, __k1, __k2, _Integral()); + } + + // Specializations for the common case of pointer and iterator: + // useful to avoid the overhead of temporary buffering in _M_replace. + __versa_string& + replace(iterator __i1, iterator __i2, _CharT* __k1, _CharT* __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + __glibcxx_requires_valid_range(__k1, __k2); + return this->replace(__i1 - _M_ibegin(), __i2 - __i1, + __k1, __k2 - __k1); + } + + __versa_string& + replace(iterator __i1, iterator __i2, + const _CharT* __k1, const _CharT* __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + __glibcxx_requires_valid_range(__k1, __k2); + return this->replace(__i1 - _M_ibegin(), __i2 - __i1, + __k1, __k2 - __k1); + } + + __versa_string& + replace(iterator __i1, iterator __i2, iterator __k1, iterator __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + __glibcxx_requires_valid_range(__k1, __k2); + return this->replace(__i1 - _M_ibegin(), __i2 - __i1, + __k1.base(), __k2 - __k1); + } + + __versa_string& + replace(iterator __i1, iterator __i2, + const_iterator __k1, const_iterator __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + __glibcxx_requires_valid_range(__k1, __k2); + return this->replace(__i1 - _M_ibegin(), __i2 - __i1, + __k1.base(), __k2 - __k1); + } + + private: + template<class _Integer> + __versa_string& + _M_replace_dispatch(iterator __i1, iterator __i2, _Integer __n, + _Integer __val, std::__true_type) + { return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __val); } + + template<class _InputIterator> + __versa_string& + _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1, + _InputIterator __k2, std::__false_type); + + __versa_string& + _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2, + _CharT __c); + + __versa_string& + _M_replace(size_type __pos, size_type __len1, const _CharT* __s, + const size_type __len2); + + __versa_string& + _M_append(const _CharT* __s, size_type __n); + + public: + + /** + * @brief Copy substring into C string. + * @param s C string to copy value into. + * @param n Number of characters to copy. + * @param pos Index of first character to copy. + * @return Number of characters actually copied + * @throw std::out_of_range If pos > size(). + * + * Copies up to @a n characters starting at @a pos into the C string @a + * s. If @a pos is greater than size(), out_of_range is thrown. + */ + size_type + copy(_CharT* __s, size_type __n, size_type __pos = 0) const; + + /** + * @brief Swap contents with another string. + * @param s String to swap with. + * + * Exchanges the contents of this string with that of @a s in constant + * time. + */ + void + swap(__versa_string& __s) + { this->_M_swap(__s); } + + // String operations: + /** + * @brief Return const pointer to null-terminated contents. + * + * This is a handle to internal data. Do not modify or dire things may + * happen. + */ + const _CharT* + c_str() const + { return this->_M_data(); } + + /** + * @brief Return const pointer to contents. + * + * This is a handle to internal data. Do not modify or dire things may + * happen. + */ + const _CharT* + data() const + { return this->_M_data(); } + + /** + * @brief Return copy of allocator used to construct this string. + */ + allocator_type + get_allocator() const + { return allocator_type(this->_M_get_allocator()); } + + /** + * @brief Find position of a C substring. + * @param s C string to locate. + * @param pos Index of character to search from. + * @param n Number of characters from @a s to search for. + * @return Index of start of first occurrence. + * + * Starting from @a pos, searches forward for the first @a n characters + * in @a s within this string. If found, returns the index where it + * begins. If not found, returns npos. + */ + size_type + find(const _CharT* __s, size_type __pos, size_type __n) const; + + /** + * @brief Find position of a string. + * @param str String to locate. + * @param pos Index of character to search from (default 0). + * @return Index of start of first occurrence. + * + * Starting from @a pos, searches forward for value of @a str within + * this string. If found, returns the index where it begins. If not + * found, returns npos. + */ + size_type + find(const __versa_string& __str, size_type __pos = 0) const + { return this->find(__str.data(), __pos, __str.size()); } + + /** + * @brief Find position of a C string. + * @param s C string to locate. + * @param pos Index of character to search from (default 0). + * @return Index of start of first occurrence. + * + * Starting from @a pos, searches forward for the value of @a s within + * this string. If found, returns the index where it begins. If not + * found, returns npos. + */ + size_type + find(const _CharT* __s, size_type __pos = 0) const + { + __glibcxx_requires_string(__s); + return this->find(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find position of a character. + * @param c Character to locate. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for @a c within this string. + * If found, returns the index where it was found. If not found, + * returns npos. + */ + size_type + find(_CharT __c, size_type __pos = 0) const; + + /** + * @brief Find last position of a string. + * @param str String to locate. + * @param pos Index of character to search back from (default end). + * @return Index of start of last occurrence. + * + * Starting from @a pos, searches backward for value of @a str within + * this string. If found, returns the index where it begins. If not + * found, returns npos. + */ + size_type + rfind(const __versa_string& __str, size_type __pos = npos) const + { return this->rfind(__str.data(), __pos, __str.size()); } + + /** + * @brief Find last position of a C substring. + * @param s C string to locate. + * @param pos Index of character to search back from. + * @param n Number of characters from s to search for. + * @return Index of start of last occurrence. + * + * Starting from @a pos, searches backward for the first @a n + * characters in @a s within this string. If found, returns the index + * where it begins. If not found, returns npos. + */ + size_type + rfind(const _CharT* __s, size_type __pos, size_type __n) const; + + /** + * @brief Find last position of a C string. + * @param s C string to locate. + * @param pos Index of character to start search at (default end). + * @return Index of start of last occurrence. + * + * Starting from @a pos, searches backward for the value of @a s within + * this string. If found, returns the index where it begins. If not + * found, returns npos. + */ + size_type + rfind(const _CharT* __s, size_type __pos = npos) const + { + __glibcxx_requires_string(__s); + return this->rfind(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find last position of a character. + * @param c Character to locate. + * @param pos Index of character to search back from (default end). + * @return Index of last occurrence. + * + * Starting from @a pos, searches backward for @a c within this string. + * If found, returns the index where it was found. If not found, + * returns npos. + */ + size_type + rfind(_CharT __c, size_type __pos = npos) const; + + /** + * @brief Find position of a character of string. + * @param str String containing characters to locate. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for one of the characters of + * @a str within this string. If found, returns the index where it was + * found. If not found, returns npos. + */ + size_type + find_first_of(const __versa_string& __str, size_type __pos = 0) const + { return this->find_first_of(__str.data(), __pos, __str.size()); } + + /** + * @brief Find position of a character of C substring. + * @param s String containing characters to locate. + * @param pos Index of character to search from (default 0). + * @param n Number of characters from s to search for. + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for one of the first @a n + * characters of @a s within this string. If found, returns the index + * where it was found. If not found, returns npos. + */ + size_type + find_first_of(const _CharT* __s, size_type __pos, size_type __n) const; + + /** + * @brief Find position of a character of C string. + * @param s String containing characters to locate. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for one of the characters of + * @a s within this string. If found, returns the index where it was + * found. If not found, returns npos. + */ + size_type + find_first_of(const _CharT* __s, size_type __pos = 0) const + { + __glibcxx_requires_string(__s); + return this->find_first_of(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find position of a character. + * @param c Character to locate. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for the character @a c within + * this string. If found, returns the index where it was found. If + * not found, returns npos. + * + * Note: equivalent to find(c, pos). + */ + size_type + find_first_of(_CharT __c, size_type __pos = 0) const + { return this->find(__c, __pos); } + + /** + * @brief Find last position of a character of string. + * @param str String containing characters to locate. + * @param pos Index of character to search back from (default end). + * @return Index of last occurrence. + * + * Starting from @a pos, searches backward for one of the characters of + * @a str within this string. If found, returns the index where it was + * found. If not found, returns npos. + */ + size_type + find_last_of(const __versa_string& __str, size_type __pos = npos) const + { return this->find_last_of(__str.data(), __pos, __str.size()); } + + /** + * @brief Find last position of a character of C substring. + * @param s C string containing characters to locate. + * @param pos Index of character to search back from (default end). + * @param n Number of characters from s to search for. + * @return Index of last occurrence. + * + * Starting from @a pos, searches backward for one of the first @a n + * characters of @a s within this string. If found, returns the index + * where it was found. If not found, returns npos. + */ + size_type + find_last_of(const _CharT* __s, size_type __pos, size_type __n) const; + + /** + * @brief Find last position of a character of C string. + * @param s C string containing characters to locate. + * @param pos Index of character to search back from (default end). + * @return Index of last occurrence. + * + * Starting from @a pos, searches backward for one of the characters of + * @a s within this string. If found, returns the index where it was + * found. If not found, returns npos. + */ + size_type + find_last_of(const _CharT* __s, size_type __pos = npos) const + { + __glibcxx_requires_string(__s); + return this->find_last_of(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find last position of a character. + * @param c Character to locate. + * @param pos Index of character to search back from (default 0). + * @return Index of last occurrence. + * + * Starting from @a pos, searches backward for @a c within this string. + * If found, returns the index where it was found. If not found, + * returns npos. + * + * Note: equivalent to rfind(c, pos). + */ + size_type + find_last_of(_CharT __c, size_type __pos = npos) const + { return this->rfind(__c, __pos); } + + /** + * @brief Find position of a character not in string. + * @param str String containing characters to avoid. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for a character not contained + * in @a str within this string. If found, returns the index where it + * was found. If not found, returns npos. + */ + size_type + find_first_not_of(const __versa_string& __str, size_type __pos = 0) const + { return this->find_first_not_of(__str.data(), __pos, __str.size()); } + + /** + * @brief Find position of a character not in C substring. + * @param s C string containing characters to avoid. + * @param pos Index of character to search from (default 0). + * @param n Number of characters from s to consider. + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for a character not contained + * in the first @a n characters of @a s within this string. If found, + * returns the index where it was found. If not found, returns npos. + */ + size_type + find_first_not_of(const _CharT* __s, size_type __pos, + size_type __n) const; + + /** + * @brief Find position of a character not in C string. + * @param s C string containing characters to avoid. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for a character not contained + * in @a s within this string. If found, returns the index where it + * was found. If not found, returns npos. + */ + size_type + find_first_not_of(const _CharT* __s, size_type __pos = 0) const + { + __glibcxx_requires_string(__s); + return this->find_first_not_of(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find position of a different character. + * @param c Character to avoid. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for a character other than @a c + * within this string. If found, returns the index where it was found. + * If not found, returns npos. + */ + size_type + find_first_not_of(_CharT __c, size_type __pos = 0) const; + + /** + * @brief Find last position of a character not in string. + * @param str String containing characters to avoid. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches backward for a character not + * contained in @a str within this string. If found, returns the index + * where it was found. If not found, returns npos. + */ + size_type + find_last_not_of(const __versa_string& __str, + size_type __pos = npos) const + { return this->find_last_not_of(__str.data(), __pos, __str.size()); } + + /** + * @brief Find last position of a character not in C substring. + * @param s C string containing characters to avoid. + * @param pos Index of character to search from (default 0). + * @param n Number of characters from s to consider. + * @return Index of first occurrence. + * + * Starting from @a pos, searches backward for a character not + * contained in the first @a n characters of @a s within this string. + * If found, returns the index where it was found. If not found, + * returns npos. + */ + size_type + find_last_not_of(const _CharT* __s, size_type __pos, + size_type __n) const; + /** + * @brief Find position of a character not in C string. + * @param s C string containing characters to avoid. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches backward for a character not + * contained in @a s within this string. If found, returns the index + * where it was found. If not found, returns npos. + */ + size_type + find_last_not_of(const _CharT* __s, size_type __pos = npos) const + { + __glibcxx_requires_string(__s); + return this->find_last_not_of(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find last position of a different character. + * @param c Character to avoid. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches backward for a character other than + * @a c within this string. If found, returns the index where it was + * found. If not found, returns npos. + */ + size_type + find_last_not_of(_CharT __c, size_type __pos = npos) const; + + /** + * @brief Get a substring. + * @param pos Index of first character (default 0). + * @param n Number of characters in substring (default remainder). + * @return The new string. + * @throw std::out_of_range If pos > size(). + * + * Construct and return a new string using the @a n characters starting + * at @a pos. If the string is too short, use the remainder of the + * characters. If @a pos is beyond the end of the string, out_of_range + * is thrown. + */ + __versa_string + substr(size_type __pos = 0, size_type __n = npos) const + { + return __versa_string(*this, _M_check(__pos, "__versa_string::substr"), + __n); + } + + /** + * @brief Compare to a string. + * @param str String to compare against. + * @return Integer < 0, 0, or > 0. + * + * Returns an integer < 0 if this string is ordered before @a str, 0 if + * their values are equivalent, or > 0 if this string is ordered after + * @a str. Determines the effective length rlen of the strings to + * compare as the smallest of size() and str.size(). The function + * then compares the two strings by calling traits::compare(data(), + * str.data(),rlen). If the result of the comparison is nonzero returns + * it, otherwise the shorter one is ordered first. + */ + int + compare(const __versa_string& __str) const + { + if (this->_M_compare(__str)) + return 0; + + const size_type __size = this->size(); + const size_type __osize = __str.size(); + const size_type __len = std::min(__size, __osize); + + int __r = traits_type::compare(this->_M_data(), __str.data(), __len); + if (!__r) + __r = __size - __osize; + return __r; + } + + /** + * @brief Compare substring to a string. + * @param pos Index of first character of substring. + * @param n Number of characters in substring. + * @param str String to compare against. + * @return Integer < 0, 0, or > 0. + * + * Form the substring of this string from the @a n characters starting + * at @a pos. Returns an integer < 0 if the substring is ordered + * before @a str, 0 if their values are equivalent, or > 0 if the + * substring is ordered after @a str. Determines the effective length + * rlen of the strings to compare as the smallest of the length of the + * substring and @a str.size(). The function then compares the two + * strings by calling traits::compare(substring.data(),str.data(),rlen). + * If the result of the comparison is nonzero returns it, otherwise the + * shorter one is ordered first. + */ + int + compare(size_type __pos, size_type __n, + const __versa_string& __str) const; + + /** + * @brief Compare substring to a substring. + * @param pos1 Index of first character of substring. + * @param n1 Number of characters in substring. + * @param str String to compare against. + * @param pos2 Index of first character of substring of str. + * @param n2 Number of characters in substring of str. + * @return Integer < 0, 0, or > 0. + * + * Form the substring of this string from the @a n1 characters starting + * at @a pos1. Form the substring of @a str from the @a n2 characters + * starting at @a pos2. Returns an integer < 0 if this substring is + * ordered before the substring of @a str, 0 if their values are + * equivalent, or > 0 if this substring is ordered after the substring + * of @a str. Determines the effective length rlen of the strings + * to compare as the smallest of the lengths of the substrings. The + * function then compares the two strings by calling + * traits::compare(substring.data(),str.substr(pos2,n2).data(),rlen). + * If the result of the comparison is nonzero returns it, otherwise the + * shorter one is ordered first. + */ + int + compare(size_type __pos1, size_type __n1, const __versa_string& __str, + size_type __pos2, size_type __n2) const; + + /** + * @brief Compare to a C string. + * @param s C string to compare against. + * @return Integer < 0, 0, or > 0. + * + * Returns an integer < 0 if this string is ordered before @a s, 0 if + * their values are equivalent, or > 0 if this string is ordered after + * @a s. Determines the effective length rlen of the strings to + * compare as the smallest of size() and the length of a string + * constructed from @a s. The function then compares the two strings + * by calling traits::compare(data(),s,rlen). If the result of the + * comparison is nonzero returns it, otherwise the shorter one is + * ordered first. + */ + int + compare(const _CharT* __s) const; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 5 String::compare specification questionable + /** + * @brief Compare substring to a C string. + * @param pos Index of first character of substring. + * @param n1 Number of characters in substring. + * @param s C string to compare against. + * @return Integer < 0, 0, or > 0. + * + * Form the substring of this string from the @a n1 characters starting + * at @a pos. Returns an integer < 0 if the substring is ordered + * before @a s, 0 if their values are equivalent, or > 0 if the + * substring is ordered after @a s. Determines the effective length + * rlen of the strings to compare as the smallest of the length of the + * substring and the length of a string constructed from @a s. The + * function then compares the two string by calling + * traits::compare(substring.data(),s,rlen). If the result of the + * comparison is nonzero returns it, otherwise the shorter one is + * ordered first. + */ + int + compare(size_type __pos, size_type __n1, const _CharT* __s) const; + + /** + * @brief Compare substring against a character array. + * @param pos1 Index of first character of substring. + * @param n1 Number of characters in substring. + * @param s character array to compare against. + * @param n2 Number of characters of s. + * @return Integer < 0, 0, or > 0. + * + * Form the substring of this string from the @a n1 characters starting + * at @a pos1. Form a string from the first @a n2 characters of @a s. + * Returns an integer < 0 if this substring is ordered before the string + * from @a s, 0 if their values are equivalent, or > 0 if this substring + * is ordered after the string from @a s. Determines the effective + * length rlen of the strings to compare as the smallest of the length + * of the substring and @a n2. The function then compares the two + * strings by calling traits::compare(substring.data(),s,rlen). If the + * result of the comparison is nonzero returns it, otherwise the shorter + * one is ordered first. + * + * NB: s must have at least n2 characters, '\0' has no special + * meaning. + */ + int + compare(size_type __pos, size_type __n1, const _CharT* __s, + size_type __n2) const; + }; + + // operator+ + /** + * @brief Concatenate two strings. + * @param lhs First string. + * @param rhs Last string. + * @return New string with value of @a lhs followed by @a rhs. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + __versa_string<_CharT, _Traits, _Alloc, _Base> + operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs); + + /** + * @brief Concatenate C string and string. + * @param lhs First string. + * @param rhs Last string. + * @return New string with value of @a lhs followed by @a rhs. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + __versa_string<_CharT, _Traits, _Alloc, _Base> + operator+(const _CharT* __lhs, + const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs); + + /** + * @brief Concatenate character and string. + * @param lhs First string. + * @param rhs Last string. + * @return New string with @a lhs followed by @a rhs. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + __versa_string<_CharT, _Traits, _Alloc, _Base> + operator+(_CharT __lhs, + const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs); + + /** + * @brief Concatenate string and C string. + * @param lhs First string. + * @param rhs Last string. + * @return New string with @a lhs followed by @a rhs. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + __versa_string<_CharT, _Traits, _Alloc, _Base> + operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + const _CharT* __rhs); + + /** + * @brief Concatenate string and character. + * @param lhs First string. + * @param rhs Last string. + * @return New string with @a lhs followed by @a rhs. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + __versa_string<_CharT, _Traits, _Alloc, _Base> + operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + _CharT __rhs); + + // operator == + /** + * @brief Test equivalence of two strings. + * @param lhs First string. + * @param rhs Second string. + * @return True if @a lhs.compare(@a rhs) == 0. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline bool + operator==(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) + { return __lhs.compare(__rhs) == 0; } + + /** + * @brief Test equivalence of C string and string. + * @param lhs C string. + * @param rhs String. + * @return True if @a rhs.compare(@a lhs) == 0. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline bool + operator==(const _CharT* __lhs, + const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) + { return __rhs.compare(__lhs) == 0; } + + /** + * @brief Test equivalence of string and C string. + * @param lhs String. + * @param rhs C string. + * @return True if @a lhs.compare(@a rhs) == 0. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline bool + operator==(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) == 0; } + + // operator != + /** + * @brief Test difference of two strings. + * @param lhs First string. + * @param rhs Second string. + * @return True if @a lhs.compare(@a rhs) != 0. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline bool + operator!=(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) + { return __rhs.compare(__lhs) != 0; } + + /** + * @brief Test difference of C string and string. + * @param lhs C string. + * @param rhs String. + * @return True if @a rhs.compare(@a lhs) != 0. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline bool + operator!=(const _CharT* __lhs, + const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) + { return __rhs.compare(__lhs) != 0; } + + /** + * @brief Test difference of string and C string. + * @param lhs String. + * @param rhs C string. + * @return True if @a lhs.compare(@a rhs) != 0. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline bool + operator!=(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) != 0; } + + // operator < + /** + * @brief Test if string precedes string. + * @param lhs First string. + * @param rhs Second string. + * @return True if @a lhs precedes @a rhs. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline bool + operator<(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) + { return __lhs.compare(__rhs) < 0; } + + /** + * @brief Test if string precedes C string. + * @param lhs String. + * @param rhs C string. + * @return True if @a lhs precedes @a rhs. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline bool + operator<(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) < 0; } + + /** + * @brief Test if C string precedes string. + * @param lhs C string. + * @param rhs String. + * @return True if @a lhs precedes @a rhs. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline bool + operator<(const _CharT* __lhs, + const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) + { return __rhs.compare(__lhs) > 0; } + + // operator > + /** + * @brief Test if string follows string. + * @param lhs First string. + * @param rhs Second string. + * @return True if @a lhs follows @a rhs. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline bool + operator>(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) + { return __lhs.compare(__rhs) > 0; } + + /** + * @brief Test if string follows C string. + * @param lhs String. + * @param rhs C string. + * @return True if @a lhs follows @a rhs. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline bool + operator>(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) > 0; } + + /** + * @brief Test if C string follows string. + * @param lhs C string. + * @param rhs String. + * @return True if @a lhs follows @a rhs. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline bool + operator>(const _CharT* __lhs, + const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) + { return __rhs.compare(__lhs) < 0; } + + // operator <= + /** + * @brief Test if string doesn't follow string. + * @param lhs First string. + * @param rhs Second string. + * @return True if @a lhs doesn't follow @a rhs. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline bool + operator<=(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) + { return __lhs.compare(__rhs) <= 0; } + + /** + * @brief Test if string doesn't follow C string. + * @param lhs String. + * @param rhs C string. + * @return True if @a lhs doesn't follow @a rhs. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline bool + operator<=(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) <= 0; } + + /** + * @brief Test if C string doesn't follow string. + * @param lhs C string. + * @param rhs String. + * @return True if @a lhs doesn't follow @a rhs. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline bool + operator<=(const _CharT* __lhs, + const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) + { return __rhs.compare(__lhs) >= 0; } + + // operator >= + /** + * @brief Test if string doesn't precede string. + * @param lhs First string. + * @param rhs Second string. + * @return True if @a lhs doesn't precede @a rhs. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline bool + operator>=(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) + { return __lhs.compare(__rhs) >= 0; } + + /** + * @brief Test if string doesn't precede C string. + * @param lhs String. + * @param rhs C string. + * @return True if @a lhs doesn't precede @a rhs. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline bool + operator>=(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + const _CharT* __rhs) + { return __lhs.compare(__rhs) >= 0; } + + /** + * @brief Test if C string doesn't precede string. + * @param lhs C string. + * @param rhs String. + * @return True if @a lhs doesn't precede @a rhs. False otherwise. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline bool + operator>=(const _CharT* __lhs, + const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) + { return __rhs.compare(__lhs) <= 0; } + + /** + * @brief Swap contents of two strings. + * @param lhs First string. + * @param rhs Second string. + * + * Exchanges the contents of @a lhs and @a rhs in constant time. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline void + swap(__versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) + { __lhs.swap(__rhs); } + +_GLIBCXX_END_NAMESPACE + +_GLIBCXX_BEGIN_NAMESPACE(std) + + /** + * @brief Read stream into a string. + * @param is Input stream. + * @param str Buffer to store into. + * @return Reference to the input stream. + * + * Stores characters from @a is into @a str until whitespace is found, the + * end of the stream is encountered, or str.max_size() is reached. If + * is.width() is non-zero, that is the limit on the number of characters + * stored into @a str. Any previous contents of @a str are erased. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __is, + __gnu_cxx::__versa_string<_CharT, _Traits, + _Alloc, _Base>& __str); + + /** + * @brief Write string to a stream. + * @param os Output stream. + * @param str String to write out. + * @return Reference to the output stream. + * + * Output characters of @a str into os following the same rules as for + * writing a C string. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, + const __gnu_cxx::__versa_string<_CharT, _Traits, + _Alloc, _Base>& __str) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 586. string inserter not a formatted function + return __ostream_insert(__os, __str.data(), __str.size()); + } + + /** + * @brief Read a line from stream into a string. + * @param is Input stream. + * @param str Buffer to store into. + * @param delim Character marking end of line. + * @return Reference to the input stream. + * + * Stores characters from @a is into @a str until @a delim is found, the + * end of the stream is encountered, or str.max_size() is reached. If + * is.width() is non-zero, that is the limit on the number of characters + * stored into @a str. Any previous contents of @a str are erased. If @a + * delim was encountered, it is extracted but not stored into @a str. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + basic_istream<_CharT, _Traits>& + getline(basic_istream<_CharT, _Traits>& __is, + __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>& __str, + _CharT __delim); + + /** + * @brief Read a line from stream into a string. + * @param is Input stream. + * @param str Buffer to store into. + * @return Reference to the input stream. + * + * Stores characters from is into @a str until '\n' is found, the end of + * the stream is encountered, or str.max_size() is reached. If is.width() + * is non-zero, that is the limit on the number of characters stored into + * @a str. Any previous contents of @a str are erased. If end of line was + * encountered, it is extracted but not stored into @a str. + */ + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + inline basic_istream<_CharT, _Traits>& + getline(basic_istream<_CharT, _Traits>& __is, + __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>& __str) + { return getline(__is, __str, __is.widen('\n')); } + +_GLIBCXX_END_NAMESPACE + +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include "vstring.tcc" +#endif + +#endif /* _VSTRING_H */ diff --git a/contrib/libstdc++/include/ext/vstring.tcc b/contrib/libstdc++/include/ext/vstring.tcc new file mode 100644 index 000000000000..3e4cd773959a --- /dev/null +++ b/contrib/libstdc++/include/ext/vstring.tcc @@ -0,0 +1,690 @@ +// Versatile string -*- C++ -*- + +// Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/** @file ext/vstring.tcc + * This file is a GNU extension to the Standard C++ Library. + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _VSTRING_TCC +#define _VSTRING_TCC 1 + +#pragma GCC system_header + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + const typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type + __versa_string<_CharT, _Traits, _Alloc, _Base>::npos; + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + void + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + resize(size_type __n, _CharT __c) + { + const size_type __size = this->size(); + if (__size < __n) + this->append(__n - __size, __c); + else if (__n < __size) + this->_M_erase(__n, __size - __n); + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + __versa_string<_CharT, _Traits, _Alloc, _Base>& + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + _M_append(const _CharT* __s, size_type __n) + { + const size_type __len = __n + this->size(); + + if (__len <= this->capacity() && !this->_M_is_shared()) + { + if (__n) + this->_S_copy(this->_M_data() + this->size(), __s, __n); + } + else + this->_M_mutate(this->size(), size_type(0), __s, __n); + + this->_M_set_length(__len); + return *this; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + template<typename _InputIterator> + __versa_string<_CharT, _Traits, _Alloc, _Base>& + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1, + _InputIterator __k2, std::__false_type) + { + const __versa_string __s(__k1, __k2); + const size_type __n1 = __i2 - __i1; + return _M_replace(__i1 - _M_ibegin(), __n1, __s._M_data(), + __s.size()); + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + __versa_string<_CharT, _Traits, _Alloc, _Base>& + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2, + _CharT __c) + { + _M_check_length(__n1, __n2, "__versa_string::_M_replace_aux"); + + const size_type __old_size = this->size(); + const size_type __new_size = __old_size + __n2 - __n1; + + if (__new_size <= this->capacity() && !this->_M_is_shared()) + { + _CharT* __p = this->_M_data() + __pos1; + + const size_type __how_much = __old_size - __pos1 - __n1; + if (__how_much && __n1 != __n2) + this->_S_move(__p + __n2, __p + __n1, __how_much); + } + else + this->_M_mutate(__pos1, __n1, 0, __n2); + + if (__n2) + this->_S_assign(this->_M_data() + __pos1, __n2, __c); + + this->_M_set_length(__new_size); + return *this; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + __versa_string<_CharT, _Traits, _Alloc, _Base>& + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + _M_replace(size_type __pos, size_type __len1, const _CharT* __s, + const size_type __len2) + { + _M_check_length(__len1, __len2, "__versa_string::_M_replace"); + + const size_type __old_size = this->size(); + const size_type __new_size = __old_size + __len2 - __len1; + + if (__new_size <= this->capacity() && !this->_M_is_shared()) + { + _CharT* __p = this->_M_data() + __pos; + + const size_type __how_much = __old_size - __pos - __len1; + if (_M_disjunct(__s)) + { + if (__how_much && __len1 != __len2) + this->_S_move(__p + __len2, __p + __len1, __how_much); + if (__len2) + this->_S_copy(__p, __s, __len2); + } + else + { + // Work in-place. + if (__len2 && __len2 <= __len1) + this->_S_move(__p, __s, __len2); + if (__how_much && __len1 != __len2) + this->_S_move(__p + __len2, __p + __len1, __how_much); + if (__len2 > __len1) + { + if (__s + __len2 <= __p + __len1) + this->_S_move(__p, __s, __len2); + else if (__s >= __p + __len1) + this->_S_copy(__p, __s + __len2 - __len1, __len2); + else + { + const size_type __nleft = (__p + __len1) - __s; + this->_S_move(__p, __s, __nleft); + this->_S_copy(__p + __nleft, __p + __len2, + __len2 - __nleft); + } + } + } + } + else + this->_M_mutate(__pos, __len1, __s, __len2); + + this->_M_set_length(__new_size); + return *this; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + __versa_string<_CharT, _Traits, _Alloc, _Base> + operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) + { + __versa_string<_CharT, _Traits, _Alloc, _Base> __str; + __str.reserve(__lhs.size() + __rhs.size()); + __str.append(__lhs); + __str.append(__rhs); + return __str; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + __versa_string<_CharT, _Traits, _Alloc, _Base> + operator+(const _CharT* __lhs, + const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) + { + __glibcxx_requires_string(__lhs); + typedef __versa_string<_CharT, _Traits, _Alloc, _Base> __string_type; + typedef typename __string_type::size_type __size_type; + const __size_type __len = _Traits::length(__lhs); + __string_type __str; + __str.reserve(__len + __rhs.size()); + __str.append(__lhs, __len); + __str.append(__rhs); + return __str; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + __versa_string<_CharT, _Traits, _Alloc, _Base> + operator+(_CharT __lhs, + const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) + { + __versa_string<_CharT, _Traits, _Alloc, _Base> __str; + __str.reserve(__rhs.size() + 1); + __str.push_back(__lhs); + __str.append(__rhs); + return __str; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + __versa_string<_CharT, _Traits, _Alloc, _Base> + operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + const _CharT* __rhs) + { + __glibcxx_requires_string(__rhs); + typedef __versa_string<_CharT, _Traits, _Alloc, _Base> __string_type; + typedef typename __string_type::size_type __size_type; + const __size_type __len = _Traits::length(__rhs); + __string_type __str; + __str.reserve(__lhs.size() + __len); + __str.append(__lhs); + __str.append(__rhs, __len); + return __str; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + __versa_string<_CharT, _Traits, _Alloc, _Base> + operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, + _CharT __rhs) + { + __versa_string<_CharT, _Traits, _Alloc, _Base> __str; + __str.reserve(__lhs.size() + 1); + __str.append(__lhs); + __str.push_back(__rhs); + return __str; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + copy(_CharT* __s, size_type __n, size_type __pos) const + { + _M_check(__pos, "__versa_string::copy"); + __n = _M_limit(__pos, __n); + __glibcxx_requires_string_len(__s, __n); + if (__n) + this->_S_copy(__s, this->_M_data() + __pos, __n); + // 21.3.5.7 par 3: do not append null. (good.) + return __n; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + find(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_requires_string_len(__s, __n); + const size_type __size = this->size(); + const _CharT* __data = this->_M_data(); + + if (__n == 0) + return __pos <= __size ? __pos : npos; + + if (__n <= __size) + { + for (; __pos <= __size - __n; ++__pos) + if (traits_type::eq(__data[__pos], __s[0]) + && traits_type::compare(__data + __pos + 1, + __s + 1, __n - 1) == 0) + return __pos; + } + return npos; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + find(_CharT __c, size_type __pos) const + { + size_type __ret = npos; + const size_type __size = this->size(); + if (__pos < __size) + { + const _CharT* __data = this->_M_data(); + const size_type __n = __size - __pos; + const _CharT* __p = traits_type::find(__data + __pos, __n, __c); + if (__p) + __ret = __p - __data; + } + return __ret; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + rfind(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_requires_string_len(__s, __n); + const size_type __size = this->size(); + if (__n <= __size) + { + __pos = std::min(size_type(__size - __n), __pos); + const _CharT* __data = this->_M_data(); + do + { + if (traits_type::compare(__data + __pos, __s, __n) == 0) + return __pos; + } + while (__pos-- > 0); + } + return npos; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + rfind(_CharT __c, size_type __pos) const + { + size_type __size = this->size(); + if (__size) + { + if (--__size > __pos) + __size = __pos; + for (++__size; __size-- > 0; ) + if (traits_type::eq(this->_M_data()[__size], __c)) + return __size; + } + return npos; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + find_first_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_requires_string_len(__s, __n); + for (; __n && __pos < this->size(); ++__pos) + { + const _CharT* __p = traits_type::find(__s, __n, + this->_M_data()[__pos]); + if (__p) + return __pos; + } + return npos; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + find_last_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_requires_string_len(__s, __n); + size_type __size = this->size(); + if (__size && __n) + { + if (--__size > __pos) + __size = __pos; + do + { + if (traits_type::find(__s, __n, this->_M_data()[__size])) + return __size; + } + while (__size-- != 0); + } + return npos; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_requires_string_len(__s, __n); + for (; __pos < this->size(); ++__pos) + if (!traits_type::find(__s, __n, this->_M_data()[__pos])) + return __pos; + return npos; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + find_first_not_of(_CharT __c, size_type __pos) const + { + for (; __pos < this->size(); ++__pos) + if (!traits_type::eq(this->_M_data()[__pos], __c)) + return __pos; + return npos; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_requires_string_len(__s, __n); + size_type __size = this->size(); + if (__size) + { + if (--__size > __pos) + __size = __pos; + do + { + if (!traits_type::find(__s, __n, this->_M_data()[__size])) + return __size; + } + while (__size--); + } + return npos; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + find_last_not_of(_CharT __c, size_type __pos) const + { + size_type __size = this->size(); + if (__size) + { + if (--__size > __pos) + __size = __pos; + do + { + if (!traits_type::eq(this->_M_data()[__size], __c)) + return __size; + } + while (__size--); + } + return npos; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + int + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + compare(size_type __pos, size_type __n, const __versa_string& __str) const + { + _M_check(__pos, "__versa_string::compare"); + __n = _M_limit(__pos, __n); + const size_type __osize = __str.size(); + const size_type __len = std::min(__n, __osize); + int __r = traits_type::compare(this->_M_data() + __pos, + __str.data(), __len); + if (!__r) + __r = __n - __osize; + return __r; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + int + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + compare(size_type __pos1, size_type __n1, const __versa_string& __str, + size_type __pos2, size_type __n2) const + { + _M_check(__pos1, "__versa_string::compare"); + __str._M_check(__pos2, "__versa_string::compare"); + __n1 = _M_limit(__pos1, __n1); + __n2 = __str._M_limit(__pos2, __n2); + const size_type __len = std::min(__n1, __n2); + int __r = traits_type::compare(this->_M_data() + __pos1, + __str.data() + __pos2, __len); + if (!__r) + __r = __n1 - __n2; + return __r; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + int + __versa_string<_CharT, _Traits, _Alloc, _Base>:: + compare(const _CharT* __s) const + { + __glibcxx_requires_string(__s); + const size_type __size = this->size(); + const size_type __osize = traits_type::length(__s); + const size_type __len = std::min(__size, __osize); + int __r = traits_type::compare(this->_M_data(), __s, __len); + if (!__r) + __r = __size - __osize; + return __r; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + int + __versa_string <_CharT, _Traits, _Alloc, _Base>:: + compare(size_type __pos, size_type __n1, const _CharT* __s) const + { + __glibcxx_requires_string(__s); + _M_check(__pos, "__versa_string::compare"); + __n1 = _M_limit(__pos, __n1); + const size_type __osize = traits_type::length(__s); + const size_type __len = std::min(__n1, __osize); + int __r = traits_type::compare(this->_M_data() + __pos, __s, __len); + if (!__r) + __r = __n1 - __osize; + return __r; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + int + __versa_string <_CharT, _Traits, _Alloc, _Base>:: + compare(size_type __pos, size_type __n1, const _CharT* __s, + size_type __n2) const + { + __glibcxx_requires_string_len(__s, __n2); + _M_check(__pos, "__versa_string::compare"); + __n1 = _M_limit(__pos, __n1); + const size_type __len = std::min(__n1, __n2); + int __r = traits_type::compare(this->_M_data() + __pos, __s, __len); + if (!__r) + __r = __n1 - __n2; + return __r; + } + +_GLIBCXX_END_NAMESPACE + +_GLIBCXX_BEGIN_NAMESPACE(std) + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>& __in, + __gnu_cxx::__versa_string<_CharT, _Traits, + _Alloc, _Base>& __str) + { + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::int_type __int_type; + typedef typename __istream_type::__streambuf_type __streambuf_type; + typedef typename __istream_type::__ctype_type __ctype_type; + typedef __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base> + __string_type; + typedef typename __string_type::size_type __size_type; + + __size_type __extracted = 0; + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + typename __istream_type::sentry __cerb(__in, false); + if (__cerb) + { + try + { + // Avoid reallocation for common case. + __str.erase(); + _CharT __buf[128]; + __size_type __len = 0; + const streamsize __w = __in.width(); + const __size_type __n = __w > 0 ? static_cast<__size_type>(__w) + : __str.max_size(); + const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); + const __int_type __eof = _Traits::eof(); + __streambuf_type* __sb = __in.rdbuf(); + __int_type __c = __sb->sgetc(); + + while (__extracted < __n + && !_Traits::eq_int_type(__c, __eof) + && !__ct.is(ctype_base::space, _Traits::to_char_type(__c))) + { + if (__len == sizeof(__buf) / sizeof(_CharT)) + { + __str.append(__buf, sizeof(__buf) / sizeof(_CharT)); + __len = 0; + } + __buf[__len++] = _Traits::to_char_type(__c); + ++__extracted; + __c = __sb->snextc(); + } + __str.append(__buf, __len); + + if (_Traits::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + __in.width(0); + } + catch(...) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 91. Description of operator>> and getline() for string<> + // might cause endless loop + __in._M_setstate(ios_base::badbit); + } + } + // 211. operator>>(istream&, string&) doesn't set failbit + if (!__extracted) + __err |= ios_base::failbit; + if (__err) + __in.setstate(__err); + return __in; + } + + template<typename _CharT, typename _Traits, typename _Alloc, + template <typename, typename, typename> class _Base> + basic_istream<_CharT, _Traits>& + getline(basic_istream<_CharT, _Traits>& __in, + __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>& __str, + _CharT __delim) + { + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::int_type __int_type; + typedef typename __istream_type::__streambuf_type __streambuf_type; + typedef typename __istream_type::__ctype_type __ctype_type; + typedef __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base> + __string_type; + typedef typename __string_type::size_type __size_type; + + __size_type __extracted = 0; + const __size_type __n = __str.max_size(); + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + typename __istream_type::sentry __cerb(__in, true); + if (__cerb) + { + try + { + // Avoid reallocation for common case. + __str.erase(); + _CharT __buf[128]; + __size_type __len = 0; + const __int_type __idelim = _Traits::to_int_type(__delim); + const __int_type __eof = _Traits::eof(); + __streambuf_type* __sb = __in.rdbuf(); + __int_type __c = __sb->sgetc(); + + while (__extracted < __n + && !_Traits::eq_int_type(__c, __eof) + && !_Traits::eq_int_type(__c, __idelim)) + { + if (__len == sizeof(__buf) / sizeof(_CharT)) + { + __str.append(__buf, sizeof(__buf) / sizeof(_CharT)); + __len = 0; + } + __buf[__len++] = _Traits::to_char_type(__c); + ++__extracted; + __c = __sb->snextc(); + } + __str.append(__buf, __len); + + if (_Traits::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + else if (_Traits::eq_int_type(__c, __idelim)) + { + ++__extracted; + __sb->sbumpc(); + } + else + __err |= ios_base::failbit; + } + catch(...) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 91. Description of operator>> and getline() for string<> + // might cause endless loop + __in._M_setstate(ios_base::badbit); + } + } + if (!__extracted) + __err |= ios_base::failbit; + if (__err) + __in.setstate(__err); + return __in; + } + +_GLIBCXX_END_NAMESPACE + +#endif // _VSTRING_TCC diff --git a/contrib/libstdc++/include/ext/vstring_fwd.h b/contrib/libstdc++/include/ext/vstring_fwd.h new file mode 100644 index 000000000000..953700676466 --- /dev/null +++ b/contrib/libstdc++/include/ext/vstring_fwd.h @@ -0,0 +1,75 @@ +// Versatile string forward -*- C++ -*- + +// Copyright (C) 2005 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/** @file ext/vstring_fwd.h + * This file is a GNU extension to the Standard C++ Library. + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _VSTRING_FWD_H +#define _VSTRING_FWD_H 1 + +#pragma GCC system_header + +#include <bits/c++config.h> +#include <bits/char_traits.h> +#include <memory> // For allocator. + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + template<typename _CharT, typename _Traits, typename _Alloc> + class __sso_string_base; + + template<typename _CharT, typename _Traits, typename _Alloc> + class __rc_string_base; + + template<typename _CharT, typename _Traits = std::char_traits<_CharT>, + typename _Alloc = std::allocator<_CharT>, + template + <typename, typename, typename> class _Base = __sso_string_base> + class __versa_string; + + typedef __versa_string<char> __vstring; + typedef __vstring __sso_string; + typedef + __versa_string<char, std::char_traits<char>, + std::allocator<char>, __rc_string_base> __rc_string; + +#ifdef _GLIBCXX_USE_WCHAR_T + typedef __versa_string<wchar_t> __wvstring; + typedef __wvstring __wsso_string; + typedef + __versa_string<wchar_t, std::char_traits<wchar_t>, + std::allocator<wchar_t>, __rc_string_base> __wrc_string; +#endif + +_GLIBCXX_END_NAMESPACE + +#endif /* _VSTRING_FWD_H */ diff --git a/contrib/libstdc++/include/ext/vstring_util.h b/contrib/libstdc++/include/ext/vstring_util.h new file mode 100644 index 000000000000..5ff3034fc5b6 --- /dev/null +++ b/contrib/libstdc++/include/ext/vstring_util.h @@ -0,0 +1,177 @@ +// Versatile string utility -*- C++ -*- + +// Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/** @file ext/vstring_util.h + * This file is a GNU extension to the Standard C++ Library. + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _VSTRING_UTIL_H +#define _VSTRING_UTIL_H 1 + +#pragma GCC system_header + +#include <ext/vstring_fwd.h> +#include <debug/debug.h> +#include <bits/stl_function.h> // For less +#include <bits/functexcept.h> +#include <locale> +#include <algorithm> // For std::distance, srd::search. +#include <bits/ostream_insert.h> + +_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) + + template<typename _CharT, typename _Traits, typename _Alloc> + struct __vstring_utility + { + typedef typename _Alloc::template rebind<_CharT>::other _CharT_alloc_type; + + typedef _Traits traits_type; + typedef typename _Traits::char_type value_type; + typedef typename _CharT_alloc_type::size_type size_type; + typedef typename _CharT_alloc_type::pointer pointer; + typedef typename _CharT_alloc_type::const_pointer const_pointer; + + // For __sso_string. + typedef __gnu_cxx:: + __normal_iterator<pointer, __gnu_cxx:: + __versa_string<_CharT, _Traits, _Alloc, + __sso_string_base> > + __sso_iterator; + typedef __gnu_cxx:: + __normal_iterator<const_pointer, __gnu_cxx:: + __versa_string<_CharT, _Traits, _Alloc, + __sso_string_base> > + __const_sso_iterator; + + // For __rc_string. + typedef __gnu_cxx:: + __normal_iterator<pointer, __gnu_cxx:: + __versa_string<_CharT, _Traits, _Alloc, + __rc_string_base> > + __rc_iterator; + typedef __gnu_cxx:: + __normal_iterator<const_pointer, __gnu_cxx:: + __versa_string<_CharT, _Traits, _Alloc, + __rc_string_base> > + __const_rc_iterator; + + // NB: When the allocator is empty, deriving from it saves space + // (http://www.cantrip.org/emptyopt.html). + template<typename _Alloc1> + struct _Alloc_hider + : public _Alloc1 + { + _Alloc_hider(const _Alloc1& __a, _CharT* __ptr) + : _Alloc1(__a), _M_p(__ptr) { } + + _CharT* _M_p; // The actual data. + }; + + // For use in _M_construct (_S_construct) forward_iterator_tag. + template<typename _Type> + static bool + _S_is_null_pointer(_Type* __ptr) + { return __ptr == 0; } + + template<typename _Type> + static bool + _S_is_null_pointer(_Type) + { return false; } + + // When __n = 1 way faster than the general multichar + // traits_type::copy/move/assign. + static void + _S_copy(_CharT* __d, const _CharT* __s, size_type __n) + { + if (__n == 1) + traits_type::assign(*__d, *__s); + else + traits_type::copy(__d, __s, __n); + } + + static void + _S_move(_CharT* __d, const _CharT* __s, size_type __n) + { + if (__n == 1) + traits_type::assign(*__d, *__s); + else + traits_type::move(__d, __s, __n); + } + + static void + _S_assign(_CharT* __d, size_type __n, _CharT __c) + { + if (__n == 1) + traits_type::assign(*__d, __c); + else + traits_type::assign(__d, __n, __c); + } + + // _S_copy_chars is a separate template to permit specialization + // to optimize for the common case of pointers as iterators. + template<typename _Iterator> + static void + _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2) + { + for (; __k1 != __k2; ++__k1, ++__p) + traits_type::assign(*__p, *__k1); // These types are off. + } + + static void + _S_copy_chars(_CharT* __p, __sso_iterator __k1, __sso_iterator __k2) + { _S_copy_chars(__p, __k1.base(), __k2.base()); } + + static void + _S_copy_chars(_CharT* __p, __const_sso_iterator __k1, + __const_sso_iterator __k2) + { _S_copy_chars(__p, __k1.base(), __k2.base()); } + + static void + _S_copy_chars(_CharT* __p, __rc_iterator __k1, __rc_iterator __k2) + { _S_copy_chars(__p, __k1.base(), __k2.base()); } + + static void + _S_copy_chars(_CharT* __p, __const_rc_iterator __k1, + __const_rc_iterator __k2) + { _S_copy_chars(__p, __k1.base(), __k2.base()); } + + static void + _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2) + { _S_copy(__p, __k1, __k2 - __k1); } + + static void + _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2) + { _S_copy(__p, __k1, __k2 - __k1); } + }; + +_GLIBCXX_END_NAMESPACE + +#endif /* _VSTRING_UTIL_H */ |