Initial commit

This commit is contained in:
Eagle517
2026-01-14 10:27:57 -06:00
commit c1576fee30
11290 changed files with 1552799 additions and 0 deletions

View File

@@ -0,0 +1,536 @@
// Algorithm extensions -*- C++ -*-
// Copyright (C) 2001, 2002 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
/*
*
* 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.
*
*
* Copyright (c) 1996
* 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.
*/
/** @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.
*/
#ifndef _EXT_ALGORITHM
#define _EXT_ALGORITHM
#pragma GCC system_header
#include <algorithm>
namespace __gnu_cxx
{
using std::ptrdiff_t;
using std::min;
using std::pair;
using std::input_iterator_tag;
using std::random_access_iterator_tag;
using std::iterator_traits;
//--------------------------------------------------
// copy_n (not part of the C++ standard)
template<typename _InputIter, typename _Size, typename _OutputIter>
pair<_InputIter, _OutputIter>
__copy_n(_InputIter __first, _Size __count,
_OutputIter __result,
input_iterator_tag)
{
for ( ; __count > 0; --__count) {
*__result = *__first;
++__first;
++__result;
}
return pair<_InputIter, _OutputIter>(__first, __result);
}
template<typename _RAIter, typename _Size, typename _OutputIter>
inline pair<_RAIter, _OutputIter>
__copy_n(_RAIter __first, _Size __count,
_OutputIter __result,
random_access_iterator_tag)
{
_RAIter __last = __first + __count;
return pair<_RAIter, _OutputIter>(__last,
std::copy(__first, __last, __result));
}
/**
* @brief Copies the range [first,first+count) into [result,result+count).
* @param first An input iterator.
* @param count The number of elements to copy.
* @param result An output iterator.
* @return A std::pair composed of first+count and result+count.
*
* This is an SGI extension.
* This inline function will boil down to a call to @c memmove whenever
* possible. Failing that, if random access iterators are passed, then the
* loop count will be known (and therefore a candidate for compiler
* optimizations such as unrolling).
* @ingroup SGIextensions
*/
template<typename _InputIter, typename _Size, typename _OutputIter>
inline pair<_InputIter, _OutputIter>
copy_n(_InputIter __first, _Size __count, _OutputIter __result)
{
// concept requirements
__glibcpp_function_requires(_InputIteratorConcept<_InputIter>)
__glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
typename iterator_traits<_InputIter>::value_type>)
return __copy_n(__first, __count, __result,
std::__iterator_category(__first));
}
template<typename _InputIter1, typename _InputIter2>
int
__lexicographical_compare_3way(_InputIter1 __first1, _InputIter1 __last1,
_InputIter2 __first2, _InputIter2 __last2)
{
while (__first1 != __last1 && __first2 != __last2) {
if (*__first1 < *__first2)
return -1;
if (*__first2 < *__first1)
return 1;
++__first1;
++__first2;
}
if (__first2 == __last2) {
return !(__first1 == __last1);
}
else {
return -1;
}
}
inline int
__lexicographical_compare_3way(const unsigned char* __first1,
const unsigned char* __last1,
const unsigned char* __first2,
const unsigned char* __last2)
{
const ptrdiff_t __len1 = __last1 - __first1;
const ptrdiff_t __len2 = __last2 - __first2;
const int __result = std::memcmp(__first1, __first2, min(__len1, __len2));
return __result != 0 ? __result
: (__len1 == __len2 ? 0 : (__len1 < __len2 ? -1 : 1));
}
inline int
__lexicographical_compare_3way(const char* __first1, const char* __last1,
const char* __first2, const char* __last2)
{
#if CHAR_MAX == SCHAR_MAX
return __lexicographical_compare_3way(
(const signed char*) __first1,
(const signed char*) __last1,
(const signed char*) __first2,
(const signed char*) __last2);
#else
return __lexicographical_compare_3way((const unsigned char*) __first1,
(const unsigned char*) __last1,
(const unsigned char*) __first2,
(const unsigned char*) __last2);
#endif
}
/**
* @brief @c memcmp on steroids.
* @param first1 An input iterator.
* @param last1 An input iterator.
* @param first2 An input iterator.
* @param last2 An input iterator.
* @return An int, as with @c memcmp.
*
* The return value will be less than zero if the first range is
* "lexigraphically less than" the second, greater than zero if the second
* range is "lexigraphically less than" the first, and zero otherwise.
* This is an SGI extension.
* @ingroup SGIextensions
*/
template<typename _InputIter1, typename _InputIter2>
int
lexicographical_compare_3way(_InputIter1 __first1, _InputIter1 __last1,
_InputIter2 __first2, _InputIter2 __last2)
{
// concept requirements
__glibcpp_function_requires(_InputIteratorConcept<_InputIter1>)
__glibcpp_function_requires(_InputIteratorConcept<_InputIter2>)
__glibcpp_function_requires(_LessThanComparableConcept<
typename iterator_traits<_InputIter1>::value_type>)
__glibcpp_function_requires(_LessThanComparableConcept<
typename iterator_traits<_InputIter2>::value_type>)
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 _InputIter, typename _Tp, typename _Size>
void
count(_InputIter __first, _InputIter __last,
const _Tp& __value,
_Size& __n)
{
// concept requirements
__glibcpp_function_requires(_InputIteratorConcept<_InputIter>)
__glibcpp_function_requires(_EqualityComparableConcept<
typename iterator_traits<_InputIter>::value_type >)
__glibcpp_function_requires(_EqualityComparableConcept<_Tp>)
for ( ; __first != __last; ++__first)
if (*__first == __value)
++__n;
}
template<typename _InputIter, typename _Predicate, typename _Size>
void
count_if(_InputIter __first, _InputIter __last,
_Predicate __pred,
_Size& __n)
{
// concept requirements
__glibcpp_function_requires(_InputIteratorConcept<_InputIter>)
__glibcpp_function_requires(_UnaryPredicateConcept<_Predicate,
typename iterator_traits<_InputIter>::value_type>)
for ( ; __first != __last; ++__first)
if (__pred(*__first))
++__n;
}
// random_sample and random_sample_n (extensions, not part of the standard).
/**
* This is an SGI extension.
* @ingroup SGIextensions
* @doctodo
*/
template<typename _ForwardIter, typename _OutputIter, typename _Distance>
_OutputIter
random_sample_n(_ForwardIter __first, _ForwardIter __last,
_OutputIter __out, const _Distance __n)
{
// concept requirements
__glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>)
__glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
typename iterator_traits<_ForwardIter>::value_type>)
_Distance __remaining = std::distance(__first, __last);
_Distance __m = min(__n, __remaining);
while (__m > 0) {
if (std::__random_number(__remaining) < __m) {
*__out = *__first;
++__out;
--__m;
}
--__remaining;
++__first;
}
return __out;
}
/**
* This is an SGI extension.
* @ingroup SGIextensions
* @doctodo
*/
template<typename _ForwardIter, typename _OutputIter, typename _Distance,
typename _RandomNumberGenerator>
_OutputIter
random_sample_n(_ForwardIter __first, _ForwardIter __last,
_OutputIter __out, const _Distance __n,
_RandomNumberGenerator& __rand)
{
// concept requirements
__glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>)
__glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
typename iterator_traits<_ForwardIter>::value_type>)
__glibcpp_function_requires(_UnaryFunctionConcept<
_RandomNumberGenerator, _Distance, _Distance>)
_Distance __remaining = std::distance(__first, __last);
_Distance __m = min(__n, __remaining);
while (__m > 0) {
if (__rand(__remaining) < __m) {
*__out = *__first;
++__out;
--__m;
}
--__remaining;
++__first;
}
return __out;
}
template<typename _InputIter, typename _RandomAccessIter, typename _Distance>
_RandomAccessIter
__random_sample(_InputIter __first, _InputIter __last,
_RandomAccessIter __out,
const _Distance __n)
{
_Distance __m = 0;
_Distance __t = __n;
for ( ; __first != __last && __m < __n; ++__m, ++__first)
__out[__m] = *__first;
while (__first != __last) {
++__t;
_Distance __M = std::__random_number(__t);
if (__M < __n)
__out[__M] = *__first;
++__first;
}
return __out + __m;
}
template<typename _InputIter, typename _RandomAccessIter,
typename _RandomNumberGenerator, typename _Distance>
_RandomAccessIter
__random_sample(_InputIter __first, _InputIter __last,
_RandomAccessIter __out,
_RandomNumberGenerator& __rand,
const _Distance __n)
{
// concept requirements
__glibcpp_function_requires(_UnaryFunctionConcept<
_RandomNumberGenerator, _Distance, _Distance>)
_Distance __m = 0;
_Distance __t = __n;
for ( ; __first != __last && __m < __n; ++__m, ++__first)
__out[__m] = *__first;
while (__first != __last) {
++__t;
_Distance __M = __rand(__t);
if (__M < __n)
__out[__M] = *__first;
++__first;
}
return __out + __m;
}
/**
* This is an SGI extension.
* @ingroup SGIextensions
* @doctodo
*/
template<typename _InputIter, typename _RandomAccessIter>
inline _RandomAccessIter
random_sample(_InputIter __first, _InputIter __last,
_RandomAccessIter __out_first, _RandomAccessIter __out_last)
{
// concept requirements
__glibcpp_function_requires(_InputIteratorConcept<_InputIter>)
__glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIter>)
return __random_sample(__first, __last,
__out_first, __out_last - __out_first);
}
/**
* This is an SGI extension.
* @ingroup SGIextensions
* @doctodo
*/
template<typename _InputIter, typename _RandomAccessIter,
typename _RandomNumberGenerator>
inline _RandomAccessIter
random_sample(_InputIter __first, _InputIter __last,
_RandomAccessIter __out_first, _RandomAccessIter __out_last,
_RandomNumberGenerator& __rand)
{
// concept requirements
__glibcpp_function_requires(_InputIteratorConcept<_InputIter>)
__glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<
_RandomAccessIter>)
return __random_sample(__first, __last,
__out_first, __rand,
__out_last - __out_first);
}
// is_heap, a predicate testing whether or not a range is
// a heap. This function is an extension, not part of the C++
// standard.
template<typename _RandomAccessIter, typename _Distance>
bool
__is_heap(_RandomAccessIter __first, _Distance __n)
{
_Distance __parent = 0;
for (_Distance __child = 1; __child < __n; ++__child) {
if (__first[__parent] < __first[__child])
return false;
if ((__child & 1) == 0)
++__parent;
}
return true;
}
template<typename _RandomAccessIter, typename _Distance,
typename _StrictWeakOrdering>
bool
__is_heap(_RandomAccessIter __first, _StrictWeakOrdering __comp,
_Distance __n)
{
_Distance __parent = 0;
for (_Distance __child = 1; __child < __n; ++__child) {
if (__comp(__first[__parent], __first[__child]))
return false;
if ((__child & 1) == 0)
++__parent;
}
return true;
}
/**
* This is an SGI extension.
* @ingroup SGIextensions
* @doctodo
*/
template<typename _RandomAccessIter>
inline bool
is_heap(_RandomAccessIter __first, _RandomAccessIter __last)
{
// concept requirements
__glibcpp_function_requires(_RandomAccessIteratorConcept<_RandomAccessIter>)
__glibcpp_function_requires(_LessThanComparableConcept<
typename iterator_traits<_RandomAccessIter>::value_type>)
return __is_heap(__first, __last - __first);
}
/**
* This is an SGI extension.
* @ingroup SGIextensions
* @doctodo
*/
template<typename _RandomAccessIter, typename _StrictWeakOrdering>
inline bool
is_heap(_RandomAccessIter __first, _RandomAccessIter __last,
_StrictWeakOrdering __comp)
{
// concept requirements
__glibcpp_function_requires(_RandomAccessIteratorConcept<_RandomAccessIter>)
__glibcpp_function_requires(_BinaryPredicateConcept<_StrictWeakOrdering,
typename iterator_traits<_RandomAccessIter>::value_type,
typename iterator_traits<_RandomAccessIter>::value_type>)
return __is_heap(__first, __comp, __last - __first);
}
// is_sorted, a predicated testing whether a range is sorted in
// nondescending order. This is an extension, not part of the C++
// standard.
/**
* This is an SGI extension.
* @ingroup SGIextensions
* @doctodo
*/
template<typename _ForwardIter>
bool
is_sorted(_ForwardIter __first, _ForwardIter __last)
{
// concept requirements
__glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>)
__glibcpp_function_requires(_LessThanComparableConcept<
typename iterator_traits<_ForwardIter>::value_type>)
if (__first == __last)
return true;
_ForwardIter __next = __first;
for (++__next; __next != __last; __first = __next, ++__next) {
if (*__next < *__first)
return false;
}
return true;
}
/**
* This is an SGI extension.
* @ingroup SGIextensions
* @doctodo
*/
template<typename _ForwardIter, typename _StrictWeakOrdering>
bool
is_sorted(_ForwardIter __first, _ForwardIter __last, _StrictWeakOrdering __comp)
{
// concept requirements
__glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>)
__glibcpp_function_requires(_BinaryPredicateConcept<_StrictWeakOrdering,
typename iterator_traits<_ForwardIter>::value_type,
typename iterator_traits<_ForwardIter>::value_type>)
if (__first == __last)
return true;
_ForwardIter __next = __first;
for (++__next; __next != __last; __first = __next, ++__next) {
if (__comp(*__next, *__first))
return false;
}
return true;
}
} // namespace __gnu_cxx
#endif /* _EXT_ALGORITHM */

View File

@@ -0,0 +1,61 @@
// __enc_traits layer for filebuf -*- C++ -*-
// Copyright (C) 2002 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
#include <fstream>
#include <locale>
namespace __gnu_cxx
{
// Custom traits type with __enc_traits for state type, all other bits
// equivalent to the required char_traits instantiations.
template<typename _CharT>
struct enc_char_traits: public std::char_traits<_CharT>
{
typedef std::__enc_traits state_type;
};
template<typename _CharT>
class enc_filebuf
: public std::basic_filebuf<_CharT, enc_char_traits<_CharT> >
{
public:
typedef typename enc_char_traits<_CharT>::state_type state_type;
enc_filebuf(state_type& __state)
: std::basic_filebuf<_CharT, enc_char_traits<_CharT> >()
{
// Set state type to something useful.
// Something more than copyconstructible is needed here, so
// require copyconstructible + assignment operator.
__glibcpp_class_requires(state_type, _SGIAssignableConcept);
_M_state_cur = __state;
_M_state_cur._M_init();
};
};
} // namespace __gnu_cxx

View File

@@ -0,0 +1,395 @@
// Functional extensions -*- C++ -*-
// Copyright (C) 2002 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
/*
*
* 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.
*
*
* Copyright (c) 1996
* 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.
*/
/** @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.
*/
#ifndef _EXT_FUNCTIONAL
#define _EXT_FUNCTIONAL
#pragma GCC system_header
#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)
{
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;
}
/// 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
#endif /* _EXT_FUNCTIONAL */

View File

@@ -0,0 +1,454 @@
// Hashing map implementation -*- C++ -*-
// Copyright (C) 2001, 2002 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
/*
* Copyright (c) 1996
* 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.
*
*/
/** @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.
*/
#ifndef __SGI_STL_INTERNAL_HASH_MAP_H
#define __SGI_STL_INTERNAL_HASH_MAP_H
#include <ext/stl_hashtable.h>
#include <bits/concept_check.h>
namespace __gnu_cxx
{
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
__glibcpp_class_requires(_Key, _SGIAssignableConcept)
__glibcpp_class_requires(_Tp, _SGIAssignableConcept)
__glibcpp_class_requires3(_HashFcn, size_t, _Key, _UnaryFunctionConcept);
__glibcpp_class_requires3(_EqualKey, _Key, _Key, _BinaryPredicateConcept);
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_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
#endif /* __SGI_STL_INTERNAL_HASH_MAP_H */
// Local Variables:
// mode:C++
// End:

View File

@@ -0,0 +1,445 @@
// Hashing set implementation -*- C++ -*-
// Copyright (C) 2001, 2002 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
/*
* Copyright (c) 1996
* 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.
*
*/
/** @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.
*/
#ifndef __SGI_STL_INTERNAL_HASH_SET_H
#define __SGI_STL_INTERNAL_HASH_SET_H
#include <ext/stl_hashtable.h>
#include <bits/concept_check.h>
namespace __gnu_cxx
{
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;
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);
/**
* This is an SGI extension.
* @ingroup SGIextensions
* @doctodo
*/
template <class _Value, class _HashFcn, class _EqualKey, class _Alloc>
class hash_set
{
// concept requirements
__glibcpp_class_requires(_Value, _SGIAssignableConcept)
__glibcpp_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept);
__glibcpp_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 _Ht::const_pointer pointer;
typedef typename _Ht::const_pointer const_pointer;
typedef typename _Ht::const_reference reference;
typedef typename _Ht::const_reference const_reference;
typedef typename _Ht::const_iterator iterator;
typedef typename _Ht::const_iterator const_iterator;
typedef typename _Ht::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);
}
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
__glibcpp_class_requires(_Value, _SGIAssignableConcept)
__glibcpp_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept);
__glibcpp_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 _Ht::const_pointer pointer;
typedef typename _Ht::const_pointer const_pointer;
typedef typename _Ht::const_reference reference;
typedef typename _Ht::const_reference const_reference;
typedef typename _Ht::const_iterator iterator;
typedef typename _Ht::const_iterator const_iterator;
typedef typename _Ht::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
#endif /* __SGI_STL_INTERNAL_HASH_SET_H */
// Local Variables:
// mode:C++
// End:

View File

@@ -0,0 +1,113 @@
// HP/SGI iterator extensions -*- C++ -*-
// Copyright (C) 2001, 2002 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
/*
*
* 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.
*
*
* Copyright (c) 1996-1998
* 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.
*/
/** @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.
*/
#ifndef _EXT_ITERATOR
#define _EXT_ITERATOR
#pragma GCC system_header
#include <bits/concept_check.h>
#include <iterator>
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 returning nothing.
// The latter seems to be an SGI extension. -- pedwards
template<typename _InputIterator, typename _Distance>
inline void
__distance(_InputIterator __first, _InputIterator __last,
_Distance& __n, std::input_iterator_tag)
{
// concept requirements
__glibcpp_function_requires(_InputIteratorConcept<_InputIterator>)
while (__first != __last) { ++__first; ++__n; }
}
template<typename _RandomAccessIterator, typename _Distance>
inline void
__distance(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Distance& __n, std::random_access_iterator_tag)
{
// concept requirements
__glibcpp_function_requires(_RandomAccessIteratorConcept<_RandomAccessIterator>)
__n += __last - __first;
}
/**
* This is an SGI extension.
* @ingroup SGIextensions
* @doctodo
*/
template<typename _InputIterator, typename _Distance>
inline void
distance(_InputIterator __first, _InputIterator __last,
_Distance& __n)
{
// concept requirements -- taken care of in __distance
__distance(__first, __last, __n, std::__iterator_category(__first));
}
} // namespace __gnu_cxx
#endif /* _EXT_ITERATOR */

View File

@@ -0,0 +1,170 @@
// Memory extensions -*- C++ -*-
// Copyright (C) 2002 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
/*
*
* 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.
*
*
* Copyright (c) 1996
* 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.
*/
/** @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.
*/
#ifndef _EXT_MEMORY
#define _EXT_MEMORY
#pragma GCC system_header
#include <memory>
#include <bits/stl_tempbuf.h>
namespace __gnu_cxx
{
using std::ptrdiff_t;
using std::pair;
using std::__iterator_category;
using std::_Temporary_buffer;
template<typename _InputIter, typename _Size, typename _ForwardIter>
pair<_InputIter, _ForwardIter>
__uninitialized_copy_n(_InputIter __first, _Size __count,
_ForwardIter __result,
std::input_iterator_tag)
{
_ForwardIter __cur = __result;
try {
for ( ; __count > 0 ; --__count, ++__first, ++__cur)
std::_Construct(&*__cur, *__first);
return pair<_InputIter, _ForwardIter>(__first, __cur);
}
catch(...)
{
std::_Destroy(__result, __cur);
__throw_exception_again;
}
}
template<typename _RandomAccessIter, typename _Size, typename _ForwardIter>
inline pair<_RandomAccessIter, _ForwardIter>
__uninitialized_copy_n(_RandomAccessIter __first, _Size __count,
_ForwardIter __result,
std::random_access_iterator_tag)
{
_RandomAccessIter __last = __first + __count;
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));
}
/**
* @brief Copies the range [first,last) into result.
* @param first An input iterator.
* @param last An input iterator.
* @param result An output iterator.
* @return result + (first - last)
* @ingroup SGIextensions
*
* Like copy(), but does not require an initialized output range.
*/
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));
}
/**
* This class provides similar behavior and semantics of the standard
* functions get_temporary_buffer() and return_temporary_buffer(), but
* encapsulated in a type vaguely resembling a standard container.
*
* By default, a temporary_buffer<Iter> stores space for objects of
* whatever type the Iter iterator points to. It is constructed from a
* typical [first,last) range, and provides the begin(), end(), size()
* functions, as well as requested_size(). For non-trivial types, copies
* of *first will be used to initialize the storage.
*
* @c malloc is used to obtain underlying storage.
*
* Like get_temporary_buffer(), not all the requested memory may be
* available. Ideally, the created buffer will be large enough to hold a
* copy of [first,last), but if size() is less than requested_size(),
* then this didn't happen.
*
* @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
#endif /* _EXT_MEMORY */

View File

@@ -0,0 +1,151 @@
// Numeric extensions -*- C++ -*-
// Copyright (C) 2002 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
/*
*
* 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.
*
*
* Copyright (c) 1996
* 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.
*/
/** @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.
*/
#ifndef _EXT_NUMERIC
#define _EXT_NUMERIC
#pragma GCC system_header
#include <bits/concept_check.h>
#include <numeric>
#include <ext/functional> // For identity_element
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>
_Tp
__power(_Tp __x, _Integer __n, _MonoidOperation __monoid_op)
{
if (__n == 0)
return identity_element(__monoid_op);
else {
while ((__n & 1) == 0) {
__n >>= 1;
__x = __monoid_op(__x, __x);
}
_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>
inline _Tp
__power(_Tp __x, _Integer __n)
{ return __power(__x, __n, std::multiplies<_Tp>()); }
// Alias for the internal name __power. Note that power is an extension,
// not part of the C++ standard.
/**
* This is an SGI extension.
* @ingroup SGIextensions
* @doctodo
*/
template<typename _Tp, typename _Integer, typename _MonoidOperation>
inline _Tp
power(_Tp __x, _Integer __n, _MonoidOperation __monoid_op)
{ return __power(__x, __n, __monoid_op); }
/**
* This is an SGI extension.
* @ingroup SGIextensions
* @doctodo
*/
template<typename _Tp, typename _Integer>
inline _Tp
power(_Tp __x, _Integer __n)
{ return __power(__x, __n); }
// iota is not part of the C++ standard. It is an extension.
/**
* This is an SGI extension.
* @ingroup SGIextensions
* @doctodo
*/
template<typename _ForwardIter, typename _Tp>
void
iota(_ForwardIter __first, _ForwardIter __last, _Tp __value)
{
// concept requirements
__glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter>)
__glibcpp_function_requires(_ConvertibleConcept<_Tp,
typename std::iterator_traits<_ForwardIter>::value_type>)
while (__first != __last)
*__first++ = __value++;
}
} // namespace __gnu_cxx
#endif /* _EXT_NUMERIC */

View File

@@ -0,0 +1,97 @@
// rb_tree extension -*- C++ -*-
// Copyright (C) 2002 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
/*
*
* 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.
*
*
* Copyright (c) 1996
* 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.
*/
/** @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.
*/
#ifndef _EXT_RB_TREE
#define _EXT_RB_TREE
#pragma GCC system_header
#include <bits/stl_tree.h>
namespace __gnu_cxx
{
using std::_Rb_tree;
using std::allocator;
// Class rb_tree is not part of the C++ standard. It is provided for
// compatibility with the HP STL.
/**
* This is an SGI extension.
* @ingroup SGIextensions
* @doctodo
*/
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;
rb_tree(const _Compare& __comp = _Compare(),
const allocator_type& __a = allocator_type())
: _Base(__comp, __a) {}
~rb_tree() {}
};
} // namespace __gnu_cxx
#endif /* _EXT_RB_TREE */

View File

@@ -0,0 +1,66 @@
// SGI's rope class -*- C++ -*-
// Copyright (C) 2001, 2002 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
/*
* Copyright (c) 1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
/** @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.
*/
#ifndef __SGI_STL_ROPE
#define __SGI_STL_ROPE
#include <bits/stl_algobase.h>
#include <bits/stl_algo.h>
#include <bits/stl_function.h>
#include <bits/stl_numeric.h>
#include <bits/stl_alloc.h>
#include <bits/stl_construct.h>
#include <bits/stl_uninitialized.h>
#include <ext/stl_hash_fun.h>
#include <ext/stl_rope.h>
#endif /* __SGI_STL_ROPE */
// Local Variables:
// mode:C++
// End:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,957 @@
// Singly-linked list implementation -*- C++ -*-
// Copyright (C) 2001, 2002 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
/*
* Copyright (c) 1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*/
/** @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.
*/
#ifndef __SGI_STL_INTERNAL_SLIST_H
#define __SGI_STL_INTERNAL_SLIST_H
#include <bits/stl_algobase.h>
#include <bits/stl_alloc.h>
#include <bits/stl_construct.h>
#include <bits/stl_uninitialized.h>
#include <bits/concept_check.h>
namespace __gnu_cxx
{
using std::size_t;
using std::ptrdiff_t;
using std::_Alloc_traits;
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;
}
};
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;
_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;
}
_Self operator++(int)
{
_Self __tmp = *this;
_M_incr();
return __tmp;
}
};
// Base class that encapsulates details of allocators. Three cases:
// an ordinary standard-conforming allocator, a standard-conforming
// allocator with no non-static data, and an SGI-style allocator.
// This complexity is necessary only because we're worrying about backward
// compatibility and because we want to avoid wasting storage on an
// allocator instance if it isn't necessary.
// Base for general standard-conforming allocators.
template <class _Tp, class _Allocator, bool _IsStatic>
class _Slist_alloc_base {
public:
typedef typename _Alloc_traits<_Tp,_Allocator>::allocator_type
allocator_type;
allocator_type get_allocator() const { return _M_node_allocator; }
_Slist_alloc_base(const allocator_type& __a) : _M_node_allocator(__a) {}
protected:
_Slist_node<_Tp>* _M_get_node()
{ return _M_node_allocator.allocate(1); }
void _M_put_node(_Slist_node<_Tp>* __p)
{ _M_node_allocator.deallocate(__p, 1); }
protected:
typename _Alloc_traits<_Slist_node<_Tp>,_Allocator>::allocator_type
_M_node_allocator;
_Slist_node_base _M_head;
};
// Specialization for instanceless allocators.
template <class _Tp, class _Allocator>
class _Slist_alloc_base<_Tp,_Allocator, true> {
public:
typedef typename _Alloc_traits<_Tp,_Allocator>::allocator_type
allocator_type;
allocator_type get_allocator() const { return allocator_type(); }
_Slist_alloc_base(const allocator_type&) {}
protected:
typedef typename _Alloc_traits<_Slist_node<_Tp>, _Allocator>::_Alloc_type
_Alloc_type;
_Slist_node<_Tp>* _M_get_node() { return _Alloc_type::allocate(1); }
void _M_put_node(_Slist_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); }
protected:
_Slist_node_base _M_head;
};
template <class _Tp, class _Alloc>
struct _Slist_base
: public _Slist_alloc_base<_Tp, _Alloc,
_Alloc_traits<_Tp, _Alloc>::_S_instanceless>
{
typedef _Slist_alloc_base<_Tp, _Alloc,
_Alloc_traits<_Tp, _Alloc>::_S_instanceless>
_Base;
typedef typename _Base::allocator_type allocator_type;
_Slist_base(const allocator_type& __a)
: _Base(__a) { this->_M_head._M_next = 0; }
~_Slist_base() { _M_erase_after(&this->_M_head, 0); }
protected:
_Slist_node_base* _M_erase_after(_Slist_node_base* __pos)
{
_Slist_node<_Tp>* __next = (_Slist_node<_Tp>*) (__pos->_M_next);
_Slist_node_base* __next_next = __next->_M_next;
__pos->_M_next = __next_next;
_Destroy(&__next->_M_data);
_M_put_node(__next);
return __next_next;
}
_Slist_node_base* _M_erase_after(_Slist_node_base*, _Slist_node_base*);
};
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);
}
__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
__glibcpp_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(...)
{
this->_M_put_node(__node);
__throw_exception_again;
}
return __node;
}
_Node* _M_create_node() {
_Node* __node = this->_M_get_node();
try {
_Construct(&__node->_M_data);
__node->_M_next = 0;
}
catch(...)
{
this->_M_put_node(__node);
__throw_exception_again;
}
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());
}
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;
_Destroy(&__node->_M_data);
this->_M_put_node(__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));
}
private:
_Node* _M_insert_after(_Node_base* __pos, const value_type& __x) {
return (_Node*) (__slist_make_link(__pos, _M_create_node(__x)));
}
_Node* _M_insert_after(_Node_base* __pos) {
return (_Node*) (__slist_make_link(__pos, _M_create_node()));
}
void _M_insert_after_fill(_Node_base* __pos,
size_type __n, const value_type& __x) {
for (size_type __i = 0; __i < __n; ++__i)
__pos = __slist_make_link(__pos, _M_create_node(__x));
}
// Check whether it's an integral type. If so, it's not an iterator.
template <class _InIter>
void _M_insert_after_range(_Node_base* __pos,
_InIter __first, _InIter __last) {
typedef typename _Is_integer<_InIter>::_Integral _Integral;
_M_insert_after_range(__pos, __first, __last, _Integral());
}
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 _InIter>
void _M_insert_after_range(_Node_base* __pos,
_InIter __first, _InIter __last,
__false_type) {
while (__first != __last) {
__pos = __slist_make_link(__pos, _M_create_node(*__first));
++__first;
}
}
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 _InIter>
void insert_after(iterator __pos, _InIter __first, _InIter __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 _InIter>
void insert(iterator __pos, _InIter __first, _InIter __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));
}
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); }
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);
}
// 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));
}
public:
void reverse() {
if (this->_M_head._M_next)
this->_M_head._M_next = __slist_reverse(this->_M_head._M_next);
}
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 _InputIter>
void
slist<_Tp, _Alloc>::_M_assign_dispatch(_InputIter __first, _InputIter __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;
}
__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;
}
__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=(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; }
};
} // namespace std
#endif /* __SGI_STL_INTERNAL_SLIST_H */
// Local Variables:
// mode:C++
// End:

View File

@@ -0,0 +1,168 @@
// File descriptor layer for filebuf -*- C++ -*-
// Copyright (C) 2002 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General 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/stdio_filebuf.h
* This file is a GNU extension to the Standard C++ Library.
*/
#ifndef _EXT_STDIO_FILEBUF
#define _EXT_STDIO_FILEBUF
#pragma GCC system_header
#include <fstream>
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
* FILE*'s and POSIX file descriptors. It must be instantiated by the
* user with the type of character used in the file stream, e.g.,
* stdio_filebuf<char>.
*/
template<typename _CharT, typename _Traits = std::char_traits<_CharT> >
class stdio_filebuf : public std::basic_filebuf<_CharT, _Traits>
{
public:
// Types:
typedef _CharT char_type;
typedef _Traits traits_type;
typedef typename traits_type::int_type int_type;
typedef typename traits_type::pos_type pos_type;
typedef typename traits_type::off_type off_type;
protected:
// Stack-based buffer for unbuffered input.
char_type _M_unbuf[4];
public:
/**
* @param fd An open file descriptor.
* @param mode Same meaning as in a standard filebuf.
* @param del Whether to close the file on destruction.
* @param size Optimal or preferred size of internal buffer, in bytes.
*
* This constructor associates a file stream buffer with an open
* POSIX file descriptor. Iff @a del is true, then the associated
* file will be closed when the stdio_filebuf is closed/destroyed.
*/
stdio_filebuf(int __fd, std::ios_base::openmode __mode, bool __del,
int_type __size);
/**
* @param f An open @c FILE*.
* @param mode Same meaning as in a standard filebuf.
* @param size Optimal or preferred size of internal buffer, in bytes.
* Defaults to system's @c BUFSIZ.
*
* This constructor associates a file stream buffer with an open
* C @c FILE*. The @c FILE* will not be automatically closed when the
* stdio_filebuf is closed/destroyed.
*/
stdio_filebuf(std::__c_file* __f, std::ios_base::openmode __mode,
int_type __size = static_cast<int_type>(BUFSIZ));
/**
* Possibly closes the external data stream, in the case of the file
* descriptor constructor and @c del @c == @c true.
*/
virtual
~stdio_filebuf();
/**
* @return The underlying file descriptor.
*
* Once associated with an external data stream, this function can be
* used to access the underlying POSIX file descriptor. Note that
* there is no way for the library to track what you do with the
* descriptor, so be careful.
*/
int
fd()
{ return _M_file.fd(); }
};
template<typename _CharT, typename _Traits>
stdio_filebuf<_CharT, _Traits>::~stdio_filebuf()
{ }
template<typename _CharT, typename _Traits>
stdio_filebuf<_CharT, _Traits>::
stdio_filebuf(int __fd, std::ios_base::openmode __mode, bool __del,
int_type __size)
{
_M_file.sys_open(__fd, __mode, __del);
if (this->is_open())
{
_M_mode = __mode;
if (__size > 0 && __size < 4)
{
// Specify unbuffered.
_M_buf = _M_unbuf;
_M_buf_size = __size;
_M_buf_size_opt = 0;
}
else
{
_M_buf_size_opt = __size;
_M_allocate_internal_buffer();
}
_M_set_indeterminate();
}
}
template<typename _CharT, typename _Traits>
stdio_filebuf<_CharT, _Traits>::
stdio_filebuf(std::__c_file* __f, std::ios_base::openmode __mode,
int_type __size)
{
_M_file.sys_open(__f, __mode);
if (this->is_open())
{
_M_mode = __mode;
if (__size > 0 && __size < 4)
{
// Specify unbuffered.
_M_buf = _M_unbuf;
_M_buf_size = __size;
_M_buf_size_opt = 0;
}
else
{
_M_buf_size_opt = __size;
_M_allocate_internal_buffer();
}
_M_set_indeterminate();
}
}
} // namespace __gnu_cxx
#endif /* _EXT_STDIO_FILEBUF */

View File

@@ -0,0 +1,126 @@
// 'struct hash' from SGI -*- C++ -*-
// Copyright (C) 2001, 2002 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
/*
* Copyright (c) 1996-1998
* 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.
*
*/
/** @file ext/stl_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.
*/
#ifndef _CPP_BITS_STL_HASH_FUN_H
#define _CPP_BITS_STL_HASH_FUN_H 1
#include <cstddef>
namespace __gnu_cxx
{
using std::size_t;
template <class _Key> struct hash { };
inline size_t __stl_hash_string(const char* __s)
{
unsigned long __h = 0;
for ( ; *__s; ++__s)
__h = 5*__h + *__s;
return size_t(__h);
}
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
#endif /* _CPP_BITS_STL_HASH_FUN_H */
// Local Variables:
// mode:C++
// End:

View File

@@ -0,0 +1,999 @@
// Hashtable implementation used by containers -*- C++ -*-
// Copyright (C) 2001, 2002 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
/*
* 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.
*
*/
/** @file ext/stl_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.
*/
#ifndef __SGI_STL_INTERNAL_HASHTABLE_H
#define __SGI_STL_INTERNAL_HASHTABLE_H
// Hashtable class, used to implement the hashed associative containers
// hash_set, hash_map, hash_multiset, and hash_multimap.
#include <bits/stl_algobase.h>
#include <bits/stl_alloc.h>
#include <bits/stl_construct.h>
#include <bits/stl_algo.h>
#include <bits/stl_uninitialized.h>
#include <bits/stl_function.h>
#include <bits/stl_vector.h>
#include <ext/stl_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::_Alloc_traits;
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::__alloc>
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 { __stl_num_primes = 28 };
static const unsigned long __stl_prime_list[__stl_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)__stl_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_traits<_Val,_Alloc>::allocator_type allocator_type;
allocator_type get_allocator() const { return _M_node_allocator; }
private:
typename _Alloc_traits<_Node, _Alloc>::allocator_type _M_node_allocator;
_Node* _M_get_node() { return _M_node_allocator.allocate(1); }
void _M_put_node(_Node* __p) { _M_node_allocator.deallocate(__p, 1); }
private:
hasher _M_hash;
key_equal _M_equals;
_ExtractKey _M_get_key;
vector<_Node*,_Alloc> _M_buckets;
size_type _M_num_elements;
public:
typedef _Hashtable_iterator<_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;
}
~hashtable() { clear(); }
size_type size() const { return _M_num_elements; }
size_type max_size() const { return size_type(-1); }
bool empty() const { return size() == 0; }
void swap(hashtable& __ht)
{
std::swap(_M_hash, __ht._M_hash);
std::swap(_M_equals, __ht._M_equals);
std::swap(_M_get_key, __ht._M_get_key);
_M_buckets.swap(__ht._M_buckets);
std::swap(_M_num_elements, __ht._M_num_elements);
}
iterator begin()
{
for (size_type __n = 0; __n < _M_buckets.size(); ++__n)
if (_M_buckets[__n])
return iterator(_M_buckets[__n], this);
return end();
}
iterator end() { return iterator(0, this); }
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();
}
const_iterator end() const { return const_iterator(0, this); }
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:
size_type bucket_count() const { return _M_buckets.size(); }
size_type max_bucket_count() const
{ return __stl_prime_list[(int)__stl_num_primes - 1]; }
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;
}
pair<iterator, bool> insert_unique(const value_type& __obj)
{
resize(_M_num_elements + 1);
return insert_unique_noresize(__obj);
}
iterator insert_equal(const value_type& __obj)
{
resize(_M_num_elements + 1);
return insert_equal_noresize(__obj);
}
pair<iterator, bool> insert_unique_noresize(const value_type& __obj);
iterator insert_equal_noresize(const value_type& __obj);
template <class _InputIterator>
void insert_unique(_InputIterator __f, _InputIterator __l)
{
insert_unique(__f, __l, __iterator_category(__f));
}
template <class _InputIterator>
void insert_equal(_InputIterator __f, _InputIterator __l)
{
insert_equal(__f, __l, __iterator_category(__f));
}
template <class _InputIterator>
void insert_unique(_InputIterator __f, _InputIterator __l,
input_iterator_tag)
{
for ( ; __f != __l; ++__f)
insert_unique(*__f);
}
template <class _InputIterator>
void insert_equal(_InputIterator __f, _InputIterator __l,
input_iterator_tag)
{
for ( ; __f != __l; ++__f)
insert_equal(*__f);
}
template <class _ForwardIterator>
void insert_unique(_ForwardIterator __f, _ForwardIterator __l,
forward_iterator_tag)
{
size_type __n = 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);
}
reference find_or_insert(const value_type& __obj);
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);
}
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);
}
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<const_iterator, const_iterator>
equal_range(const key_type& __key) const;
size_type erase(const key_type& __key);
void erase(const iterator& __it);
void erase(iterator __first, iterator __last);
void erase(const const_iterator& __it);
void erase(const_iterator __first, const_iterator __last);
void resize(size_type __num_elements_hint);
void clear();
private:
size_type _M_next_size(size_type __n) const
{ return __stl_next_prime(__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_key(const key_type& __key) const
{
return _M_bkt_num_key(__key, _M_buckets.size());
}
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 {
_Construct(&__n->_M_val, __obj);
return __n;
}
catch(...)
{
_M_put_node(__n);
__throw_exception_again;
}
}
void _M_delete_node(_Node* __n)
{
_Destroy(&__n->_M_val);
_M_put_node(__n);
}
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;
}
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)
{
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;
}
}
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))) {
_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 = __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());
}
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());
}
}
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;
}
}
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;
}
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;
}
}
}
}
}
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<_Node*, _All> __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* __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>
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;
}
_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;
}
}
}
_M_num_elements = __ht._M_num_elements;
}
catch(...)
{
clear();
__throw_exception_again;
}
}
} // namespace __gnu_cxx
#endif /* __SGI_STL_INTERNAL_HASHTABLE_H */
// Local Variables:
// mode:C++
// End:

File diff suppressed because it is too large Load Diff