diff --git a/headers/cpp/PlotFile.h b/headers/cpp/PlotFile.h new file mode 100644 index 0000000000..82b08bc468 --- /dev/null +++ b/headers/cpp/PlotFile.h @@ -0,0 +1,89 @@ +/* This is part of libio/iostream, providing -*- C++ -*- input/output. +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + +/* + a very simple implementation of a class to output unix "plot" + format plotter files. See corresponding unix man pages for + more details. + + written by Doug Lea (dl@rocky.oswego.edu) + converted to use iostream library by Per Bothner (bothner@cygnus.com) +*/ + +#ifndef _PlotFile_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _PlotFile_h + +#include + +/* + Some plot libraries have the `box' command to draw boxes. Some don't. + `box' is included here via moves & lines to allow both possiblilties. +*/ + +extern "C++" { +class PlotFile : public ofstream +{ +protected: + PlotFile& cmd(char c); + PlotFile& operator << (const int x); + PlotFile& operator << (const char *s); + +public: + + PlotFile() : ofstream() { } + PlotFile(int fd) : ofstream(fd) { } + PlotFile(const char *name, int mode=ios::out, int prot=0664) + : ofstream(name, mode, prot) { } + +// PlotFile& remove() { ofstream::remove(); return *this; } + +// int filedesc() { return ofstream::filedesc(); } +// const char* name() { return File::name(); } +// void setname(const char* newname) { File::setname(newname); } +// int iocount() { return File::iocount(); } + + PlotFile& arc(const int xi, const int yi, + const int x0, const int y0, + const int x1, const int y1); + PlotFile& box(const int x0, const int y0, + const int x1, const int y1); + PlotFile& circle(const int x, const int y, const int r); + PlotFile& cont(const int xi, const int yi); + PlotFile& dot(const int xi, const int yi, const int dx, + int n, const int* pat); + PlotFile& erase(); + PlotFile& label(const char* s); + PlotFile& line(const int x0, const int y0, + const int x1, const int y1); + PlotFile& linemod(const char* s); + PlotFile& move(const int xi, const int yi); + PlotFile& point(const int xi, const int yi); + PlotFile& space(const int x0, const int y0, + const int x1, const int y1); +}; +} // extern "C++" +#endif diff --git a/headers/cpp/SFile.h b/headers/cpp/SFile.h new file mode 100644 index 0000000000..ed8b7eb22f --- /dev/null +++ b/headers/cpp/SFile.h @@ -0,0 +1,55 @@ +/* This is part of libio/iostream, providing -*- C++ -*- input/output. +Copyright (C) 1988, 1992, 1993 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + +#ifndef _SFile_h +#ifdef __GNUG__ +#pragma interface +#endif +#define _SFile_h 1 + +#include + +extern "C++" { +class SFile: public fstream +{ + protected: + long sz; // unit size for structured binary IO + +public: + SFile() : fstream() { } + SFile(int fd, int size); + SFile(const char *name, int size, int mode, int prot=0664); + void open(const char *name, int size, int mode, int prot=0664); + + int size() { return sz; } + int setsize(int s) { int old = sz; sz = s; return old; } + + SFile& get(void* x); + SFile& put(void* x); + SFile& operator[](long i); +}; +} // extern "C++" + +#endif diff --git a/headers/cpp/algo.h b/headers/cpp/algo.h new file mode 100644 index 0000000000..1707868c7c --- /dev/null +++ b/headers/cpp/algo.h @@ -0,0 +1,114 @@ +/* + * + * 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,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_ALGO_H +#define __SGI_STL_ALGO_H + +#include +#include +#include +#include + +#ifdef __STL_USE_NAMESPACES + +// Names from +using __STD::for_each; +using __STD::find; +using __STD::find_if; +using __STD::adjacent_find; +using __STD::count; +using __STD::count_if; +using __STD::search; +using __STD::search_n; +using __STD::swap_ranges; +using __STD::transform; +using __STD::replace; +using __STD::replace_if; +using __STD::replace_copy; +using __STD::replace_copy_if; +using __STD::generate; +using __STD::generate_n; +using __STD::remove; +using __STD::remove_if; +using __STD::remove_copy; +using __STD::remove_copy_if; +using __STD::unique; +using __STD::unique_copy; +using __STD::reverse; +using __STD::reverse_copy; +using __STD::rotate; +using __STD::rotate_copy; +using __STD::random_shuffle; +using __STD::random_sample; +using __STD::random_sample_n; +using __STD::partition; +using __STD::stable_partition; +using __STD::sort; +using __STD::stable_sort; +using __STD::partial_sort; +using __STD::partial_sort_copy; +using __STD::nth_element; +using __STD::lower_bound; +using __STD::upper_bound; +using __STD::equal_range; +using __STD::binary_search; +using __STD::merge; +using __STD::inplace_merge; +using __STD::includes; +using __STD::set_union; +using __STD::set_intersection; +using __STD::set_difference; +using __STD::set_symmetric_difference; +using __STD::min_element; +using __STD::max_element; +using __STD::next_permutation; +using __STD::prev_permutation; +using __STD::find_first_of; +using __STD::find_end; +using __STD::is_sorted; +using __STD::is_heap; + +// Names from stl_heap.h +using __STD::push_heap; +using __STD::pop_heap; +using __STD::make_heap; +using __STD::sort_heap; + +// Names from +using __STD::accumulate; +using __STD::inner_product; +using __STD::partial_sum; +using __STD::adjacent_difference; +using __STD::power; +using __STD::iota; + +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_ALGO_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/algobase.h b/headers/cpp/algobase.h new file mode 100644 index 0000000000..f35e7af4a9 --- /dev/null +++ b/headers/cpp/algobase.h @@ -0,0 +1,71 @@ +/* + * + * 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,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_ALGOBASE_H +#define __SGI_STL_ALGOBASE_H + +#ifndef __SGI_STL_PAIR_H +#include +#endif +#ifndef __SGI_STL_ITERATOR_H +#include +#endif +#ifndef __SGI_STL_INTERNAL_ALGOBASE_H +#include +#endif +#ifndef __SGI_STL_INTERNAL_UNINITIALIZED_H +#include +#endif + +#ifdef __STL_USE_NAMESPACES + +// Names from stl_algobase.h +using __STD::iter_swap; +using __STD::swap; +using __STD::min; +using __STD::max; +using __STD::copy; +using __STD::copy_backward; +using __STD::copy_n; +using __STD::fill; +using __STD::fill_n; +using __STD::mismatch; +using __STD::equal; +using __STD::lexicographical_compare; +using __STD::lexicographical_compare_3way; + +// Names from stl_uninitialized.h +using __STD::uninitialized_copy; +using __STD::uninitialized_copy_n; +using __STD::uninitialized_fill; +using __STD::uninitialized_fill_n; + +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_ALGOBASE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/algorithm b/headers/cpp/algorithm new file mode 100644 index 0000000000..1ba584f06d --- /dev/null +++ b/headers/cpp/algorithm @@ -0,0 +1,40 @@ +/* + * + * 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,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_ALGORITHM +#define __SGI_STL_ALGORITHM + +#include +#include +#include +#include +#include + +#endif /* __SGI_STL_ALGORITHM */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/alloc.h b/headers/cpp/alloc.h new file mode 100644 index 0000000000..f99a862316 --- /dev/null +++ b/headers/cpp/alloc.h @@ -0,0 +1,46 @@ +/* + * 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. + */ + +#ifndef __SGI_STL_ALLOC_H +#define __SGI_STL_ALLOC_H + +#ifndef __STL_CONFIG_H +#include +#endif +#ifndef __SGI_STL_INTERNAL_ALLOC_H +#include +#endif + +#ifdef __STL_USE_NAMESPACES + +using __STD::__malloc_alloc_template; +using __STD::malloc_alloc; +using __STD::simple_alloc; +using __STD::debug_alloc; +using __STD::__default_alloc_template; +using __STD::alloc; +using __STD::single_client_alloc; +#ifdef __STL_STATIC_TEMPLATE_MEMBER_BUG +using __STD::__malloc_alloc_oom_handler; +#endif /* __STL_STATIC_TEMPLATE_MEMBER_BUG */ +#ifdef __STL_USE_STD_ALLOCATORS +using __STD::allocator; +#endif /* __STL_USE_STD_ALLOCATORS */ + +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_ALLOC_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/bitset b/headers/cpp/bitset new file mode 100644 index 0000000000..8b4f8b1a0f --- /dev/null +++ b/headers/cpp/bitset @@ -0,0 +1,1066 @@ +/* + * Copyright (c) 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. + */ + +#ifndef __SGI_STL_BITSET +#define __SGI_STL_BITSET + +// This implementation of bitset<> has a second template parameter, +// _WordT, which defaults to unsigned long. *YOU SHOULD NOT USE +// THIS FEATURE*. It is experimental, and it may be removed in +// future releases. + +// A bitset of size N, using words of type _WordT, will have +// N % (sizeof(_WordT) * CHAR_BIT) unused bits. (They are the high- +// order bits in the highest word.) It is a class invariant +// of class bitset<> that those unused bits are always zero. + +// Most of the actual code isn't contained in bitset<> itself, but in the +// base class _Base_bitset. The base class works with whole words, not with +// individual bits. This allows us to specialize _Base_bitset for the +// important special case where the bitset is only a single word. + +// The C++ standard does not define the precise semantics of operator[]. +// In this implementation the const version of operator[] is equivalent +// to test(), except that it does no range checking. The non-const version +// returns a reference to a bit, again without doing any range checking. + + +#include // for size_t +#include // for CHAR_BIT +#include +#include // for invalid_argument, out_of_range, overflow_error +#include // for istream, ostream + +#define __BITS_PER_WORDT(__wt) (CHAR_BIT*sizeof(__wt)) +#define __BITSET_WORDS(__n,__wt) \ + ((__n) < 1 ? 1 : ((__n) + __BITS_PER_WORDT(__wt) - 1)/__BITS_PER_WORDT(__wt)) + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1209 +#endif + +// structure to aid in counting bits +template +struct _Bit_count { + static unsigned char _S_bit_count[256]; +}; + +// Mapping from 8 bit unsigned integers to the index of the first one +// bit: +template +struct _First_one { + static unsigned char _S_first_one[256]; +}; + +// +// Base class: general case. +// + +template +struct _Base_bitset { + _WordT _M_w[_Nw]; // 0 is the least significant word. + + _Base_bitset( void ) { _M_do_reset(); } + + _Base_bitset(unsigned long __val); + + static size_t _S_whichword( size_t __pos ) { + return __pos / __BITS_PER_WORDT(_WordT); + } + static size_t _S_whichbyte( size_t __pos ) { + return (__pos % __BITS_PER_WORDT(_WordT)) / CHAR_BIT; + } + static size_t _S_whichbit( size_t __pos ) { + return __pos % __BITS_PER_WORDT(_WordT); + } + static _WordT _S_maskbit( size_t __pos ) { + return (static_cast<_WordT>(1)) << _S_whichbit(__pos); + } + + _WordT& _M_getword(size_t __pos) { return _M_w[_S_whichword(__pos)]; } + _WordT _M_getword(size_t __pos) const { return _M_w[_S_whichword(__pos)]; } + + _WordT& _M_hiword() { return _M_w[_Nw - 1]; } + _WordT _M_hiword() const { return _M_w[_Nw - 1]; } + + void _M_do_and(const _Base_bitset<_Nw,_WordT>& __x) { + for ( size_t __i = 0; __i < _Nw; __i++ ) { + _M_w[__i] &= __x._M_w[__i]; + } + } + + void _M_do_or(const _Base_bitset<_Nw,_WordT>& __x) { + for ( size_t __i = 0; __i < _Nw; __i++ ) { + _M_w[__i] |= __x._M_w[__i]; + } + } + + void _M_do_xor(const _Base_bitset<_Nw,_WordT>& __x) { + for ( size_t __i = 0; __i < _Nw; __i++ ) { + _M_w[__i] ^= __x._M_w[__i]; + } + } + + void _M_do_left_shift(size_t __shift); + + void _M_do_right_shift(size_t __shift); + + void _M_do_flip() { + for ( size_t __i = 0; __i < _Nw; __i++ ) { + _M_w[__i] = ~_M_w[__i]; + } + } + + void _M_do_set() { + for ( size_t __i = 0; __i < _Nw; __i++ ) { + _M_w[__i] = ~static_cast<_WordT>(0); + } + } + + void _M_do_reset() { + for ( size_t __i = 0; __i < _Nw; __i++ ) { + _M_w[__i] = 0; + } + } + + bool _M_is_equal(const _Base_bitset<_Nw,_WordT>& __x) const { + for (size_t __i = 0; __i < _Nw; ++__i) { + if (_M_w[__i] != __x._M_w[__i]) + return false; + } + return true; + } + + bool _M_is_any() const { + for ( size_t __i = 0; __i < __BITSET_WORDS(_Nw,_WordT); __i++ ) { + if ( _M_w[__i] != static_cast<_WordT>(0) ) + return true; + } + return false; + } + + size_t _M_do_count() const { + size_t __result = 0; + const unsigned char* __byte_ptr = (const unsigned char*)_M_w; + const unsigned char* __end_ptr = (const unsigned char*)(_M_w+_Nw); + + while ( __byte_ptr < __end_ptr ) { + __result += _Bit_count::_S_bit_count[*__byte_ptr]; + __byte_ptr++; + } + return __result; + } + + unsigned long _M_do_to_ulong() const; + + // find first "on" bit + size_t _M_do_find_first(size_t __not_found) const; + + // find the next "on" bit that follows "prev" + size_t _M_do_find_next(size_t __prev, size_t __not_found) const; +}; + +// +// Definitions of non-inline functions from _Base_bitset. +// + +template +_Base_bitset<_Nw, _WordT>::_Base_bitset(unsigned long __val) +{ + _M_do_reset(); + const size_t __n = min(sizeof(unsigned long)*CHAR_BIT, + __BITS_PER_WORDT(_WordT)*_Nw); + for(size_t __i = 0; __i < __n; ++__i, __val >>= 1) + if ( __val & 0x1 ) + _M_getword(__i) |= _S_maskbit(__i); +} + +template +void _Base_bitset<_Nw, _WordT>::_M_do_left_shift(size_t __shift) +{ + if (__shift != 0) { + const size_t __wshift = __shift / __BITS_PER_WORDT(_WordT); + const size_t __offset = __shift % __BITS_PER_WORDT(_WordT); + const size_t __sub_offset = __BITS_PER_WORDT(_WordT) - __offset; + size_t __n = _Nw - 1; + for ( ; __n > __wshift; --__n) + _M_w[__n] = (_M_w[__n - __wshift] << __offset) | + (_M_w[__n - __wshift - 1] >> __sub_offset); + if (__n == __wshift) + _M_w[__n] = _M_w[0] << __offset; + for (size_t __n1 = 0; __n1 < __n; ++__n1) + _M_w[__n1] = static_cast<_WordT>(0); + } +} + +template +void _Base_bitset<_Nw, _WordT>::_M_do_right_shift(size_t __shift) +{ + if (__shift != 0) { + const size_t __wshift = __shift / __BITS_PER_WORDT(_WordT); + const size_t __offset = __shift % __BITS_PER_WORDT(_WordT); + const size_t __sub_offset = __BITS_PER_WORDT(_WordT) - __offset; + const size_t __limit = _Nw - __wshift - 1; + size_t __n = 0; + for ( ; __n < __limit; ++__n) + _M_w[__n] = (_M_w[__n + __wshift] >> __offset) | + (_M_w[__n + __wshift + 1] << __sub_offset); + _M_w[__limit] = _M_w[_Nw-1] >> __offset; + for (size_t __n1 = __limit + 1; __n1 < _Nw; ++__n1) + _M_w[__n1] = static_cast<_WordT>(0); + } +} + +template +unsigned long _Base_bitset<_Nw, _WordT>::_M_do_to_ulong() const +{ + const overflow_error __overflow("bitset"); + + if (sizeof(_WordT) >= sizeof(unsigned long)) { + for (size_t __i = 1; __i < _Nw; ++__i) + if (_M_w[__i]) + __STL_THROW(__overflow); + + const _WordT __mask = static_cast<_WordT>(static_cast(-1)); + if (_M_w[0] & ~__mask) + __STL_THROW(__overflow); + + return static_cast(_M_w[0] & __mask); + } + else { // sizeof(_WordT) < sizeof(unsigned long). + const size_t __nwords = + (sizeof(unsigned long) + sizeof(_WordT) - 1) / sizeof(_WordT); + + size_t __min_nwords = __nwords; + if (_Nw > __nwords) { + for (size_t __i = __nwords; __i < _Nw; ++__i) + if (_M_w[__i]) + __STL_THROW(__overflow); + } + else + __min_nwords = _Nw; + + // If unsigned long is 8 bytes and _WordT is 6 bytes, then an unsigned + // long consists of all of one word plus 2 bytes from another word. + const size_t __part = sizeof(unsigned long) % sizeof(_WordT); + + if (__part != 0 && __nwords <= _Nw && + (_M_w[__min_nwords - 1] >> ((sizeof(_WordT) - __part) * CHAR_BIT)) != 0) + __STL_THROW(__overflow); + + unsigned long __result = 0; + for (size_t __i = 0; __i < __min_nwords; ++__i) { + __result |= static_cast( + _M_w[__i]) << (__i * sizeof(_WordT) * CHAR_BIT); + } + return __result; + } +} // End _M_do_to_ulong + +template +size_t _Base_bitset<_Nw, _WordT>::_M_do_find_first(size_t __not_found) const +{ + for ( size_t __i = 0; __i < _Nw; __i++ ) { + _WordT __thisword = _M_w[__i]; + if ( __thisword != static_cast<_WordT>(0) ) { + // find byte within word + for ( size_t __j = 0; __j < sizeof(_WordT); __j++ ) { + unsigned char __this_byte + = static_cast(__thisword & (~(unsigned char)0)); + if ( __this_byte ) + return __i*__BITS_PER_WORDT(_WordT) + __j*CHAR_BIT + + _First_one::_S_first_one[__this_byte]; + + __thisword >>= CHAR_BIT; + } + } + } + // not found, so return an indication of failure. + return __not_found; +} + +template +size_t +_Base_bitset<_Nw, _WordT>::_M_do_find_next(size_t __prev, + size_t __not_found) const +{ + // make bound inclusive + ++__prev; + + // check out of bounds + if ( __prev >= _Nw * __BITS_PER_WORDT(_WordT) ) + return __not_found; + + // search first word + size_t __i = _S_whichword(__prev); + _WordT __thisword = _M_w[__i]; + + // mask off bits below bound + __thisword &= (~static_cast<_WordT>(0)) << _S_whichbit(__prev); + + if ( __thisword != static_cast<_WordT>(0) ) { + // find byte within word + // get first byte into place + __thisword >>= _S_whichbyte(__prev) * CHAR_BIT; + for ( size_t __j = _S_whichbyte(__prev); __j < sizeof(_WordT); __j++ ) { + unsigned char __this_byte + = static_cast(__thisword & (~(unsigned char)0)); + if ( __this_byte ) + return __i*__BITS_PER_WORDT(_WordT) + __j*CHAR_BIT + + _First_one::_S_first_one[__this_byte]; + + __thisword >>= CHAR_BIT; + } + } + + // check subsequent words + __i++; + for ( ; __i < _Nw; __i++ ) { + _WordT __thisword = _M_w[__i]; + if ( __thisword != static_cast<_WordT>(0) ) { + // find byte within word + for ( size_t __j = 0; __j < sizeof(_WordT); __j++ ) { + unsigned char __this_byte + = static_cast(__thisword & (~(unsigned char)0)); + if ( __this_byte ) + return __i*__BITS_PER_WORDT(_WordT) + __j*CHAR_BIT + + _First_one::_S_first_one[__this_byte]; + + __thisword >>= CHAR_BIT; + } + } + } + + // not found, so return an indication of failure. + return __not_found; +} // end _M_do_find_next + + +// ------------------------------------------------------------ + +// +// Base class: specialization for a single word. +// + +template +struct _Base_bitset<1, _WordT> { + _WordT _M_w; + + _Base_bitset( void ) { _M_do_reset(); } + + _Base_bitset(unsigned long __val); + + static size_t _S_whichword( size_t __pos ) { + return __pos / __BITS_PER_WORDT(_WordT); + } + static size_t _S_whichbyte( size_t __pos ) { + return (__pos % __BITS_PER_WORDT(_WordT)) / CHAR_BIT; + } + static size_t _S_whichbit( size_t __pos ) { + return __pos % __BITS_PER_WORDT(_WordT); + } + static _WordT _S_maskbit( size_t __pos ) { + return (static_cast<_WordT>(1)) << _S_whichbit(__pos); + } + + _WordT& _M_getword(size_t) { return _M_w; } + _WordT _M_getword(size_t) const { return _M_w; } + + _WordT& _M_hiword() { return _M_w; } + _WordT _M_hiword() const { return _M_w; } + + void _M_do_and(const _Base_bitset<1,_WordT>& __x) { _M_w &= __x._M_w; } + void _M_do_or(const _Base_bitset<1,_WordT>& __x) { _M_w |= __x._M_w; } + void _M_do_xor(const _Base_bitset<1,_WordT>& __x) { _M_w ^= __x._M_w; } + void _M_do_left_shift(size_t __shift) { _M_w <<= __shift; } + void _M_do_right_shift(size_t __shift) { _M_w >>= __shift; } + void _M_do_flip() { _M_w = ~_M_w; } + void _M_do_set() { _M_w = ~static_cast<_WordT>(0); } + void _M_do_reset() { _M_w = 0; } + + bool _M_is_equal(const _Base_bitset<1,_WordT>& __x) const { + return _M_w == __x._M_w; + } + bool _M_is_any() const { + return _M_w != 0; + } + + size_t _M_do_count() const { + size_t __result = 0; + const unsigned char* __byte_ptr = (const unsigned char*)&_M_w; + const unsigned char* __end_ptr = ((const unsigned char*)&_M_w)+sizeof(_M_w); + while ( __byte_ptr < __end_ptr ) { + __result += _Bit_count::_S_bit_count[*__byte_ptr]; + __byte_ptr++; + } + return __result; + } + + unsigned long _M_do_to_ulong() const { + if (sizeof(_WordT) <= sizeof(unsigned long)) + return static_cast(_M_w); + else { + const _WordT __mask = static_cast<_WordT>(static_cast(-1)); + if (_M_w & ~__mask) + __STL_THROW(overflow_error("bitset")); + return static_cast(_M_w); + } + } + + size_t _M_do_find_first(size_t __not_found) const; + + // find the next "on" bit that follows "prev" + size_t _M_do_find_next(size_t __prev, size_t __not_found) const; + +}; + +// +// Definitions of non-inline functions from the single-word version of +// _Base_bitset. +// + +template +_Base_bitset<1, _WordT>::_Base_bitset(unsigned long __val) +{ + _M_do_reset(); + const size_t __n = min(sizeof(unsigned long)*CHAR_BIT, + __BITS_PER_WORDT(_WordT)*_Nw); + for(size_t __i = 0; __i < __n; ++__i, __val >>= 1) + if ( __val & 0x1 ) + _M_w |= _S_maskbit(__i); +} + +template +size_t _Base_bitset<1, _WordT>::_M_do_find_first(size_t __not_found) const +{ + _WordT __thisword = _M_w; + + if ( __thisword != static_cast<_WordT>(0) ) { + // find byte within word + for ( size_t __j = 0; __j < sizeof(_WordT); __j++ ) { + unsigned char __this_byte + = static_cast(__thisword & (~(unsigned char)0)); + if ( __this_byte ) + return __j*CHAR_BIT + _First_one::_S_first_one[__this_byte]; + + __thisword >>= CHAR_BIT; + } + } + // not found, so return a value that indicates failure. + return __not_found; +} + +template +size_t +_Base_bitset<1, _WordT>::_M_do_find_next(size_t __prev, + size_t __not_found ) const +{ + // make bound inclusive + ++__prev; + + // check out of bounds + if ( __prev >= __BITS_PER_WORDT(_WordT) ) + return __not_found; + + // search first (and only) word + _WordT __thisword = _M_w; + + // mask off bits below bound + __thisword &= (~static_cast<_WordT>(0)) << _S_whichbit(__prev); + + if ( __thisword != static_cast<_WordT>(0) ) { + // find byte within word + // get first byte into place + __thisword >>= _S_whichbyte(__prev) * CHAR_BIT; + for ( size_t __j = _S_whichbyte(__prev); __j < sizeof(_WordT); __j++ ) { + unsigned char __this_byte + = static_cast(__thisword & (~(unsigned char)0)); + if ( __this_byte ) + return __j*CHAR_BIT + _First_one::_S_first_one[__this_byte]; + + __thisword >>= CHAR_BIT; + } + } + + // not found, so return a value that indicates failure. + return __not_found; +} // end _M_do_find_next + +// +// One last specialization: _M_do_to_ulong() and the constructor from +// unsigned long are very simple if the bitset consists of a single +// word of type unsigned long. +// + +template<> +inline unsigned long +_Base_bitset<1, unsigned long>::_M_do_to_ulong() const { return _M_w; } + +template<> +inline _Base_bitset<1, unsigned long>::_Base_bitset(unsigned long __val) { + _M_w = __val; +} + + +// ------------------------------------------------------------ +// Helper class to zero out the unused high-order bits in the highest word. + +template struct _Sanitize { + static void _M_do_sanitize(_WordT& __val) + { __val &= ~((~static_cast<_WordT>(0)) << _Extrabits); } +}; + +template struct _Sanitize<_WordT, 0> { + static void _M_do_sanitize(_WordT) {} +}; + +// ------------------------------------------------------------ +// Class bitset. +// _Nb may be any nonzero number of type size_t. +// Type _WordT may be any unsigned integral type. + +template +class bitset : private _Base_bitset<__BITSET_WORDS(_Nb,_WordT), _WordT> +{ +private: + typedef _Base_bitset<__BITSET_WORDS(_Nb,_WordT), _WordT> _Base; + + // Import base's protected interface. Necessary because of new template + // name resolution rules. + using _Base::_S_whichword; + using _Base::_S_whichbyte; + using _Base::_S_whichbit; + using _Base::_S_maskbit; + using _Base::_M_getword; + using _Base::_M_hiword; + using _Base::_M_do_and; + using _Base::_M_do_or; + using _Base::_M_do_xor; + using _Base::_M_do_left_shift; + using _Base::_M_do_right_shift; + using _Base::_M_do_flip; + using _Base::_M_do_set; + using _Base::_M_do_reset; + using _Base::_M_is_equal; + using _Base::_M_is_any; + using _Base::_M_do_count; + using _Base::_M_do_to_ulong; + using _Base::_M_do_find_first; + using _Base::_M_do_find_next; + +private: + void _M_do_sanitize() { + _Sanitize<_WordT,_Nb%__BITS_PER_WORDT(_WordT) > + ::_M_do_sanitize(_M_hiword()); + } + +public: + + // bit reference: + class reference; + friend class reference; + class reference { + friend class bitset; + + _WordT *_M_wp; + size_t _M_bpos; + + // left undefined + reference(); + + reference( bitset& __b, size_t __pos ) { + _M_wp = &__b._M_getword(__pos); + _M_bpos = _S_whichbit(__pos); + } + + public: + ~reference() {} + + // for b[i] = __x; + reference& operator=(bool __x) { + if ( __x ) + *_M_wp |= _S_maskbit(_M_bpos); + else + *_M_wp &= ~_S_maskbit(_M_bpos); + + return *this; + } + + // for b[i] = b[__j]; + reference& operator=(const reference& __j) { + if ( (*(__j._M_wp) & _S_maskbit(__j._M_bpos)) ) + *_M_wp |= _S_maskbit(_M_bpos); + else + *_M_wp &= ~_S_maskbit(_M_bpos); + + return *this; + } + + // flips the bit + bool operator~() const { return (*(_M_wp) & _S_maskbit(_M_bpos)) == 0; } + + // for __x = b[i]; + operator bool() const { return (*(_M_wp) & _S_maskbit(_M_bpos)) != 0; } + + // for b[i].flip(); + reference& flip() { + *_M_wp ^= _S_maskbit(_M_bpos); + return *this; + } + }; + + // 23.3.5.1 constructors: + bitset() {} + bitset(unsigned long __val) : + _Base_bitset<__BITSET_WORDS(_Nb,_WordT), _WordT>(__val) {} + + template + explicit bitset(const basic_string<_CharT,_Traits,_Alloc>& __s, + size_t __pos = 0, + size_t __n = size_t(basic_string<_CharT,_Traits,_Alloc>::npos)) + : _Base() + { + if (__pos > __s.size()) + __STL_THROW(out_of_range("bitset")); + _M_copy_from_string(__s, __pos, __n); + } + + // 23.3.5.2 bitset operations: + bitset<_Nb,_WordT>& operator&=(const bitset<_Nb,_WordT>& __rhs) { + _M_do_and(__rhs); + return *this; + } + + bitset<_Nb,_WordT>& operator|=(const bitset<_Nb,_WordT>& __rhs) { + _M_do_or(__rhs); + return *this; + } + + bitset<_Nb,_WordT>& operator^=(const bitset<_Nb,_WordT>& __rhs) { + _M_do_xor(__rhs); + return *this; + } + + bitset<_Nb,_WordT>& operator<<=(size_t __pos) { + _M_do_left_shift(__pos); + _M_do_sanitize(); + return *this; + } + + bitset<_Nb,_WordT>& operator>>=(size_t __pos) { + _M_do_right_shift(__pos); + _M_do_sanitize(); + return *this; + } + + // + // Extension: + // Versions of single-bit set, reset, flip, test with no range checking. + // + + bitset<_Nb,_WordT>& _Unchecked_set(size_t __pos) { + _M_getword(__pos) |= _S_maskbit(__pos); + return *this; + } + + bitset<_Nb,_WordT>& _Unchecked_set(size_t __pos, int __val) { + if (__val) + _M_getword(__pos) |= _S_maskbit(__pos); + else + _M_getword(__pos) &= ~_S_maskbit(__pos); + + return *this; + } + + bitset<_Nb,_WordT>& _Unchecked_reset(size_t __pos) { + _M_getword(__pos) &= ~_S_maskbit(__pos); + return *this; + } + + bitset<_Nb,_WordT>& _Unchecked_flip(size_t __pos) { + _M_getword(__pos) ^= _S_maskbit(__pos); + return *this; + } + + bool _Unchecked_test(size_t __pos) const { + return (_M_getword(__pos) & _S_maskbit(__pos)) != static_cast<_WordT>(0); + } + + // Set, reset, and flip. + + bitset<_Nb,_WordT>& set() { + _M_do_set(); + _M_do_sanitize(); + return *this; + } + + bitset<_Nb,_WordT>& set(size_t __pos) { + if (__pos >= _Nb) + __STL_THROW(out_of_range("bitset")); + + return _Unchecked_set(__pos); + } + + bitset<_Nb,_WordT>& set(size_t __pos, int __val) { + if (__pos >= _Nb) + __STL_THROW(out_of_range("bitset")); + + return _Unchecked_set(__pos, __val); + } + + bitset<_Nb,_WordT>& reset() { + _M_do_reset(); + return *this; + } + + bitset<_Nb,_WordT>& reset(size_t __pos) { + if (__pos >= _Nb) + __STL_THROW(out_of_range("bitset")); + + return _Unchecked_reset(__pos); + } + + bitset<_Nb,_WordT>& flip() { + _M_do_flip(); + _M_do_sanitize(); + return *this; + } + + bitset<_Nb,_WordT>& flip(size_t __pos) { + if (__pos >= _Nb) + __STL_THROW(out_of_range("bitset")); + + return _Unchecked_flip(__pos); + } + + bitset<_Nb,_WordT> operator~() const { + return bitset<_Nb,_WordT>(*this).flip(); + } + + // element access: + //for b[i]; + reference operator[](size_t __pos) { return reference(*this,__pos); } + bool operator[](size_t __pos) const { return _Unchecked_test(__pos); } + + unsigned long to_ulong() const { return _M_do_to_ulong(); } + +#ifdef __STL_EXPLICIT_FUNCTION_TMPL_ARGS + template + basic_string<_CharT, _Traits, _Alloc> to_string() const { + basic_string<_CharT, _Traits, _Alloc> __result; + _M_copy_to_string(__result); + return __result; + } +#endif /* __STL_EXPLICIT_FUNCTION_TMPL_ARGS */ + + // Helper functions for string operations. + template + void _M_copy_from_string(const basic_string<_CharT,_Traits,_Alloc>& __s, + size_t, + size_t); + + // Helper functions for string operations. + template + void _M_copy_to_string(basic_string<_CharT,_Traits,_Alloc>&) const; + + size_t count() const { return _M_do_count(); } + + size_t size() const { return _Nb; } + + bool operator==(const bitset<_Nb,_WordT>& __rhs) const { + return _M_is_equal(__rhs); + } + bool operator!=(const bitset<_Nb,_WordT>& __rhs) const { + return !_M_is_equal(__rhs); + } + + bool test(size_t __pos) const { + if (__pos > _Nb) + __STL_THROW(out_of_range("bitset")); + + return _Unchecked_test(__pos); + } + + bool any() const { return _M_is_any(); } + bool none() const { return !_M_is_any(); } + + bitset<_Nb,_WordT> operator<<(size_t __pos) const + { return bitset<_Nb,_WordT>(*this) <<= __pos; } + bitset<_Nb,_WordT> operator>>(size_t __pos) const + { return bitset<_Nb,_WordT>(*this) >>= __pos; } + + // + // EXTENSIONS: bit-find operations. These operations are + // experimental, and are subject to change or removal in future + // versions. + // + + // find the index of the first "on" bit + size_t _Find_first() const + { return _M_do_find_first(_Nb); } + + // find the index of the next "on" bit after prev + size_t _Find_next( size_t __prev ) const + { return _M_do_find_next(__prev, _Nb); } + +}; + +// +// Definitions of non-inline member functions. +// + +template +template +void bitset<_Nb, _WordT> + ::_M_copy_from_string(const basic_string<_CharT,_Traits,_Alloc>& __s, + size_t __pos, + size_t __n) +{ + reset(); + const size_t __nbits = min(_Nb, min(__n, __s.size() - __pos)); + for (size_t __i = 0; __i < __nbits; ++__i) { + switch(__s[__pos + __nbits - __i - 1]) { + case '0': + break; + case '1': + set(__i); + break; + default: + __STL_THROW(invalid_argument("bitset")); + } + } +} + +template +template +void bitset<_Nb, _WordT> + ::_M_copy_to_string(basic_string<_CharT, _Traits, _Alloc>& __s) const +{ + __s.assign(_Nb, '0'); + + for (size_t __i = 0; __i < _Nb; ++__i) + if (_Unchecked_test(__i)) + __s[_Nb - 1 - __i] = '1'; +} + +// ------------------------------------------------------------ + +// +// 23.3.5.3 bitset operations: +// + +template +inline bitset<_Nb,_WordT> operator&(const bitset<_Nb,_WordT>& __x, + const bitset<_Nb,_WordT>& __y) { + bitset<_Nb,_WordT> __result(__x); + __result &= __y; + return __result; +} + + +template +inline bitset<_Nb,_WordT> operator|(const bitset<_Nb,_WordT>& __x, + const bitset<_Nb,_WordT>& __y) { + bitset<_Nb,_WordT> __result(__x); + __result |= __y; + return __result; +} + +template +inline bitset<_Nb,_WordT> operator^(const bitset<_Nb,_WordT>& __x, + const bitset<_Nb,_WordT>& __y) { + bitset<_Nb,_WordT> __result(__x); + __result ^= __y; + return __result; +} + +// NOTE: these must be rewritten once we have templatized iostreams. + +template +istream& +operator>>(istream& __is, bitset<_Nb,_WordT>& __x) { + string __tmp; + __tmp.reserve(_Nb); + + // In new templatized iostreams, use istream::sentry + if (__is.flags() & ios::skipws) { + char __c; + do + __is.get(__c); + while (__is && isspace(__c)); + if (__is) + __is.putback(__c); + } + + for (size_t __i = 0; __i < _Nb; ++__i) { + char __c; + __is.get(__c); + + if (!__is) + break; + else if (__c != '0' && __c != '1') { + __is.putback(__c); + break; + } + else + __tmp.push_back(__c); + } + + if (__tmp.empty()) + __is.clear(__is.rdstate() | ios::failbit); + else + __x._M_copy_from_string(__tmp, static_cast(0), _Nb); + + return __is; +} + +template +ostream& operator<<(ostream& __os, const bitset<_Nb,_WordT>& __x) { + string __tmp; + __x._M_copy_to_string(__tmp); + return __os << __tmp; +} + +// ------------------------------------------------------------ +// Lookup tables for find and count operations. + +template +unsigned char _Bit_count<__dummy>::_S_bit_count[] = { + 0, /* 0 */ 1, /* 1 */ 1, /* 2 */ 2, /* 3 */ 1, /* 4 */ + 2, /* 5 */ 2, /* 6 */ 3, /* 7 */ 1, /* 8 */ 2, /* 9 */ + 2, /* 10 */ 3, /* 11 */ 2, /* 12 */ 3, /* 13 */ 3, /* 14 */ + 4, /* 15 */ 1, /* 16 */ 2, /* 17 */ 2, /* 18 */ 3, /* 19 */ + 2, /* 20 */ 3, /* 21 */ 3, /* 22 */ 4, /* 23 */ 2, /* 24 */ + 3, /* 25 */ 3, /* 26 */ 4, /* 27 */ 3, /* 28 */ 4, /* 29 */ + 4, /* 30 */ 5, /* 31 */ 1, /* 32 */ 2, /* 33 */ 2, /* 34 */ + 3, /* 35 */ 2, /* 36 */ 3, /* 37 */ 3, /* 38 */ 4, /* 39 */ + 2, /* 40 */ 3, /* 41 */ 3, /* 42 */ 4, /* 43 */ 3, /* 44 */ + 4, /* 45 */ 4, /* 46 */ 5, /* 47 */ 2, /* 48 */ 3, /* 49 */ + 3, /* 50 */ 4, /* 51 */ 3, /* 52 */ 4, /* 53 */ 4, /* 54 */ + 5, /* 55 */ 3, /* 56 */ 4, /* 57 */ 4, /* 58 */ 5, /* 59 */ + 4, /* 60 */ 5, /* 61 */ 5, /* 62 */ 6, /* 63 */ 1, /* 64 */ + 2, /* 65 */ 2, /* 66 */ 3, /* 67 */ 2, /* 68 */ 3, /* 69 */ + 3, /* 70 */ 4, /* 71 */ 2, /* 72 */ 3, /* 73 */ 3, /* 74 */ + 4, /* 75 */ 3, /* 76 */ 4, /* 77 */ 4, /* 78 */ 5, /* 79 */ + 2, /* 80 */ 3, /* 81 */ 3, /* 82 */ 4, /* 83 */ 3, /* 84 */ + 4, /* 85 */ 4, /* 86 */ 5, /* 87 */ 3, /* 88 */ 4, /* 89 */ + 4, /* 90 */ 5, /* 91 */ 4, /* 92 */ 5, /* 93 */ 5, /* 94 */ + 6, /* 95 */ 2, /* 96 */ 3, /* 97 */ 3, /* 98 */ 4, /* 99 */ + 3, /* 100 */ 4, /* 101 */ 4, /* 102 */ 5, /* 103 */ 3, /* 104 */ + 4, /* 105 */ 4, /* 106 */ 5, /* 107 */ 4, /* 108 */ 5, /* 109 */ + 5, /* 110 */ 6, /* 111 */ 3, /* 112 */ 4, /* 113 */ 4, /* 114 */ + 5, /* 115 */ 4, /* 116 */ 5, /* 117 */ 5, /* 118 */ 6, /* 119 */ + 4, /* 120 */ 5, /* 121 */ 5, /* 122 */ 6, /* 123 */ 5, /* 124 */ + 6, /* 125 */ 6, /* 126 */ 7, /* 127 */ 1, /* 128 */ 2, /* 129 */ + 2, /* 130 */ 3, /* 131 */ 2, /* 132 */ 3, /* 133 */ 3, /* 134 */ + 4, /* 135 */ 2, /* 136 */ 3, /* 137 */ 3, /* 138 */ 4, /* 139 */ + 3, /* 140 */ 4, /* 141 */ 4, /* 142 */ 5, /* 143 */ 2, /* 144 */ + 3, /* 145 */ 3, /* 146 */ 4, /* 147 */ 3, /* 148 */ 4, /* 149 */ + 4, /* 150 */ 5, /* 151 */ 3, /* 152 */ 4, /* 153 */ 4, /* 154 */ + 5, /* 155 */ 4, /* 156 */ 5, /* 157 */ 5, /* 158 */ 6, /* 159 */ + 2, /* 160 */ 3, /* 161 */ 3, /* 162 */ 4, /* 163 */ 3, /* 164 */ + 4, /* 165 */ 4, /* 166 */ 5, /* 167 */ 3, /* 168 */ 4, /* 169 */ + 4, /* 170 */ 5, /* 171 */ 4, /* 172 */ 5, /* 173 */ 5, /* 174 */ + 6, /* 175 */ 3, /* 176 */ 4, /* 177 */ 4, /* 178 */ 5, /* 179 */ + 4, /* 180 */ 5, /* 181 */ 5, /* 182 */ 6, /* 183 */ 4, /* 184 */ + 5, /* 185 */ 5, /* 186 */ 6, /* 187 */ 5, /* 188 */ 6, /* 189 */ + 6, /* 190 */ 7, /* 191 */ 2, /* 192 */ 3, /* 193 */ 3, /* 194 */ + 4, /* 195 */ 3, /* 196 */ 4, /* 197 */ 4, /* 198 */ 5, /* 199 */ + 3, /* 200 */ 4, /* 201 */ 4, /* 202 */ 5, /* 203 */ 4, /* 204 */ + 5, /* 205 */ 5, /* 206 */ 6, /* 207 */ 3, /* 208 */ 4, /* 209 */ + 4, /* 210 */ 5, /* 211 */ 4, /* 212 */ 5, /* 213 */ 5, /* 214 */ + 6, /* 215 */ 4, /* 216 */ 5, /* 217 */ 5, /* 218 */ 6, /* 219 */ + 5, /* 220 */ 6, /* 221 */ 6, /* 222 */ 7, /* 223 */ 3, /* 224 */ + 4, /* 225 */ 4, /* 226 */ 5, /* 227 */ 4, /* 228 */ 5, /* 229 */ + 5, /* 230 */ 6, /* 231 */ 4, /* 232 */ 5, /* 233 */ 5, /* 234 */ + 6, /* 235 */ 5, /* 236 */ 6, /* 237 */ 6, /* 238 */ 7, /* 239 */ + 4, /* 240 */ 5, /* 241 */ 5, /* 242 */ 6, /* 243 */ 5, /* 244 */ + 6, /* 245 */ 6, /* 246 */ 7, /* 247 */ 5, /* 248 */ 6, /* 249 */ + 6, /* 250 */ 7, /* 251 */ 6, /* 252 */ 7, /* 253 */ 7, /* 254 */ + 8 /* 255 */ +}; // end _Bit_count + +template +unsigned char _First_one<__dummy>::_S_first_one[] = { + 0, /* 0 */ 0, /* 1 */ 1, /* 2 */ 0, /* 3 */ 2, /* 4 */ + 0, /* 5 */ 1, /* 6 */ 0, /* 7 */ 3, /* 8 */ 0, /* 9 */ + 1, /* 10 */ 0, /* 11 */ 2, /* 12 */ 0, /* 13 */ 1, /* 14 */ + 0, /* 15 */ 4, /* 16 */ 0, /* 17 */ 1, /* 18 */ 0, /* 19 */ + 2, /* 20 */ 0, /* 21 */ 1, /* 22 */ 0, /* 23 */ 3, /* 24 */ + 0, /* 25 */ 1, /* 26 */ 0, /* 27 */ 2, /* 28 */ 0, /* 29 */ + 1, /* 30 */ 0, /* 31 */ 5, /* 32 */ 0, /* 33 */ 1, /* 34 */ + 0, /* 35 */ 2, /* 36 */ 0, /* 37 */ 1, /* 38 */ 0, /* 39 */ + 3, /* 40 */ 0, /* 41 */ 1, /* 42 */ 0, /* 43 */ 2, /* 44 */ + 0, /* 45 */ 1, /* 46 */ 0, /* 47 */ 4, /* 48 */ 0, /* 49 */ + 1, /* 50 */ 0, /* 51 */ 2, /* 52 */ 0, /* 53 */ 1, /* 54 */ + 0, /* 55 */ 3, /* 56 */ 0, /* 57 */ 1, /* 58 */ 0, /* 59 */ + 2, /* 60 */ 0, /* 61 */ 1, /* 62 */ 0, /* 63 */ 6, /* 64 */ + 0, /* 65 */ 1, /* 66 */ 0, /* 67 */ 2, /* 68 */ 0, /* 69 */ + 1, /* 70 */ 0, /* 71 */ 3, /* 72 */ 0, /* 73 */ 1, /* 74 */ + 0, /* 75 */ 2, /* 76 */ 0, /* 77 */ 1, /* 78 */ 0, /* 79 */ + 4, /* 80 */ 0, /* 81 */ 1, /* 82 */ 0, /* 83 */ 2, /* 84 */ + 0, /* 85 */ 1, /* 86 */ 0, /* 87 */ 3, /* 88 */ 0, /* 89 */ + 1, /* 90 */ 0, /* 91 */ 2, /* 92 */ 0, /* 93 */ 1, /* 94 */ + 0, /* 95 */ 5, /* 96 */ 0, /* 97 */ 1, /* 98 */ 0, /* 99 */ + 2, /* 100 */ 0, /* 101 */ 1, /* 102 */ 0, /* 103 */ 3, /* 104 */ + 0, /* 105 */ 1, /* 106 */ 0, /* 107 */ 2, /* 108 */ 0, /* 109 */ + 1, /* 110 */ 0, /* 111 */ 4, /* 112 */ 0, /* 113 */ 1, /* 114 */ + 0, /* 115 */ 2, /* 116 */ 0, /* 117 */ 1, /* 118 */ 0, /* 119 */ + 3, /* 120 */ 0, /* 121 */ 1, /* 122 */ 0, /* 123 */ 2, /* 124 */ + 0, /* 125 */ 1, /* 126 */ 0, /* 127 */ 7, /* 128 */ 0, /* 129 */ + 1, /* 130 */ 0, /* 131 */ 2, /* 132 */ 0, /* 133 */ 1, /* 134 */ + 0, /* 135 */ 3, /* 136 */ 0, /* 137 */ 1, /* 138 */ 0, /* 139 */ + 2, /* 140 */ 0, /* 141 */ 1, /* 142 */ 0, /* 143 */ 4, /* 144 */ + 0, /* 145 */ 1, /* 146 */ 0, /* 147 */ 2, /* 148 */ 0, /* 149 */ + 1, /* 150 */ 0, /* 151 */ 3, /* 152 */ 0, /* 153 */ 1, /* 154 */ + 0, /* 155 */ 2, /* 156 */ 0, /* 157 */ 1, /* 158 */ 0, /* 159 */ + 5, /* 160 */ 0, /* 161 */ 1, /* 162 */ 0, /* 163 */ 2, /* 164 */ + 0, /* 165 */ 1, /* 166 */ 0, /* 167 */ 3, /* 168 */ 0, /* 169 */ + 1, /* 170 */ 0, /* 171 */ 2, /* 172 */ 0, /* 173 */ 1, /* 174 */ + 0, /* 175 */ 4, /* 176 */ 0, /* 177 */ 1, /* 178 */ 0, /* 179 */ + 2, /* 180 */ 0, /* 181 */ 1, /* 182 */ 0, /* 183 */ 3, /* 184 */ + 0, /* 185 */ 1, /* 186 */ 0, /* 187 */ 2, /* 188 */ 0, /* 189 */ + 1, /* 190 */ 0, /* 191 */ 6, /* 192 */ 0, /* 193 */ 1, /* 194 */ + 0, /* 195 */ 2, /* 196 */ 0, /* 197 */ 1, /* 198 */ 0, /* 199 */ + 3, /* 200 */ 0, /* 201 */ 1, /* 202 */ 0, /* 203 */ 2, /* 204 */ + 0, /* 205 */ 1, /* 206 */ 0, /* 207 */ 4, /* 208 */ 0, /* 209 */ + 1, /* 210 */ 0, /* 211 */ 2, /* 212 */ 0, /* 213 */ 1, /* 214 */ + 0, /* 215 */ 3, /* 216 */ 0, /* 217 */ 1, /* 218 */ 0, /* 219 */ + 2, /* 220 */ 0, /* 221 */ 1, /* 222 */ 0, /* 223 */ 5, /* 224 */ + 0, /* 225 */ 1, /* 226 */ 0, /* 227 */ 2, /* 228 */ 0, /* 229 */ + 1, /* 230 */ 0, /* 231 */ 3, /* 232 */ 0, /* 233 */ 1, /* 234 */ + 0, /* 235 */ 2, /* 236 */ 0, /* 237 */ 1, /* 238 */ 0, /* 239 */ + 4, /* 240 */ 0, /* 241 */ 1, /* 242 */ 0, /* 243 */ 2, /* 244 */ + 0, /* 245 */ 1, /* 246 */ 0, /* 247 */ 3, /* 248 */ 0, /* 249 */ + 1, /* 250 */ 0, /* 251 */ 2, /* 252 */ 0, /* 253 */ 1, /* 254 */ + 0, /* 255 */ +}; // end _First_one + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1209 +#endif + +__STL_END_NAMESPACE + + +#undef __BITS_PER_WORDT +#undef __BITSET_WORDS + +#endif /* __SGI_STL_BITSET */ + + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/builtinbuf.h b/headers/cpp/builtinbuf.h new file mode 100644 index 0000000000..3aa4c37a65 --- /dev/null +++ b/headers/cpp/builtinbuf.h @@ -0,0 +1,68 @@ +/* +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + +#ifndef _BUILTINBUF_H +#define _BUILTINBUF_H + +#ifdef __GNUC__ +#pragma interface +#endif + +#include + +#if !_IO_UNIFIED_JUMPTABLES +// A builtinbuf is a streambuf where all the virtual operations +// call the _IO_jump_t table. + +extern "C++" { +class builtinbuf : public streambuf { + friend ios; + virtual int overflow(int); + virtual int underflow(); + virtual streamsize xsgetn(char *, streamsize); + virtual streamsize xsputn(const char *, streamsize); + virtual streambuf* setbuf(char*, int); + virtual int doallocate(); + virtual ~builtinbuf(); + virtual int sync(); + + virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out); + virtual streampos seekpos(streampos pos, int mode = ios::in|ios::out); + virtual int pbackfail(int c); + virtual streamsize sys_read(char* buf, streamsize size); + virtual streampos sys_seek(streamoff, _seek_dir); + virtual streamsize sys_write(const char*, streamsize); + virtual int sys_stat(void*); // Actually, a (struct stat*) + virtual int sys_close(); +#if 0 + virtual int get_column(); + virtual int set_column(int); +#endif + private: + builtinbuf() { } +}; +} // extern "C++" +#endif + +#endif /* _BUILTINBUF_H */ diff --git a/headers/cpp/bvector.h b/headers/cpp/bvector.h new file mode 100644 index 0000000000..03a3fb1c7f --- /dev/null +++ b/headers/cpp/bvector.h @@ -0,0 +1,51 @@ +/* + * + * 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. + */ + +#ifndef __SGI_STL_BVECTOR_H +#define __SGI_STL_BVECTOR_H + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION +#include +#else +#include +#include +#endif + +#include + +#ifdef __STL_USE_NAMESPACES + +using __STD::bit_vector; + +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_BVECTOR_H */ + +// Local Variables: +// mode:C++ +// End: + + diff --git a/headers/cpp/cassert b/headers/cpp/cassert new file mode 100644 index 0000000000..b4165bfae7 --- /dev/null +++ b/headers/cpp/cassert @@ -0,0 +1,7 @@ +// -*- C++ -*- forwarding header. +// This file is part of the GNU ANSI C++ Library. + +#ifndef __CASSERT__ +#define __CASSERT__ +#include +#endif diff --git a/headers/cpp/cctype b/headers/cpp/cctype new file mode 100644 index 0000000000..e2765aed50 --- /dev/null +++ b/headers/cpp/cctype @@ -0,0 +1,7 @@ +// The -*- C++ -*- character type header. +// This file is part of the GNU ANSI C++ Library. + +#ifndef __CCTYPE__ +#define __CCTYPE__ +#include +#endif diff --git a/headers/cpp/cerrno b/headers/cpp/cerrno new file mode 100644 index 0000000000..ce49346959 --- /dev/null +++ b/headers/cpp/cerrno @@ -0,0 +1,7 @@ +// The -*- C++ -*- error number header. +// This file is part of the GNU ANSI C++ Library. + +#ifndef __CERRNO__ +#define __CERRNO__ +#include +#endif diff --git a/headers/cpp/cfloat b/headers/cpp/cfloat new file mode 100644 index 0000000000..cf59eadfb7 --- /dev/null +++ b/headers/cpp/cfloat @@ -0,0 +1,7 @@ +// -*- C++ -*- forwarding header. +// This file is part of the GNU ANSI C++ Library. + +#ifndef __CFLOAT__ +#define __CFLOAT__ +#include +#endif diff --git a/headers/cpp/ciso646 b/headers/cpp/ciso646 new file mode 100644 index 0000000000..4d8200d73d --- /dev/null +++ b/headers/cpp/ciso646 @@ -0,0 +1,7 @@ +// -*- C++ -*- forwarding header. +// This file is part of the GNU ANSI C++ Library. + +#ifndef __CISO646__ +#define __CISO646__ +#include +#endif diff --git a/headers/cpp/climits b/headers/cpp/climits new file mode 100644 index 0000000000..1b29b3af01 --- /dev/null +++ b/headers/cpp/climits @@ -0,0 +1,7 @@ +// -*- C++ -*- forwarding header. +// This file is part of the GNU ANSI C++ Library. + +#ifndef __CLIMITS__ +#define __CLIMITS__ +#include +#endif diff --git a/headers/cpp/clocale b/headers/cpp/clocale new file mode 100644 index 0000000000..b67cf31c9d --- /dev/null +++ b/headers/cpp/clocale @@ -0,0 +1,7 @@ +// The -*- C++ -*- locale support header. +// This file is part of the GNU ANSI C++ Library. + +#ifndef __CLOCALE__ +#define __CLOCALE__ +#include +#endif diff --git a/headers/cpp/cmath b/headers/cpp/cmath new file mode 100644 index 0000000000..b18ea0b428 --- /dev/null +++ b/headers/cpp/cmath @@ -0,0 +1,76 @@ +// The -*- C++ -*- math functions header. +// This file is part of the GNU ANSI C++ Library. + +#ifndef __CMATH__ +#define __CMATH__ +#include <_G_config.h> +#include + +#ifdef __GNUG__ +#pragma interface "cmath" +#endif + +extern "C++" { +#if 0 +float acos (float); +float asin (float); +float atan (float); +float atan2(float, float); +float ceil (float); +float cos (float); +float cosh (float); +float exp (float); +float fabs (float); +float floor(float); +float fmod (float, float); +float frexp(float, int*); +float modf (float, float*); +float ldexp(float, int); +float log (float); +float log10(float); +float pow (float, float); +float pow (float, int); +float sin (float); +float sinh (float); +float sqrt (float); +float tan (float); +float tanh (float); +#endif + +inline float abs (float x) { return fabs (x); } +#if ! _G_MATH_H_INLINES /* hpux and SCO define this in math.h */ +inline double abs (double x) { return fabs (x); } +#endif + +#if 0 +double pow(double, int); + +long double acos (long double); +long double asin (long double); +long double atan (long double); +long double atan2(long double, long double); +long double ceil (long double); +long double cos (long double); +long double cosh (long double); +long double exp (long double); +long double fabs (long double); +long double floor(long double); +long double frexp(long double, int*); +long double fmod (long double, long double); +long double frexp(long double, int*); +long double log (long double); +long double log10(long double); +long double modf (long double, long double*); +long double pow (long double, long double); +long double pow (long double, int); +long double sin (long double); +long double sinh (long double); +long double sqrt (long double); +long double tan (long double); +long double tanh (long double); +#endif +inline long double abs (long double x) { return fabs (x); } + +} // extern "C++" + +#endif diff --git a/headers/cpp/complex b/headers/cpp/complex new file mode 100644 index 0000000000..bfdd352b46 --- /dev/null +++ b/headers/cpp/complex @@ -0,0 +1,18 @@ +// Main header for the -*- C++ -*- complex number classes. +// This file is part of the GNU ANSI C++ Library. + +#ifndef __COMPLEX__ +#define __COMPLEX__ + +#include + +extern "C++" { +#define __STD_COMPLEX + +// ANSI complex types +typedef complex float_complex; +typedef complex double_complex; +typedef complex long_double_complex; +} + +#endif diff --git a/headers/cpp/complex.h b/headers/cpp/complex.h new file mode 100644 index 0000000000..2e88de854a --- /dev/null +++ b/headers/cpp/complex.h @@ -0,0 +1,6 @@ +// -*- C++ -*- backward compatiblity header. +// Copyright (C) 1994 Free Software Foundation + +#ifndef __COMPLEX_H__ +#include +#endif diff --git a/headers/cpp/csetjmp b/headers/cpp/csetjmp new file mode 100644 index 0000000000..4bba048dcb --- /dev/null +++ b/headers/cpp/csetjmp @@ -0,0 +1,8 @@ +// The -*- C++ -*- setjmp/longjmp header. +// This file is part of the GNU ANSI C++ Library. + +#ifndef __CSETJMP__ +#define __CSETJMP__ +#include +#endif + diff --git a/headers/cpp/csignal b/headers/cpp/csignal new file mode 100644 index 0000000000..6febfb7b2e --- /dev/null +++ b/headers/cpp/csignal @@ -0,0 +1,7 @@ +// The -*- C++ -*- signal handling header. +// This file is part of the GNU ANSI C++ Library. + +#ifndef __CSIGNAL__ +#define __CSIGNAL__ +#include +#endif diff --git a/headers/cpp/cstdarg b/headers/cpp/cstdarg new file mode 100644 index 0000000000..324f5a1c19 --- /dev/null +++ b/headers/cpp/cstdarg @@ -0,0 +1,7 @@ +// -*- C++ -*- forwarding header. +// This file is part of the GNU ANSI C++ Library. + +#ifndef __CSTDARG__ +#define __CSTDARG__ +#include +#endif diff --git a/headers/cpp/cstddef b/headers/cpp/cstddef new file mode 100644 index 0000000000..db5cbe4003 --- /dev/null +++ b/headers/cpp/cstddef @@ -0,0 +1,7 @@ +// -*- C++ -*- forwarding header. +// This file is part of the GNU ANSI C++ Library. + +#ifndef __CSTDDEF__ +#define __CSTDDEF__ +#include +#endif diff --git a/headers/cpp/cstdio b/headers/cpp/cstdio new file mode 100644 index 0000000000..1fe1456b5b --- /dev/null +++ b/headers/cpp/cstdio @@ -0,0 +1,7 @@ +// The -*- C++ -*- standard I/O header. +// This file is part of the GNU ANSI C++ Library. + +#ifndef __CSTDIO__ +#define __CSTDIO__ +#include +#endif diff --git a/headers/cpp/cstdlib b/headers/cpp/cstdlib new file mode 100644 index 0000000000..e7c1a5160a --- /dev/null +++ b/headers/cpp/cstdlib @@ -0,0 +1,23 @@ +// The -*- C++ -*- standard library header. +// This file is part of the GNU ANSI C++ Library. + +#ifndef __CSTDLIB__ +#define __CSTDLIB__ +#include + +#ifdef __GNUG__ +#pragma interface "cstdlib" +#endif + +extern "C++" { + +#if _G_HAS_LABS +inline long abs(long x) { return labs (x); } +#else +inline long abs(long x) { return x >= 0 ? x : -x; } +#endif +//inline ldiv_t div(long x, long y) { return ldiv (x, y); } + +} // extern "C++" + +#endif diff --git a/headers/cpp/cstring b/headers/cpp/cstring new file mode 100644 index 0000000000..d8d03a765b --- /dev/null +++ b/headers/cpp/cstring @@ -0,0 +1,96 @@ +// The -*- C++ -*- null-terminated string header. +// This file is part of the GNU ANSI C++ Library. + +#ifndef __CSTRING__ +#define __CSTRING__ + +#include + +#if 0 // Let's not bother with this just yet. +#include + +#ifdef __GNUG__ +#pragma interface "cstring" +#endif + +// The ANSI C prototypes for these functions have a const argument type and +// non-const return type, so we can't use them. + +extern "C++" { +extern inline const char * +_G_strchr (const char *s, int c) +{ + return strchr (s, c); +} + +extern inline char * +_G_strchr (char *s, int c) +{ + return const_cast (strchr (s, c)); +} + +extern inline const char * +_G_strpbrk (const char *s1, const char *s2) +{ + return strpbrk (s1, s2); +} + +extern inline char * +_G_strpbrk (char *s1, const char *s2) +{ + return const_cast (strpbrk (s1, s2)); +} + +extern inline const char * +_G_strrchr (const char *s, int c) +{ + return strrchr (s, c); +} + +extern inline char * +_G_strrchr (char *s, int c) +{ + return const_cast (strrchr (s, c)); +} + +extern inline const char * +_G_strstr (const char *s1, const char *s2) +{ + return strstr (s1, s2); +} + +extern inline char * +_G_strstr (char *s1, const char *s2) +{ + return const_cast (strstr (s1, s2)); +} + +extern inline const void * +_G_memchr (const void *s, int c, size_t n) +{ + return memchr (s, c, n); +} + +extern inline void * +_G_memchr (void *s, int c, size_t n) +{ + return const_cast (memchr (s, c, n)); +} +} // extern "C++" + +// Lose any vendor macros for these functions. +#undef strchr +#undef strpbrk +#undef strrchr +#undef strstr +#undef memchr + +// Ewww, namespace pollution. Anyone have a better idea? +#define strchr _G_strchr +#define strpbrk _G_strpbrk +#define strrchr _G_strrchr +#define strstr _G_strstr +#define memchr _G_memchr +#endif // 0 + +#endif // !defined (__CSTRING__) diff --git a/headers/cpp/ctime b/headers/cpp/ctime new file mode 100644 index 0000000000..0184da5929 --- /dev/null +++ b/headers/cpp/ctime @@ -0,0 +1,7 @@ +// The -*- C++ -*- time header. +// This file is part of the GNU ANSI C++ Library. + +#ifndef __CTIME__ +#define __CTIME__ +#include +#endif diff --git a/headers/cpp/cwchar b/headers/cpp/cwchar new file mode 100644 index 0000000000..1674c12b61 --- /dev/null +++ b/headers/cpp/cwchar @@ -0,0 +1,7 @@ +// The -*- C++ -*- wide character header. +// This file is part of the GNU ANSI C++ Library. + +#ifndef __CWCHAR__ +#define __CWCHAR__ +#include +#endif diff --git a/headers/cpp/cwctype b/headers/cpp/cwctype new file mode 100644 index 0000000000..81122012bd --- /dev/null +++ b/headers/cpp/cwctype @@ -0,0 +1,7 @@ +// The -*- C++ -*- wide character type header. +// This file is part of the GNU ANSI C++ Library. + +#ifndef __CWCTYPE__ +#define __CWCTYPE__ +#include +#endif diff --git a/headers/cpp/defalloc.h b/headers/cpp/defalloc.h new file mode 100644 index 0000000000..40d6579ecf --- /dev/null +++ b/headers/cpp/defalloc.h @@ -0,0 +1,95 @@ +/* + * + * 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. + * + */ + +// Inclusion of this file is DEPRECATED. This is the original HP +// default allocator. It is provided only for backward compatibility. +// This file WILL BE REMOVED in a future release. +// +// DO NOT USE THIS FILE unless you have an old container implementation +// that requires an allocator with the HP-style interface. +// +// Standard-conforming allocators have a very different interface. The +// standard default allocator is declared in the header . + +#ifndef DEFALLOC_H +#define DEFALLOC_H + +#include +#include +#include +#include +#if __BEOS__ +# include +#else +#include +#endif +#include + + +template +inline T* allocate(ptrdiff_t size, T*) { + set_new_handler(0); + T* tmp = (T*)(::operator new((size_t)(size * sizeof(T)))); + if (tmp == 0) { +#if __BEOS__ + fprintf(stderr, "out of memory\n"); +#else + cerr << "out of memory" << endl; +#endif + exit(1); + } + return tmp; +} + + +template +inline void deallocate(T* buffer) { + ::operator delete(buffer); +} + +template +class allocator { +public: + typedef T value_type; + typedef T* pointer; + typedef const T* const_pointer; + typedef T& reference; + typedef const T& const_reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + pointer allocate(size_type n) { + return ::allocate((difference_type)n, (pointer)0); + } + void deallocate(pointer p) { ::deallocate(p); } + pointer address(reference x) { return (pointer)&x; } + const_pointer const_address(const_reference x) { + return (const_pointer)&x; + } + size_type init_page_size() { + return max(size_type(1), size_type(4096/sizeof(T))); + } + size_type max_size() const { + return max(size_type(1), size_type(UINT_MAX/sizeof(T))); + } +}; + +class allocator { +public: + typedef void* pointer; +}; + + + +#endif diff --git a/headers/cpp/deque b/headers/cpp/deque new file mode 100644 index 0000000000..61654acad5 --- /dev/null +++ b/headers/cpp/deque @@ -0,0 +1,40 @@ +/* + * + * 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) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_DEQUE +#define __SGI_STL_DEQUE + +#include +#include +#include +#include +#include + +#endif /* __SGI_STL_DEQUE */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/deque.h b/headers/cpp/deque.h new file mode 100644 index 0000000000..ede38b1ceb --- /dev/null +++ b/headers/cpp/deque.h @@ -0,0 +1,42 @@ +/* + * + * 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) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_DEQUE_H +#define __SGI_STL_DEQUE_H + +#include +#include +#include + +#ifdef __STL_USE_NAMESPACES +using __STD::deque; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_DEQUE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/editbuf.h b/headers/cpp/editbuf.h new file mode 100644 index 0000000000..d15758f257 --- /dev/null +++ b/headers/cpp/editbuf.h @@ -0,0 +1,185 @@ +/* This is part of libio/iostream, providing -*- C++ -*- input/output. +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. + +Written by Per Bothner (bothner@cygnus.com). */ + +#ifndef _EDITBUF_H +#define _EDITBUF_H +#ifdef __GNUG__ +#pragma interface +#endif +#include +#include + +extern "C++" { +typedef unsigned long mark_pointer; +// At some point, it might be nice to parameterize this code +// in terms of buf_char. +typedef /*unsigned*/ char buf_char; + +// Logical pos from start of buffer (does not count gap). +typedef long buf_index; + +// Pos from start of buffer, possibly including gap_size. +typedef long buf_offset; + +#if 0 +struct buf_cookie { + FILE *file; + struct edit_string *str; + struct buf_cookie *next; + buf_index tell(); +}; +#endif + +struct edit_buffer; +struct edit_mark; + +// A edit_string is defined as the region between the 'start' and 'end' marks. +// Normally (always?) 'start->insert_before()' should be false, +// and 'end->insert_before()' should be true. + +struct edit_string { + struct edit_buffer *buffer; // buffer that 'start' and 'end' belong to + struct edit_mark *start, *end; + int length() const; // count of buf_chars currently in string + edit_string(struct edit_buffer *b, + struct edit_mark *ms, struct edit_mark *me) + { buffer = b; start = ms; end = me; } +/* Make a fresh, contiguous copy of the data in STR. + Assign length of STR to *LENP. + (Output has extra NUL at out[*LENP].) */ + buf_char *copy_bytes(int *lenp) const; +// FILE *open_file(char *mode); + void assign(struct edit_string *src); // copy bytes from src to this +}; + +struct edit_streambuf : public streambuf { + friend edit_buffer; + edit_string *str; + edit_streambuf* next; // Chain of edit_streambuf's for a edit_buffer. + short _mode; + edit_streambuf(edit_string* bstr, int mode); + ~edit_streambuf(); + virtual int underflow(); + virtual int overflow(int c = EOF); + virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out); + void flush_to_buffer(); + void flush_to_buffer(edit_buffer* buffer); + int _inserting; + int inserting() { return _inserting; } + void inserting(int i) { _inserting = i; } +// int delete_chars(int count, char* cut_buf); Not implemented. + int truncate(); + int is_reading() { return gptr() != NULL; } + buf_char* current() { return is_reading() ? gptr() : pptr(); } + void set_current(char *p, int is_reading); + protected: + void disconnect_gap_from_file(edit_buffer* buffer); +}; + +// A 'edit_mark' indicates a position in a buffer. +// It is "attached" the text (rather than the offset). +// There are two kinds of mark, which have different behavior +// when text is inserted at the mark: +// If 'insert_before()' is true the mark will be adjusted to be +// *after* the new text. + +struct edit_mark { + struct edit_mark *chain; + mark_pointer _pos; + inline int insert_before() { return _pos & 1; } + inline unsigned long index_in_buffer(struct edit_buffer *) + { return _pos >> 1; } + inline buf_char *ptr(struct edit_buffer *buf); + buf_index tell(); + edit_mark() { } + edit_mark(struct edit_string *str, long delta); + edit_buffer *buffer(); + ~edit_mark(); +}; + +// A 'edit_buffer' consists of a sequence of buf_chars (the data), +// a list of edit_marks pointing into the data, and a list of FILEs +// also pointing into the data. +// A 'edit_buffer' coerced to a edit_string is the string of +// all the buf_chars in the buffer. + +// This implementation uses a conventional buffer gap (as in Emacs). +// The gap start is defined by de-referencing a (buf_char**). +// This is because sometimes a FILE is inserting into the buffer, +// so rather than having each putc adjust the gap, we use indirection +// to have the gap be defined as the write pointer of the FILE. +// (This assumes that putc adjusts a pointer (as in GNU's libc), not an index.) + +struct edit_buffer { + buf_char *data; /* == emacs buffer_text.p1+1 */ + buf_char *_gap_start; + edit_streambuf* _writer; // If non-NULL, currently writing stream + inline buf_char *gap_start() + { return _writer ? _writer->pptr() : _gap_start; } + buf_offset __gap_end_pos; // size of part 1 + size of gap + /* int gap; implicit: buf_size - size1 - size2 */ + int buf_size; + struct edit_streambuf *files; + struct edit_mark start_mark; + struct edit_mark end_mark; + edit_buffer(); + inline buf_offset gap_end_pos() { return __gap_end_pos; } + inline struct edit_mark *start_marker() { return &start_mark; } + inline struct edit_mark *end_marker() { return &end_mark; } +/* these should be protected, ultimately */ + buf_index tell(edit_mark*); + buf_index tell(buf_char*); + inline buf_char *gap_end() { return data + gap_end_pos(); } + inline int gap_size() { return gap_end() - gap_start(); } + inline int size1() { return gap_start() - data; } + inline int size2() { return buf_size - gap_end_pos(); } + inline struct edit_mark * mark_list() { return &start_mark; } + void make_gap (buf_offset); + void move_gap (buf_offset pos); + void move_gap (buf_char *pos) { move_gap(pos - data); } + void gap_left (int pos); + void gap_right (int pos); + void adjust_markers(mark_pointer low, mark_pointer high, + int amount, buf_char *old_data); + void delete_range(buf_index from, buf_index to); + void delete_range(struct edit_mark *start, struct edit_mark *end); +}; + +extern buf_char * bstr_copy(struct edit_string *str, int *lenp); + +// Convert a edit_mark to a (buf_char*) + +inline buf_char *edit_mark::ptr(struct edit_buffer *buf) + { return buf->data + index_in_buffer(buf); } + +inline void edit_streambuf::flush_to_buffer() +{ + edit_buffer* buffer = str->buffer; + if (buffer->_writer == this) flush_to_buffer(buffer); +} +} // extern "C++" +#endif /* !_EDITBUF_H*/ + diff --git a/headers/cpp/floatio.h b/headers/cpp/floatio.h new file mode 100644 index 0000000000..827767bde3 --- /dev/null +++ b/headers/cpp/floatio.h @@ -0,0 +1,51 @@ +/* +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + +/* + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * %W% (Berkeley) %G% + */ + +/* + * Floating point scanf/printf (input/output) definitions. + */ + +/* 11-bit exponent (VAX G floating point) is 308 decimal digits */ +#define MAXEXP 308 +/* 128 bit fraction takes up 39 decimal digits; max reasonable precision */ +#define MAXFRACT 39 diff --git a/headers/cpp/fstream b/headers/cpp/fstream new file mode 100644 index 0000000000..2c35ca92b0 --- /dev/null +++ b/headers/cpp/fstream @@ -0,0 +1,7 @@ +// -*- C++ -*- forwarding header. +// This file is part of the GNU ANSI C++ Library. + +#ifndef __FSTREAM__ +#define __FSTREAM__ +#include +#endif diff --git a/headers/cpp/fstream.h b/headers/cpp/fstream.h new file mode 100644 index 0000000000..b5f6598538 --- /dev/null +++ b/headers/cpp/fstream.h @@ -0,0 +1,92 @@ +/* This is part of libio/iostream, providing -*- C++ -*- input/output. +Copyright (C) 1993, 2000 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + +#ifndef _FSTREAM_H +#define _FSTREAM_H +#ifdef __GNUG__ +#pragma interface +#endif +#include + +extern "C++" { +class fstreambase : virtual public ios { +#ifdef _IO_NEW_STREAMS + mutable filebuf __my_fb; // mutable so rdbuf() can be const +#endif + void __fb_init (); + public: + fstreambase(); + fstreambase(int fd); + fstreambase(int fd, char *p, int l); /* Deprecated */ + fstreambase(const char *name, int mode, int prot=0664); + void close(); +#ifdef _IO_NEW_STREAMS + filebuf* rdbuf() const { return &__my_fb; } +#else + filebuf* rdbuf() const { return (filebuf*) ios::rdbuf(); } +#endif + void open(const char *name, int mode, int prot=0664); + int is_open() const { return rdbuf()->is_open(); } + void setbuf(char *ptr, int len) { rdbuf()->setbuf(ptr, len); } + void attach(int fd); +#ifdef _STREAM_COMPAT + int filedesc() { return rdbuf()->fd(); } + fstreambase& raw() { rdbuf()->setbuf(NULL, 0); return *this; } +#endif +}; + +class ifstream : public fstreambase, public istream { + public: + ifstream() : fstreambase() { } + ifstream(int fd) : fstreambase(fd) { } + ifstream(int fd, char *p, int l) : fstreambase(fd, p, l) { } /*Deprecated*/ + ifstream(const char *name, int mode=ios::in, int prot=0664) + : fstreambase(name, mode | ios::in, prot) { } + void open(const char *name, int mode=ios::in, int prot=0664) + { fstreambase::open(name, mode | ios::in, prot); } +}; + +class ofstream : public fstreambase, public ostream { + public: + ofstream() : fstreambase() { } + ofstream(int fd) : fstreambase(fd) { } + ofstream(int fd, char *p, int l) : fstreambase(fd, p, l) { } /*Deprecated*/ + ofstream(const char *name, int mode=ios::out, int prot=0664) + : fstreambase(name, mode | ios::out, prot) { } + void open(const char *name, int mode=ios::out, int prot=0664) + { fstreambase::open(name, mode | ios::out, prot); } +}; + +class fstream : public fstreambase, public iostream { + public: + fstream() : fstreambase() { } + fstream(int fd) : fstreambase(fd) { } + fstream(const char *name, int mode, int prot=0664) + : fstreambase(name, mode, prot) { } + fstream(int fd, char *p, int l) : fstreambase(fd, p, l) { } /*Deprecated*/ + void open(const char *name, int mode, int prot=0664) + { fstreambase::open(name, mode, prot); } +}; +} // extern "C++" +#endif /*!_FSTREAM_H*/ diff --git a/headers/cpp/function.h b/headers/cpp/function.h new file mode 100644 index 0000000000..6474dd99fa --- /dev/null +++ b/headers/cpp/function.h @@ -0,0 +1,118 @@ +/* + * + * 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,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_FUNCTION_H +#define __SGI_STL_FUNCTION_H + +#ifndef __STL_CONFIG_H +#include +#endif +#ifndef __SGI_STL_INTERNAL_RELOPS +#include +#endif +#include +#ifndef __SGI_STL_INTERNAL_FUNCTION_H +#include +#endif + +#ifdef __STL_USE_NAMESPACE_FOR_RELOPS + +// Names from stl_relops.h +using __STD_RELOPS::operator!=; +using __STD_RELOPS::operator>; +using __STD_RELOPS::operator<=; +using __STD_RELOPS::operator>=; + +#endif /* __STL_USE_NAMESPACE_FOR_RELOPS */ + +#ifdef __STL_USE_NAMESPACES + +// Names from stl_function.h +using __STD::unary_function; +using __STD::binary_function; +using __STD::plus; +using __STD::minus; +using __STD::multiplies; +using __STD::divides; +using __STD::identity_element; +using __STD::modulus; +using __STD::negate; +using __STD::equal_to; +using __STD::not_equal_to; +using __STD::greater; +using __STD::less; +using __STD::greater_equal; +using __STD::less_equal; +using __STD::logical_and; +using __STD::logical_or; +using __STD::logical_not; +using __STD::unary_negate; +using __STD::binary_negate; +using __STD::not1; +using __STD::not2; +using __STD::binder1st; +using __STD::binder2nd; +using __STD::bind1st; +using __STD::bind2nd; +using __STD::unary_compose; +using __STD::binary_compose; +using __STD::compose1; +using __STD::compose2; +using __STD::pointer_to_unary_function; +using __STD::pointer_to_binary_function; +using __STD::ptr_fun; +using __STD::identity; +using __STD::select1st; +using __STD::select2nd; +using __STD::project1st; +using __STD::project2nd; +using __STD::constant_void_fun; +using __STD::constant_unary_fun; +using __STD::constant_binary_fun; +using __STD::constant0; +using __STD::constant1; +using __STD::constant2; +using __STD::subtractive_rng; +using __STD::mem_fun_t; +using __STD::const_mem_fun_t; +using __STD::mem_fun_ref_t; +using __STD::const_mem_fun_ref_t; +using __STD::mem_fun1_t; +using __STD::const_mem_fun1_t; +using __STD::mem_fun1_ref_t; +using __STD::const_mem_fun1_ref_t; +using __STD::mem_fun; +using __STD::mem_fun_ref; +using __STD::mem_fun1; +using __STD::mem_fun1_ref; + +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_FUNCTION_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/functional b/headers/cpp/functional new file mode 100644 index 0000000000..d046dbb036 --- /dev/null +++ b/headers/cpp/functional @@ -0,0 +1,26 @@ +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef __SGI_STL_FUNCTIONAL +#define __SGI_STL_FUNCTIONAL + +#include +#include +#include + +#endif /* __SGI_STL_FUNCTIONAL */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/hash_map b/headers/cpp/hash_map new file mode 100644 index 0000000000..f7421e026f --- /dev/null +++ b/headers/cpp/hash_map @@ -0,0 +1,40 @@ +/* + * 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. + * + */ + +#ifndef __SGI_STL_HASH_MAP +#define __SGI_STL_HASH_MAP + +#ifndef __SGI_STL_INTERNAL_HASHTABLE_H +#include +#endif + +#include + +#endif /* __SGI_STL_HASH_MAP */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/hash_map.h b/headers/cpp/hash_map.h new file mode 100644 index 0000000000..f347162704 --- /dev/null +++ b/headers/cpp/hash_map.h @@ -0,0 +1,49 @@ +/* + * 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. + * + */ + +#ifndef __SGI_STL_HASH_MAP_H +#define __SGI_STL_HASH_MAP_H + +#ifndef __SGI_STL_INTERNAL_HASHTABLE_H +#include +#endif + +#include +#include + +#ifdef __STL_USE_NAMESPACES +using __STD::hash; +using __STD::hashtable; +using __STD::hash_map; +using __STD::hash_multimap; +#endif /* __STL_USE_NAMESPACES */ + + +#endif /* __SGI_STL_HASH_MAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/hash_set b/headers/cpp/hash_set new file mode 100644 index 0000000000..2244f47cfa --- /dev/null +++ b/headers/cpp/hash_set @@ -0,0 +1,40 @@ +/* + * 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. + * + */ + +#ifndef __SGI_STL_HASH_SET +#define __SGI_STL_HASH_SET + +#ifndef __SGI_STL_INTERNAL_HASHTABLE_H +#include +#endif + +#include + +#endif /* __SGI_STL_HASH_SET */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/hash_set.h b/headers/cpp/hash_set.h new file mode 100644 index 0000000000..d3e93c0c26 --- /dev/null +++ b/headers/cpp/hash_set.h @@ -0,0 +1,44 @@ +/* + * 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. + * + */ + +#ifndef __SGI_STL_HASH_SET_H +#define __SGI_STL_HASH_SET_H + +#ifndef __SGI_STL_INTERNAL_HASHTABLE_H +#include +#endif + +#include +#include + +#ifdef __STL_USE_NAMESPACES +using __STD::hash; +using __STD::hashtable; +using __STD::hash_set; +using __STD::hash_multiset; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_HASH_SET_H */ diff --git a/headers/cpp/hashtable.h b/headers/cpp/hashtable.h new file mode 100644 index 0000000000..15dbfc9164 --- /dev/null +++ b/headers/cpp/hashtable.h @@ -0,0 +1,48 @@ +/* + * 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. + * + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_HASHTABLE_H +#define __SGI_STL_HASHTABLE_H + +#include +#include +#include +#include + +#ifdef __STL_USE_NAMESPACES +using __STD::hash; +using __STD::hashtable; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_HASHTABLE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/heap.h b/headers/cpp/heap.h new file mode 100644 index 0000000000..2ec93c07b7 --- /dev/null +++ b/headers/cpp/heap.h @@ -0,0 +1,46 @@ +/* + * + * 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) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_HEAP_H +#define __SGI_STL_HEAP_H + +#include +#include + +#ifdef __STL_USE_NAMESPACES + +using __STD::push_heap; +using __STD::pop_heap; +using __STD::make_heap; +using __STD::sort_heap; + +#endif /* __STL_USE_NAMESPACES */ + + +#endif /* __SGI_STL_HEAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/indstream.h b/headers/cpp/indstream.h new file mode 100644 index 0000000000..c4558623d0 --- /dev/null +++ b/headers/cpp/indstream.h @@ -0,0 +1,77 @@ +/* This is part of libio/iostream, providing -*- C++ -*- input/output. +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. + +Written by Per Bothner (bothner@cygnus.com). */ + +#ifndef _INDSTREAM_H +#define _INDSTREAM_H + +#ifdef __GNUG__ +#pragma interface +#endif + +#include + +extern "C++" { +// An indirectbuf is one that forwards all of its I/O requests +// to another streambuf. +// All get-related requests are sent to get_stream(). +// All put-related requests are sent to put_stream(). + +// An indirectbuf can be used to implement Common Lisp +// synonym-streams and two-way-streams. +// +// class synonymbuf : public indirectbuf { +// Symbol *sym; +// synonymbuf(Symbol *s) { sym = s; } +// virtual streambuf *lookup_stream(int mode) { +// return coerce_to_streambuf(lookup_value(sym)); } +// }; + +class indirectbuf : public streambuf { + protected: + streambuf *_get_stream; // Optional cache for get_stream(). + streambuf *_put_stream; // Optional cache for put_stream(). + int _delete_flags; + public: + streambuf *get_stream() + { return _get_stream ? _get_stream : lookup_stream(ios::in); } + streambuf *put_stream() + { return _put_stream ? _put_stream : lookup_stream(ios::out); } + virtual streambuf *lookup_stream(int/*mode*/) { return NULL; } // ERROR! + indirectbuf(streambuf *get=NULL, streambuf *put=NULL, int delete_mode=0); + virtual ~indirectbuf(); + virtual streamsize xsputn(const char* s, streamsize n); + virtual streamsize xsgetn(char* s, streamsize n); + virtual int underflow(); + virtual int uflow(); + virtual int overflow(int c = EOF); + virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out); + virtual streampos seekpos(streampos pos, int mode = ios::in|ios::out); + virtual int sync(); + virtual int pbackfail(int c); +}; +} // extern "C++" + +#endif /* !_INDSTREAM_H */ diff --git a/headers/cpp/iomanip b/headers/cpp/iomanip new file mode 100644 index 0000000000..817948579c --- /dev/null +++ b/headers/cpp/iomanip @@ -0,0 +1,7 @@ +// -*- C++ -*- forwarding header. +// This file is part of the GNU ANSI C++ Library. + +#ifndef __IOMANIP__ +#define __IOMANIP__ +#include +#endif diff --git a/headers/cpp/iomanip.h b/headers/cpp/iomanip.h new file mode 100644 index 0000000000..7c0232ed1e --- /dev/null +++ b/headers/cpp/iomanip.h @@ -0,0 +1,180 @@ +/* This is part of libio/iostream, providing -*- C++ -*- input/output. +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + +#ifndef _IOMANIP_H +#ifdef __GNUG__ +#pragma interface +#endif +#define _IOMANIP_H + +#include + +extern "C++" { +//----------------------------------------------------------------------------- +// Parametrized Manipulators as specified by ANSI draft +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Stream Manipulators +//----------------------------------------------------------------------------- +// +template class smanip; // TP = Type Param + +template class sapp { + ios& (*_f)(ios&, TP); +public: + sapp(ios& (*f)(ios&, TP)) : _f(f) {} + // + smanip operator()(TP a) + { return smanip(_f, a); } +}; + +template +inline istream& operator>>(istream& i, const smanip& m); +template +inline ostream& operator<<(ostream& o, const smanip& m); + +template class smanip { + ios& (*_f)(ios&, TP); + TP _a; +public: + smanip(ios& (*f)(ios&, TP), TP a) : _f(f), _a(a) {} + // + friend + istream& operator>> <>(istream& i, const smanip& m); + friend + ostream& operator<< <>(ostream& o, const smanip& m); +}; + +#ifdef __GNUG__ +__extension__ extern template class smanip; +__extension__ extern template class smanip; +#endif + +template +inline istream& operator>>(istream& i, const smanip& m) +{ (*m._f)(i, m._a); return i; } + +template +inline ostream& operator<<(ostream& o, const smanip& m) +{ (*m._f)(o, m._a); return o;} + +#ifdef __GNUG__ +__extension__ extern +template istream& operator>>(istream&, const smanip&); +__extension__ extern +template istream& operator>>(istream&, const smanip&); +__extension__ extern +template ostream& operator<<(ostream&, const smanip&); +__extension__ extern +template ostream& operator<<(ostream&, const smanip&); +#endif + +//----------------------------------------------------------------------------- +// Input-Stream Manipulators +//----------------------------------------------------------------------------- +// +template class imanip; + +template class iapp { + istream& (*_f)(istream&, TP); +public: + iapp(istream& (*f)(istream&,TP)) : _f(f) {} + // + imanip operator()(TP a) + { return imanip(_f, a); } +}; + +template +inline istream& operator>>(istream&, const imanip&); + +template class imanip { + istream& (*_f)(istream&, TP); + TP _a; +public: + imanip(istream& (*f)(istream&, TP), TP a) : _f(f), _a(a) {} + // + friend + istream& operator>> <>(istream& i, const imanip& m); +}; + +template +inline istream& operator>>(istream& i, const imanip& m) +{ return (*m._f)( i, m._a); } + +//----------------------------------------------------------------------------- +// Output-Stream Manipulators +//----------------------------------------------------------------------------- +// +template class omanip; + +template class oapp { + ostream& (*_f)(ostream&, TP); +public: + oapp(ostream& (*f)(ostream&,TP)) : _f(f) {} + // + omanip operator()(TP a) + { return omanip(_f, a); } +}; + +template +inline ostream& operator<<(ostream&, const omanip&); + +template class omanip { + ostream& (*_f)(ostream&, TP); + TP _a; +public: + omanip(ostream& (*f)(ostream&, TP), TP a) : _f(f), _a(a) {} + // + friend + ostream& operator<< <>(ostream& o, const omanip& m); +}; + +template +inline ostream& operator<<(ostream& o, const omanip& m) +{ return (*m._f)(o, m._a); } + +//----------------------------------------------------------------------------- +// Available Manipulators +//----------------------------------------------------------------------------- + +// +// Macro to define an iomanip function, with one argument +// The underlying function is `__iomanip_' +// +#define __DEFINE_IOMANIP_FN1(type,param,function) \ + extern ios& __iomanip_##function (ios&, param); \ + inline type function (param n) \ + { return type (__iomanip_##function, n); } + +__DEFINE_IOMANIP_FN1( smanip, int, setbase) +__DEFINE_IOMANIP_FN1( smanip, int, setfill) +__DEFINE_IOMANIP_FN1( smanip, int, setprecision) +__DEFINE_IOMANIP_FN1( smanip, int, setw) + +__DEFINE_IOMANIP_FN1( smanip, ios::fmtflags, resetiosflags) +__DEFINE_IOMANIP_FN1( smanip, ios::fmtflags, setiosflags) +} // extern "C++" + +#endif /*!_IOMANIP_H*/ diff --git a/headers/cpp/iosfwd b/headers/cpp/iosfwd new file mode 100644 index 0000000000..8314cf7b73 --- /dev/null +++ b/headers/cpp/iosfwd @@ -0,0 +1,15 @@ +// -*- C++ -*- I/O forward declaration header. +// This file is part of the GNU ANSI C++ Library. + +#ifndef __IOSFWD__ +#define __IOSFWD__ +class ios; +class streambuf; +class istream; +class ostream; +class iostream; +class filebuf; +class ifstream; +class ofstream; +class fstream; +#endif diff --git a/headers/cpp/iostdio.h b/headers/cpp/iostdio.h new file mode 100644 index 0000000000..9ed47a4654 --- /dev/null +++ b/headers/cpp/iostdio.h @@ -0,0 +1,114 @@ +/* +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + +/* This file defines a stdio-like environment, except that it avoid + link-time name clashes with an existing stdio. + It allows for testing the libio using stdio-using programs + with an incompatible libc.a. + It is not predantically correct - e.g. some macros are used + that may evaluate a stream argument more than once. */ + +#ifndef _IOSTDIO_H +#define _IOSTDIO_H + +#include "iolibio.h" + +typedef _IO_FILE FILE; +#ifndef EOF +#define EOF (-1) +#endif +#ifndef BUFSIZ +#define BUFSIZ 1024 +#endif + +/* #define size_t, fpos_t L_tmpname TMP_MAX */ + +#define _IOFBF 0 /* Fully buffered. */ +#define _IOLBF 1 /* Line buffered. */ +#define _IONBF 2 /* No buffering. */ + +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 + +#define stdin _IO_stdin +#define stdout _IO_stdout +#define stderr _IO_stderr + +#define getc(_fp) _IO_getc(_fp) +#define putc(_ch, _fp) _IO_putc(_ch, _fp) + +#define clearerr _IO_clearerr +#define fclose _IO_fclose +#define feof _IO_feof +#define ferror _IO_ferror +#define fflush _IO_fflush +#define fgetc(__fp) _IO_getc(_fp) +#define fgetpos _IO_fgetpos +#define fgets _IO_fgets +#define fopen _IO_fopen +#define fprintf _IO_fprintf +#define fputc(_ch, _fp) _IO_putc(_ch, _fp) +#define fputs _IO_fputs +#define fread _IO_fread +#define freopen _IO_freopen +#define fscanf _IO_fscanf +#define fseek _IO_fseek +#define fsetpos _IO_fsetpos +#define ftell _IO_ftell +#define fwrite _IO_fwrite +#define gets _IO_gets +#define perror _IO_perror +#define printf _IO_printf +#define puts _IO_puts +#define rewind _IO_rewind +#define scanf _IO_scanf +#define setbuf _IO_setbuf +#define setbuffer _IO_setbuffer +#define setvbuf _IO_setvbuf +#define sprintf _IO_sprintf +#define sscanf _IO_sscanf +#define ungetc _IO_ungetc +#define vfprintf _IO_vfprintf +#define vprintf(__fmt, __args) vfprintf(stdout, __fmt, __args) +#define vsprintf _IO_vsprintf + +#if 0 +/* We can use the libc versions of these, since they don't pass FILE*s. */ +#define remove ??? __P((const char*)) +#define rename ??? __P((const char* _old, const char* _new)) +#define tmpfile ??? __P((void)) +#define tmpnam ??? __P((char*)) +#endif + +#if !defined(__STRICT_ANSI__) || defined(_POSIX_SOURCE) +#define fdopen _IO_fdopen +#define fileno _IO_fileno +#define popen _IO_popen +#define pclose _IO_pclose +#define setbuf _IO_setbuf +#define setlinebuf _IO_setlinebuf +#endif + +#endif /* _IOSTDIO_H */ diff --git a/headers/cpp/iostream b/headers/cpp/iostream new file mode 100644 index 0000000000..7ecba6e8da --- /dev/null +++ b/headers/cpp/iostream @@ -0,0 +1,7 @@ +// -*- C++ -*- forwarding header. +// This file is part of the GNU ANSI C++ Library. + +#ifndef __IOSTREAM__ +#define __IOSTREAM__ +#include +#endif diff --git a/headers/cpp/iostream.h b/headers/cpp/iostream.h new file mode 100644 index 0000000000..22b9d69e25 --- /dev/null +++ b/headers/cpp/iostream.h @@ -0,0 +1,289 @@ +/* This is part of libio/iostream, providing -*- C++ -*- input/output. +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + +#ifndef _IOSTREAM_H +#ifdef __GNUG__ +#pragma interface +#endif +#define _IOSTREAM_H + +#include + +extern "C++" { +class istream; class ostream; +typedef ios& (*__manip)(ios&); +typedef istream& (*__imanip)(istream&); +typedef ostream& (*__omanip)(ostream&); + +extern istream& ws(istream& ins); +extern ostream& flush(ostream& outs); +extern ostream& endl(ostream& outs); +extern ostream& ends(ostream& outs); + +class ostream : virtual public ios +{ + // NOTE: If fields are changed, you must fix _fake_ostream in stdstreams.C! + void do_osfx(); + public: + ostream() { } + ostream(streambuf* sb, ostream* tied=NULL); + int opfx() { + if (!good()) return 0; + else { if (_tie) _tie->flush(); _IO_flockfile(_strbuf); return 1;} } + void osfx() { _IO_funlockfile(_strbuf); + if (flags() & (ios::unitbuf|ios::stdio)) + do_osfx(); } + ostream& flush(); + ostream& put(char c) { _strbuf->sputc(c); return *this; } +#ifdef _STREAM_COMPAT + /* Temporary binary compatibility. REMOVE IN NEXT RELEASE. */ + ostream& put(unsigned char c) { return put((char)c); } + ostream& put(signed char c) { return put((char)c); } +#endif + ostream& write(const char *s, streamsize n); + ostream& write(const unsigned char *s, streamsize n) + { return write((const char*)s, n);} + ostream& write(const signed char *s, streamsize n) + { return write((const char*)s, n);} + ostream& write(const void *s, streamsize n) + { return write((const char*)s, n);} +#ifdef _STREAM_COMPAT + // [zooey]: added for R5-compatibility with bdb, + // these can't be inlined as they wouldn't end up in the lib then. + ostream& write(const char *s, int n); + ostream& write(const unsigned char *s, int n); + ostream& write(const signed char *s, int n); + ostream& write(const void *s, int n); +#endif + ostream& seekp(streampos); + ostream& seekp(streamoff, _seek_dir); + streampos tellp(); + ostream& form(const char *format ...); + ostream& vform(const char *format, _IO_va_list args); + + ostream& operator<<(char c); + ostream& operator<<(unsigned char c) { return (*this) << (char)c; } + ostream& operator<<(signed char c) { return (*this) << (char)c; } + ostream& operator<<(const char *s); + ostream& operator<<(const unsigned char *s) + { return (*this) << (const char*)s; } + ostream& operator<<(const signed char *s) + { return (*this) << (const char*)s; } + ostream& operator<<(const void *p); + ostream& operator<<(int n); + ostream& operator<<(unsigned int n); + ostream& operator<<(long n); + ostream& operator<<(unsigned long n); +#if defined(__GNUC__) + __extension__ ostream& operator<<(long long n); + __extension__ ostream& operator<<(unsigned long long n); +#endif + ostream& operator<<(short n) {return operator<<((int)n);} + ostream& operator<<(unsigned short n) {return operator<<((unsigned int)n);} +#if _G_HAVE_BOOL + ostream& operator<<(bool b) { return operator<<((int)b); } +#endif + ostream& operator<<(double n); + ostream& operator<<(float n) { return operator<<((double)n); } +#if _G_HAVE_LONG_DOUBLE_IO + ostream& operator<<(long double n); +#else + ostream& operator<<(long double n) { return operator<<((double)n); } +#endif + ostream& operator<<(__omanip func) { return (*func)(*this); } + ostream& operator<<(__manip func) {(*func)(*this); return *this;} + ostream& operator<<(streambuf*); +#ifdef _STREAM_COMPAT + streambuf* ostreambuf() const { return _strbuf; } +#endif +}; + +class istream : virtual public ios +{ + // NOTE: If fields are changed, you must fix _fake_istream in stdstreams.C! +protected: + _IO_size_t _gcount; + + int _skip_ws(); + public: + istream(): _gcount (0) { } + istream(streambuf* sb, ostream*tied=NULL); + istream& get(char* ptr, int len, char delim = '\n'); + istream& get(unsigned char* ptr, int len, char delim = '\n') + { return get((char*)ptr, len, delim); } + istream& get(char& c); + istream& get(unsigned char& c) { return get((char&)c); } + istream& getline(char* ptr, int len, char delim = '\n'); + istream& getline(unsigned char* ptr, int len, char delim = '\n') + { return getline((char*)ptr, len, delim); } + istream& get(signed char& c) { return get((char&)c); } + istream& get(signed char* ptr, int len, char delim = '\n') + { return get((char*)ptr, len, delim); } + istream& getline(signed char* ptr, int len, char delim = '\n') + { return getline((char*)ptr, len, delim); } + istream& read(char *ptr, streamsize n); + istream& read(unsigned char *ptr, streamsize n) + { return read((char*)ptr, n); } + istream& read(signed char *ptr, streamsize n) + { return read((char*)ptr, n); } + istream& read(void *ptr, streamsize n) + { return read((char*)ptr, n); } +#ifdef _STREAM_COMPAT + // [zooey]: added for R5-compatibility with bdb, + // these can't be inlined as they wouldn't end up in the lib then. + istream& read(char *ptr, int n); + istream& read(unsigned char *ptr, int n); + istream& read(signed char *ptr, int n); + istream& read(void *ptr, int n); +#endif + istream& get(streambuf& sb, char delim = '\n'); + istream& gets(char **s, char delim = '\n'); + int ipfx(int need = 0) { + if (!good()) { set(ios::failbit); return 0; } + else { + _IO_flockfile(_strbuf); + if (_tie && (need == 0 || rdbuf()->in_avail() < need)) _tie->flush(); + if (!need && (flags() & ios::skipws)) return _skip_ws(); + else return 1; + } + } + int ipfx0() { // Optimized version of ipfx(0). + if (!good()) { set(ios::failbit); return 0; } + else { + _IO_flockfile(_strbuf); + if (_tie) _tie->flush(); + if (flags() & ios::skipws) return _skip_ws(); + else return 1; + } + } + int ipfx1() { // Optimized version of ipfx(1). + if (!good()) { set(ios::failbit); return 0; } + else { + _IO_flockfile(_strbuf); + if (_tie && rdbuf()->in_avail() == 0) _tie->flush(); + return 1; + } + } + void isfx() { _IO_funlockfile(_strbuf); } + int get() { if (!ipfx1()) return EOF; + else { int ch = _strbuf->sbumpc(); + if (ch == EOF) set(ios::eofbit); + isfx(); + return ch; + } } + int peek(); + _IO_size_t gcount() { return _gcount; } + istream& ignore(int n=1, int delim = EOF); + int sync (); + istream& seekg(streampos); + istream& seekg(streamoff, _seek_dir); + streampos tellg(); + istream& putback(char ch) { + if (good() && _strbuf->sputbackc(ch) == EOF) clear(ios::badbit); + return *this;} + istream& unget() { + if (good() && _strbuf->sungetc() == EOF) clear(ios::badbit); + return *this;} + istream& scan(const char *format ...); + istream& vscan(const char *format, _IO_va_list args); +#ifdef _STREAM_COMPAT + istream& unget(char ch) { return putback(ch); } + int skip(int i); + streambuf* istreambuf() const { return _strbuf; } +#endif + + istream& operator>>(char*); + istream& operator>>(unsigned char* p) { return operator>>((char*)p); } + istream& operator>>(signed char*p) { return operator>>((char*)p); } + istream& operator>>(char& c); + istream& operator>>(unsigned char& c) {return operator>>((char&)c);} + istream& operator>>(signed char& c) {return operator>>((char&)c);} + istream& operator>>(int&); + istream& operator>>(long&); +#if defined(__GNUC__) + __extension__ istream& operator>>(long long&); + __extension__ istream& operator>>(unsigned long long&); +#endif + istream& operator>>(short&); + istream& operator>>(unsigned int&); + istream& operator>>(unsigned long&); + istream& operator>>(unsigned short&); +#if _G_HAVE_BOOL + istream& operator>>(bool&); +#endif + istream& operator>>(float&); + istream& operator>>(double&); + istream& operator>>(long double&); + istream& operator>>( __manip func) {(*func)(*this); return *this;} + istream& operator>>(__imanip func) { return (*func)(*this); } + istream& operator>>(streambuf*); +}; + +class iostream : public istream, public ostream +{ + public: + iostream() { } + iostream(streambuf* sb, ostream*tied=NULL); +}; + +class _IO_istream_withassign : public istream { +public: + _IO_istream_withassign& operator=(istream&); + _IO_istream_withassign& operator=(_IO_istream_withassign& rhs) + { return operator= (static_cast (rhs)); } +}; + +class _IO_ostream_withassign : public ostream { +public: + _IO_ostream_withassign& operator=(ostream&); + _IO_ostream_withassign& operator=(_IO_ostream_withassign& rhs) + { return operator= (static_cast (rhs)); } +}; + +extern _IO_istream_withassign cin; +// clog->rdbuf() == cerr->rdbuf() +extern _IO_ostream_withassign cout, cerr; + +extern _IO_ostream_withassign clog +#if _G_CLOG_CONFLICT +__asm__ ("__IO_clog") +#endif +; + +extern istream& lock(istream& ins); +extern istream& unlock(istream& ins); +extern ostream& lock(ostream& outs); +extern ostream& unlock(ostream& outs); + +struct Iostream_init { } ; // Compatibility hack for AT&T library. + +inline ios& dec(ios& i) +{ i.setf(ios::dec, ios::dec|ios::hex|ios::oct); return i; } +inline ios& hex(ios& i) +{ i.setf(ios::hex, ios::dec|ios::hex|ios::oct); return i; } +inline ios& oct(ios& i) +{ i.setf(ios::oct, ios::dec|ios::hex|ios::oct); return i; } +} // extern "C++" + +#endif /*!_IOSTREAM_H*/ diff --git a/headers/cpp/istream.h b/headers/cpp/istream.h new file mode 100644 index 0000000000..f54ec1de9a --- /dev/null +++ b/headers/cpp/istream.h @@ -0,0 +1,25 @@ +/* +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General 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 diff --git a/headers/cpp/iterator b/headers/cpp/iterator new file mode 100644 index 0000000000..4ddd208f27 --- /dev/null +++ b/headers/cpp/iterator @@ -0,0 +1,44 @@ +/* + * + * 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,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_ITERATOR +#define __SGI_STL_ITERATOR + +#include +#include +#include /* XXX should use */ +#if 0 /* XXX define a flag for this */ +#include +#else +#include +#endif +#include + +#endif /* __SGI_STL_ITERATOR */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/iterator.h b/headers/cpp/iterator.h new file mode 100644 index 0000000000..f8a0237742 --- /dev/null +++ b/headers/cpp/iterator.h @@ -0,0 +1,104 @@ +/* + * + * 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. + */ + +#ifndef __SGI_STL_ITERATOR_H +#define __SGI_STL_ITERATOR_H + +#ifndef __SGI_STL_FUNCTION_H +#include +#endif +#include +#include +#ifndef __SGI_STL_INTERNAL_ITERATOR_H +#include +#endif +#ifndef __TYPE_TRAITS_H +#include +#endif +#ifndef __SGI_STL_INTERNAL_CONSTRUCT_H +#include +#endif +#ifndef __SGI_STL_INTERNAL_RAW_STORAGE_ITERATOR_H +#include +#endif + +#ifdef __STL_USE_NAMESPACES + +// Names from stl_iterator.h + +using __STD::input_iterator_tag; +using __STD::output_iterator_tag; +using __STD::forward_iterator_tag; +using __STD::bidirectional_iterator_tag; +using __STD::random_access_iterator_tag; + +#if 0 +using __STD::iterator; +#endif +using __STD::input_iterator; +using __STD::output_iterator; +using __STD::forward_iterator; +using __STD::bidirectional_iterator; +using __STD::random_access_iterator; + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION +using __STD::iterator_traits; +#endif + +using __STD::iterator_category; +using __STD::distance_type; +using __STD::value_type; + +using __STD::distance; +using __STD::advance; + +using __STD::insert_iterator; +using __STD::front_insert_iterator; +using __STD::back_insert_iterator; +using __STD::inserter; +using __STD::front_inserter; +using __STD::back_inserter; + +using __STD::reverse_iterator; +using __STD::reverse_bidirectional_iterator; + +using __STD::istream_iterator; +using __STD::ostream_iterator; + +// Names from stl_construct.h +using __STD::construct; +using __STD::destroy; + +// Names from stl_raw_storage_iter.h +using __STD::raw_storage_iterator; + +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_ITERATOR_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/list b/headers/cpp/list new file mode 100644 index 0000000000..5294f39fea --- /dev/null +++ b/headers/cpp/list @@ -0,0 +1,40 @@ +/* + * + * 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,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_LIST +#define __SGI_STL_LIST + +#include +#include +#include +#include +#include + +#endif /* __SGI_STL_LIST */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/list.h b/headers/cpp/list.h new file mode 100644 index 0000000000..4e6ee0b411 --- /dev/null +++ b/headers/cpp/list.h @@ -0,0 +1,42 @@ +/* + * + * 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,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_LIST_H +#define __SGI_STL_LIST_H + +#include +#include +#include + +#ifdef __STL_USE_NAMESPACES +using __STD::list; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_LIST_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/map b/headers/cpp/map new file mode 100644 index 0000000000..4cfb7652c5 --- /dev/null +++ b/headers/cpp/map @@ -0,0 +1,40 @@ +/* + * + * 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,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_MAP +#define __SGI_STL_MAP + +#ifndef __SGI_STL_INTERNAL_TREE_H +#include +#endif +#include +#include + +#endif /* __SGI_STL_MAP */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/map.h b/headers/cpp/map.h new file mode 100644 index 0000000000..a89bd31e81 --- /dev/null +++ b/headers/cpp/map.h @@ -0,0 +1,41 @@ +/* + * + * 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,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_MAP_H +#define __SGI_STL_MAP_H + +#include +#include + +#ifdef __STL_USE_NAMESPACES +using __STD::map; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_MAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/memory b/headers/cpp/memory new file mode 100644 index 0000000000..64338dd313 --- /dev/null +++ b/headers/cpp/memory @@ -0,0 +1,108 @@ +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef __SGI_STL_MEMORY +#define __SGI_STL_MEMORY + +#include +#include +#include +#include +#include +#include + + +#if defined(__STL_MEMBER_TEMPLATES) + +__STL_BEGIN_NAMESPACE + +template class auto_ptr { +private: + _Tp* _M_ptr; + +public: + typedef _Tp element_type; + explicit auto_ptr(_Tp* __p = 0) __STL_NOTHROW : _M_ptr(__p) {} + auto_ptr(auto_ptr& __a) __STL_NOTHROW : _M_ptr(__a.release()) {} + template auto_ptr(auto_ptr<_Tp1>& __a) __STL_NOTHROW + : _M_ptr(__a.release()) {} + auto_ptr& operator=(auto_ptr& __a) __STL_NOTHROW { + if (&__a != this) { + delete _M_ptr; + _M_ptr = __a.release(); + } + return *this; + } + template + auto_ptr& operator=(auto_ptr<_Tp1>& __a) __STL_NOTHROW { + if (__a.get() != this->get()) { + delete _M_ptr; + _M_ptr = __a.release(); + } + return *this; + } + ~auto_ptr() __STL_NOTHROW { delete _M_ptr; } + + _Tp& operator*() const __STL_NOTHROW { + return *_M_ptr; + } + _Tp* operator->() const __STL_NOTHROW { + return _M_ptr; + } + _Tp* get() const __STL_NOTHROW { + return _M_ptr; + } + _Tp* release() __STL_NOTHROW { + _Tp* __tmp = _M_ptr; + _M_ptr = 0; + return __tmp; + } + void reset(_Tp* __p = 0) __STL_NOTHROW { + delete _M_ptr; + _M_ptr = __p; + } + + // According to the C++ standard, these conversions are required. Most + // present-day compilers, however, do not enforce that requirement---and, + // in fact, most present-day compilers do not support the language + // features that these conversions rely on. + +#ifdef __SGI_STL_USE_AUTO_PTR_CONVERSIONS + +private: + template struct auto_ptr_ref { + _Tp1* _M_ptr; + auto_ptr_ref(_Tp1* __p) : _M_ptr(__p) {} + }; + +public: + auto_ptr(auto_ptr_ref<_Tp> __ref) __STL_NOTHROW + : _M_ptr(__ref._M_ptr) {} + template operator auto_ptr_ref<_Tp1>() __STL_NOTHROW + { return auto_ptr_ref<_Tp>(this->release()); } + template operator auto_ptr<_Tp1>() __STL_NOTHROW + { return auto_ptr<_Tp1>(this->release()); } + +#endif /* __SGI_STL_USE_AUTO_PTR_CONVERSIONS */ +}; + +__STL_END_NAMESPACE +#endif /* member templates */ + +#endif /* __SGI_STL_MEMORY */ + + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/multimap.h b/headers/cpp/multimap.h new file mode 100644 index 0000000000..1a8ec4af4f --- /dev/null +++ b/headers/cpp/multimap.h @@ -0,0 +1,41 @@ +/* + * + * 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,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_MULTIMAP_H +#define __SGI_STL_MULTIMAP_H + +#include +#include + +#ifdef __STL_USE_NAMESPACES +using __STD::multimap; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_MULTIMAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/multiset.h b/headers/cpp/multiset.h new file mode 100644 index 0000000000..3024fd74c0 --- /dev/null +++ b/headers/cpp/multiset.h @@ -0,0 +1,41 @@ +/* + * + * 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,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_MULTISET_H +#define __SGI_STL_MULTISET_H + +#include +#include + +#ifdef __STL_USE_NAMESPACES +using __STD::multiset; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_MULTISET_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/numeric b/headers/cpp/numeric new file mode 100644 index 0000000000..7f048e11b5 --- /dev/null +++ b/headers/cpp/numeric @@ -0,0 +1,42 @@ +/* + * + * 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,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_NUMERIC +#define __SGI_STL_NUMERIC + +#include +#include +#include +#include +#include +#include +#include + +#endif /* __SGI_STL_NUMERIC */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/ostream.h b/headers/cpp/ostream.h new file mode 100644 index 0000000000..f54ec1de9a --- /dev/null +++ b/headers/cpp/ostream.h @@ -0,0 +1,25 @@ +/* +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General 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 diff --git a/headers/cpp/pair.h b/headers/cpp/pair.h new file mode 100644 index 0000000000..00f5caddb6 --- /dev/null +++ b/headers/cpp/pair.h @@ -0,0 +1,51 @@ +/* + * + * 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,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_PAIR_H +#define __SGI_STL_PAIR_H + +#ifndef __STL_CONFIG_H +#include +#endif +#ifndef __SGI_STL_INTERNAL_RELOPS +#include +#endif +#ifndef __SGI_STL_INTERNAL_PAIR_H +#include +#endif + +#ifdef __STL_USE_NAMESPACES + +using __STD::pair; +using __STD::make_pair; + +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_PAIR_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/parsestream.h b/headers/cpp/parsestream.h new file mode 100644 index 0000000000..97655bcbf6 --- /dev/null +++ b/headers/cpp/parsestream.h @@ -0,0 +1,156 @@ +/* This is part of libio/iostream, providing -*- C++ -*- input/output. +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. + +Written by Per Bothner (bothner@cygnus.com). */ + +#ifndef PARSESTREAM_H +#define PARSESTREAM_H +#ifdef __GNUG__ +#pragma interface +#endif +#include "streambuf.h" + +extern "C++" { +// A parsebuf is a streambuf optimized for scanning text files. +// It keeps track of line and column numbers. +// It is guaranteed to remember the entire current line, +// as well the '\n'-s on either side of it (if they exist). +// You can arbitrarily seek (or unget) within this extended line. +// Other backward seeks are not supported. +// Normal read semantics are supported (and hence istream operators like >>). + +class parsebuf : public streambuf { + protected: + _IO_off_t pos_at_line_start; + long _line_length; + unsigned long __line_number; + char *buf_start; + char *buf_end; + + public: + parsebuf *chain; + + // Return column number (raw - don't handle tabs etc). + // Retult can be -1, meaning: at '\n' before current line. + virtual int tell_in_line(); + + // seek to (raw) column I in current line. + // Result is new (raw) column position - differs from I if unable to seek. + // Seek to -1 tries to seek to before previous LF. + virtual int seek_in_line(int i); + + // Note: there is no "current line" initially, until something is read. + + // Current line number, starting with 0. + // If tell_in_line()==-1, then line number of next line. + int line_number() { return __line_number; } + + // Length of current line, not counting either '\n'. + int line_length() { return _line_length; } + // Current line - not a copy, so file ops may trash it. + virtual char* current_line(); + virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out); + virtual streambuf* setbuf(char* p, int len); + protected: + parsebuf() { chain= NULL; + __line_number = 0; pos_at_line_start = 0; _line_length = -1; } + virtual int pbackfail(int c); +}; + +// A string_parsebuf is a parsebuf whose source is a fixed string. + +class string_parsebuf : public parsebuf { + public: + int do_delete; + string_parsebuf(char *str, int len, int delete_at_close=0); + virtual int underflow(); + virtual char* current_line(); + virtual int seek_in_line(int i); + virtual int tell_in_line(); + char *left() const { return base(); } + char *right() const { return ebuf(); } +// streampos seekoff(streamoff, _seek_dir, int); +}; + +// A func_parsebuf calls a given function to get new input. +// Each call returns an entire NUL-terminated line (without the '\n'). +// That line has been allocated with malloc(), not new. +// The interface is tailored to the GNU readline library. +// Example: +// char* DoReadLine(void* arg) +// { +// char *line = readline((char*)arg); /* 'arg' is used as prompt. */ +// if line == NULL) { putc('\n', stderr); return NULL; } +// if (line[0] != '\0') add_history(line); +// return line; +// } +// char PromptBuffer[100] = "> "; +// func_parsebuf my_stream(DoReadLine, PromptBuffer); + +typedef char *(*CharReader)(void *arg); +class istream; + +class func_parsebuf : public parsebuf { + public: + void *arg; + CharReader read_func; + int backed_up_to_newline; + func_parsebuf(CharReader func, void *argm = NULL); + int underflow(); + virtual int tell_in_line(); + virtual int seek_in_line(int i); + virtual char* current_line(); +}; + +// A general_parsebuf is a parsebuf which gets its input from some +// other streambuf. It explicitly buffers up an entire line. + +class general_parsebuf : public parsebuf { + public: + streambuf *sbuf; + int delete_buf; // Delete sbuf when destroying this. + general_parsebuf(streambuf *buf, int delete_arg_buf = 0); + int underflow(); + virtual int tell_in_line(); + virtual int seek_in_line(int i); + ~general_parsebuf(); + virtual char* current_line(); +}; + +#if 0 +class parsestream : public istream { + streammarker marks[2]; + short _first; // of the two marks; either 0 or 1 + int _lineno; + int first() { return _first; } + int second() { return 1-_first; } + int line_length() { marks[second].delta(marks[first]); } + int line_length() { marks[second].delta(marks[first]); } + int seek_in_line(int i); + int tell_in_line(); + int line_number(); +}; +#endif +} // extern "C++" +#endif /*!defined(PARSESTREAM_H)*/ diff --git a/headers/cpp/pfstream.h b/headers/cpp/pfstream.h new file mode 100644 index 0000000000..3c5458baaa --- /dev/null +++ b/headers/cpp/pfstream.h @@ -0,0 +1,59 @@ +/* This is part of libio/iostream, providing -*- C++ -*- input/output. +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + +/* Written by Per Bothner (bothner@cygnus.com). */ + +#ifndef _PFSTREAM_H +#define _PFSTREAM_H +#ifdef __GNUG__ +#pragma interface +#endif +#include + +extern "C++" { +// ipfstream foo("NAME") is like: ifstream foo("NAME"). However, +// if NAME starts *or ends* with a '|', the remainder of NAME is +// evaluated as a shell command (using a procbuf), and all input +// read from foo is whatever that shell writes to its standard output. +// E.g. ipfstream foo("|zcat foo.Z") or ipfstream foo("zcat foo.Z|") +// (These two forms are equivalent.) + +class ipfstream : public ifstream { + public: + ipfstream(const char *name, int mode=ios::in, int prot=0664); +}; + +// opfstream foo("NAME") is like: ofstream foo("NAME"). +// However, if NAME starts with a '|', the remainder of NAME is +// evaluated as a shell command (using a procbuf), and all output +// written to foo is piped to the standard input of that shell. +// E.g. opfstream foo("|more"); + +class opfstream : public ofstream { + public: + opfstream(const char *name, int mode=ios::out, int prot=0664); +}; +} // extern "C++" +#endif /*!_PFSTREAM_H*/ + diff --git a/headers/cpp/procbuf.h b/headers/cpp/procbuf.h new file mode 100644 index 0000000000..b361a6a7c8 --- /dev/null +++ b/headers/cpp/procbuf.h @@ -0,0 +1,50 @@ +/* This is part of libio/iostream, providing -*- C++ -*- input/output. +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + +/* Written by Per Bothner (bothner@cygnus.com). */ + +#ifndef _PROCBUF_H +#define _PROCBUF_H +#ifdef __GNUG__ +#pragma interface +#endif + +#include + +extern "C++" { +class procbuf : public filebuf { + /* Following fields must match those in struct _IO_proc_file */ + _IO_pid_t _pid; + procbuf *_next; + public: + procbuf() : filebuf() { } + procbuf(const char *command, int mode); + procbuf* open(const char *command, int mode); + procbuf *close() { return (procbuf*)filebuf::close(); } + virtual int sys_close(); + ~procbuf(); +}; +} // extern "C++" + +#endif /* !_PROCBUF_H */ diff --git a/headers/cpp/pthread_alloc b/headers/cpp/pthread_alloc new file mode 100644 index 0000000000..1852908095 --- /dev/null +++ b/headers/cpp/pthread_alloc @@ -0,0 +1,479 @@ +/* + * 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. + */ + +#ifndef __SGI_STL_PTHREAD_ALLOC +#define __SGI_STL_PTHREAD_ALLOC + +// Pthread-specific node allocator. +// This is similar to the default allocator, except that free-list +// information is kept separately for each thread, avoiding locking. +// This should be reasonably fast even in the presence of threads. +// The down side is that storage may not be well-utilized. +// It is not an error to allocate memory in thread A and deallocate +// it in thread B. But this effectively transfers ownership of the memory, +// so that it can only be reallocated by thread B. Thus this can effectively +// result in a storage leak if it's done on a regular basis. +// It can also result in frequent sharing of +// cache lines among processors, with potentially serious performance +// consequences. + +#include +#include +#ifndef __RESTRICT +# define __RESTRICT +#endif + +__STL_BEGIN_NAMESPACE + +#define __STL_DATA_ALIGNMENT 8 + +union _Pthread_alloc_obj { + union _Pthread_alloc_obj * __free_list_link; + char __client_data[__STL_DATA_ALIGNMENT]; /* The client sees this. */ +}; + +// Pthread allocators don't appear to the client to have meaningful +// instances. We do in fact need to associate some state with each +// thread. That state is represented by +// _Pthread_alloc_per_thread_state<_Max_size>. + +template +struct _Pthread_alloc_per_thread_state { + typedef _Pthread_alloc_obj __obj; + enum { _S_NFREELISTS = _Max_size/__STL_DATA_ALIGNMENT }; + _Pthread_alloc_obj* volatile __free_list[_S_NFREELISTS]; + _Pthread_alloc_per_thread_state<_Max_size> * __next; + // Free list link for list of available per thread structures. + // When one of these becomes available for reuse due to thread + // termination, any objects in its free list remain associated + // with it. The whole structure may then be used by a newly + // created thread. + _Pthread_alloc_per_thread_state() : __next(0) + { + memset((void *)__free_list, 0, _S_NFREELISTS * sizeof(__obj *)); + } + // Returns an object of size __n, and possibly adds to size n free list. + void *_M_refill(size_t __n); +}; + +// Pthread-specific allocator. +// The argument specifies the largest object size allocated from per-thread +// free lists. Larger objects are allocated using malloc_alloc. +// Max_size must be a power of 2. +template +class _Pthread_alloc_template { + +public: // but only for internal use: + + typedef _Pthread_alloc_obj __obj; + + // Allocates a chunk for nobjs of size "size". nobjs may be reduced + // if it is inconvenient to allocate the requested number. + static char *_S_chunk_alloc(size_t __size, int &__nobjs); + + enum {_S_ALIGN = __STL_DATA_ALIGNMENT}; + + static size_t _S_round_up(size_t __bytes) { + return (((__bytes) + _S_ALIGN-1) & ~(_S_ALIGN - 1)); + } + static size_t _S_freelist_index(size_t __bytes) { + return (((__bytes) + _S_ALIGN-1)/_S_ALIGN - 1); + } + +private: + // Chunk allocation state. And other shared state. + // Protected by _S_chunk_allocator_lock. + static pthread_mutex_t _S_chunk_allocator_lock; + static char *_S_start_free; + static char *_S_end_free; + static size_t _S_heap_size; + static _Pthread_alloc_per_thread_state<_Max_size>* _S_free_per_thread_states; + static pthread_key_t _S_key; + static bool _S_key_initialized; + // Pthread key under which per thread state is stored. + // Allocator instances that are currently unclaimed by any thread. + static void _S_destructor(void *instance); + // Function to be called on thread exit to reclaim per thread + // state. + static _Pthread_alloc_per_thread_state<_Max_size> *_S_new_per_thread_state(); + // Return a recycled or new per thread state. + static _Pthread_alloc_per_thread_state<_Max_size> *_S_get_per_thread_state(); + // ensure that the current thread has an associated + // per thread state. + friend class _M_lock; + class _M_lock { + public: + _M_lock () { pthread_mutex_lock(&_S_chunk_allocator_lock); } + ~_M_lock () { pthread_mutex_unlock(&_S_chunk_allocator_lock); } + }; + +public: + + /* n must be > 0 */ + static void * allocate(size_t __n) + { + __obj * volatile * __my_free_list; + __obj * __RESTRICT __result; + _Pthread_alloc_per_thread_state<_Max_size>* __a; + + if (__n > _Max_size) { + return(malloc_alloc::allocate(__n)); + } + if (!_S_key_initialized || + !(__a = (_Pthread_alloc_per_thread_state<_Max_size>*) + pthread_getspecific(_S_key))) { + __a = _S_get_per_thread_state(); + } + __my_free_list = __a -> __free_list + _S_freelist_index(__n); + __result = *__my_free_list; + if (__result == 0) { + void *__r = __a -> _M_refill(_S_round_up(__n)); + return __r; + } + *__my_free_list = __result -> __free_list_link; + return (__result); + }; + + /* p may not be 0 */ + static void deallocate(void *__p, size_t __n) + { + __obj *__q = (__obj *)__p; + __obj * volatile * __my_free_list; + _Pthread_alloc_per_thread_state<_Max_size>* __a; + + if (__n > _Max_size) { + malloc_alloc::deallocate(__p, __n); + return; + } + if (!_S_key_initialized || + !(__a = (_Pthread_alloc_per_thread_state<_Max_size> *) + pthread_getspecific(_S_key))) { + __a = _S_get_per_thread_state(); + } + __my_free_list = __a->__free_list + _S_freelist_index(__n); + __q -> __free_list_link = *__my_free_list; + *__my_free_list = __q; + } + + static void * reallocate(void *__p, size_t __old_sz, size_t __new_sz); + +} ; + +typedef _Pthread_alloc_template<> pthread_alloc; + + +template +void _Pthread_alloc_template<_Max_size>::_S_destructor(void * __instance) +{ + _M_lock __lock_instance; // Need to acquire lock here. + _Pthread_alloc_per_thread_state<_Max_size>* __s = + (_Pthread_alloc_per_thread_state<_Max_size> *)__instance; + __s -> __next = _S_free_per_thread_states; + _S_free_per_thread_states = __s; +} + +template +_Pthread_alloc_per_thread_state<_Max_size> * +_Pthread_alloc_template<_Max_size>::_S_new_per_thread_state() +{ + /* lock already held here. */ + if (0 != _S_free_per_thread_states) { + _Pthread_alloc_per_thread_state<_Max_size> *__result = + _S_free_per_thread_states; + _S_free_per_thread_states = _S_free_per_thread_states -> __next; + return __result; + } else { + return new _Pthread_alloc_per_thread_state<_Max_size>; + } +} + +template +_Pthread_alloc_per_thread_state<_Max_size> * +_Pthread_alloc_template<_Max_size>::_S_get_per_thread_state() +{ + /*REFERENCED*/ + _M_lock __lock_instance; // Need to acquire lock here. + _Pthread_alloc_per_thread_state<_Max_size> * __result; + if (!_S_key_initialized) { + if (pthread_key_create(&_S_key, _S_destructor)) { + abort(); // failed + } + _S_key_initialized = true; + } + __result = _S_new_per_thread_state(); + if (pthread_setspecific(_S_key, __result)) abort(); + return __result; +} + +/* We allocate memory in large chunks in order to avoid fragmenting */ +/* the malloc heap too much. */ +/* We assume that size is properly aligned. */ +template +char *_Pthread_alloc_template<_Max_size> +::_S_chunk_alloc(size_t __size, int &__nobjs) +{ + { + char * __result; + size_t __total_bytes; + size_t __bytes_left; + /*REFERENCED*/ + _M_lock __lock_instance; // Acquire lock for this routine + + __total_bytes = __size * __nobjs; + __bytes_left = _S_end_free - _S_start_free; + if (__bytes_left >= __total_bytes) { + __result = _S_start_free; + _S_start_free += __total_bytes; + return(__result); + } else if (__bytes_left >= __size) { + __nobjs = __bytes_left/__size; + __total_bytes = __size * __nobjs; + __result = _S_start_free; + _S_start_free += __total_bytes; + return(__result); + } else { + size_t __bytes_to_get = + 2 * __total_bytes + _S_round_up(_S_heap_size >> 4); + // Try to make use of the left-over piece. + if (__bytes_left > 0) { + _Pthread_alloc_per_thread_state<_Max_size>* __a = + (_Pthread_alloc_per_thread_state<_Max_size>*) + pthread_getspecific(_S_key); + __obj * volatile * __my_free_list = + __a->__free_list + _S_freelist_index(__bytes_left); + + ((__obj *)_S_start_free) -> __free_list_link = *__my_free_list; + *__my_free_list = (__obj *)_S_start_free; + } +# ifdef _SGI_SOURCE + // Try to get memory that's aligned on something like a + // cache line boundary, so as to avoid parceling out + // parts of the same line to different threads and thus + // possibly different processors. + { + const int __cache_line_size = 128; // probable upper bound + __bytes_to_get &= ~(__cache_line_size-1); + _S_start_free = (char *)memalign(__cache_line_size, __bytes_to_get); + if (0 == _S_start_free) { + _S_start_free = (char *)malloc_alloc::allocate(__bytes_to_get); + } + } +# else /* !SGI_SOURCE */ + _S_start_free = (char *)malloc_alloc::allocate(__bytes_to_get); +# endif + _S_heap_size += __bytes_to_get; + _S_end_free = _S_start_free + __bytes_to_get; + } + } + // lock is released here + return(_S_chunk_alloc(__size, __nobjs)); +} + + +/* Returns an object of size n, and optionally adds to size n free list.*/ +/* We assume that n is properly aligned. */ +/* We hold the allocation lock. */ +template +void *_Pthread_alloc_per_thread_state<_Max_size> +::_M_refill(size_t __n) +{ + int __nobjs = 128; + char * __chunk = + _Pthread_alloc_template<_Max_size>::_S_chunk_alloc(__n, __nobjs); + __obj * volatile * __my_free_list; + __obj * __result; + __obj * __current_obj, * __next_obj; + int __i; + + if (1 == __nobjs) { + return(__chunk); + } + __my_free_list = __free_list + + _Pthread_alloc_template<_Max_size>::_S_freelist_index(__n); + + /* Build free list in chunk */ + __result = (__obj *)__chunk; + *__my_free_list = __next_obj = (__obj *)(__chunk + __n); + for (__i = 1; ; __i++) { + __current_obj = __next_obj; + __next_obj = (__obj *)((char *)__next_obj + __n); + if (__nobjs - 1 == __i) { + __current_obj -> __free_list_link = 0; + break; + } else { + __current_obj -> __free_list_link = __next_obj; + } + } + return(__result); +} + +template +void *_Pthread_alloc_template<_Max_size> +::reallocate(void *__p, size_t __old_sz, size_t __new_sz) +{ + void * __result; + size_t __copy_sz; + + if (__old_sz > _Max_size + && __new_sz > _Max_size) { + return(realloc(__p, __new_sz)); + } + if (_S_round_up(__old_sz) == _S_round_up(__new_sz)) return(__p); + __result = allocate(__new_sz); + __copy_sz = __new_sz > __old_sz? __old_sz : __new_sz; + memcpy(__result, __p, __copy_sz); + deallocate(__p, __old_sz); + return(__result); +} + +template +_Pthread_alloc_per_thread_state<_Max_size> * +_Pthread_alloc_template<_Max_size>::_S_free_per_thread_states = 0; + +template +pthread_key_t _Pthread_alloc_template<_Max_size>::_S_key; + +template +bool _Pthread_alloc_template<_Max_size>::_S_key_initialized = false; + +template +pthread_mutex_t _Pthread_alloc_template<_Max_size>::_S_chunk_allocator_lock += PTHREAD_MUTEX_INITIALIZER; + +template +char *_Pthread_alloc_template<_Max_size> +::_S_start_free = 0; + +template +char *_Pthread_alloc_template<_Max_size> +::_S_end_free = 0; + +template +size_t _Pthread_alloc_template<_Max_size> +::_S_heap_size = 0; + +#ifdef __STL_USE_STD_ALLOCATORS + +template +class pthread_allocator { + typedef pthread_alloc _S_Alloc; // The underlying allocator. +public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef _Tp value_type; + + template struct rebind { + typedef pthread_allocator<_Up> other; + }; + + pthread_allocator() __STL_NOTHROW {} + pthread_allocator(const pthread_allocator& a) __STL_NOTHROW {} + template pthread_allocator(const pthread_allocator<_Up>&) + __STL_NOTHROW {} + ~pthread_allocator() __STL_NOTHROW {} + + pointer address(reference __x) const { return &__x; } + const_pointer address(const_reference __x) const { return &__x; } + + // __n is permitted to be 0. The C++ standard says nothing about what + // the return value is when __n == 0. + _Tp* allocate(size_type __n, const void* = 0) { + return __n != 0 ? static_cast<_Tp*>(_S_Alloc::allocate(__n * sizeof(_Tp))) + : 0; + } + + // p is not permitted to be a null pointer. + void deallocate(pointer __p, size_type __n) + { _S_Alloc::deallocate(__p, __n * sizeof(_Tp)); } + + size_type max_size() const __STL_NOTHROW + { return size_t(-1) / sizeof(_Tp); } + + void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); } + void destroy(pointer _p) { _p->~_Tp(); } +}; + +template<> +class pthread_allocator { +public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef void* pointer; + typedef const void* const_pointer; + typedef void value_type; + + template struct rebind { + typedef pthread_allocator<_Up> other; + }; +}; + +template +inline bool operator==(const _Pthread_alloc_template<_Max_size>&, + const _Pthread_alloc_template<_Max_size>&) +{ + return true; +} + +template +inline bool operator==(const pthread_allocator<_T1>&, + const pthread_allocator<_T2>& a2) +{ + return true; +} + +template +inline bool operator!=(const pthread_allocator<_T1>&, + const pthread_allocator<_T2>&) +{ + return false; +} + +template +struct _Alloc_traits<_Tp, _Pthread_alloc_template<_Max_size> > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, _Pthread_alloc_template<_Max_size> > _Alloc_type; + typedef __allocator<_Tp, _Pthread_alloc_template<_Max_size> > + allocator_type; +}; + +template +struct _Alloc_traits<_Tp, __allocator<_Up, _Pthread_alloc_template<_Max> > > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, _Pthread_alloc_template<_Max> > _Alloc_type; + typedef __allocator<_Tp, _Pthread_alloc_template<_Max> > allocator_type; +}; + +template +struct _Alloc_traits<_Tp, pthread_allocator<_Up> > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, _Pthread_alloc_template<> > _Alloc_type; + typedef pthread_allocator<_Tp> allocator_type; +}; + + +#endif /* __STL_USE_STD_ALLOCATORS */ + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_PTHREAD_ALLOC */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/pthread_alloc.h b/headers/cpp/pthread_alloc.h new file mode 100644 index 0000000000..774ef04edc --- /dev/null +++ b/headers/cpp/pthread_alloc.h @@ -0,0 +1,31 @@ +/* + * 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. + */ + +#ifndef __SGI_STL_PTHREAD_ALLOC_H +#define __SGI_STL_PTHREAD_ALLOC_H + +#include + +#ifdef __STL_USE_NAMESPACES + +using __STD::_Pthread_alloc_template; +using __STD::pthread_alloc; + +#endif /* __STL_USE_NAMESPACES */ + + +#endif /* __SGI_STL_PTHREAD_ALLOC_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/queue b/headers/cpp/queue new file mode 100644 index 0000000000..f9417fb1fb --- /dev/null +++ b/headers/cpp/queue @@ -0,0 +1,45 @@ +/* + * + * 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,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_QUEUE +#define __SGI_STL_QUEUE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif /* __SGI_STL_QUEUE */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/rope b/headers/cpp/rope new file mode 100644 index 0000000000..f861500000 --- /dev/null +++ b/headers/cpp/rope @@ -0,0 +1,32 @@ +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_ROPE +#define __SGI_STL_ROPE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif /* __SGI_STL_ROPE */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/rope.h b/headers/cpp/rope.h new file mode 100644 index 0000000000..d767fa32e7 --- /dev/null +++ b/headers/cpp/rope.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_ROPE_H +#define __SGI_STL_ROPE_H + +#include +#include + +#ifdef __STL_USE_NAMESPACES + +using __STD::char_producer; +using __STD::sequence_buffer; +using __STD::rope; +using __STD::crope; +using __STD::wrope; + +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_ROPE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/ropeimpl.h b/headers/cpp/ropeimpl.h new file mode 100644 index 0000000000..18bb2c9ec9 --- /dev/null +++ b/headers/cpp/ropeimpl.h @@ -0,0 +1,1550 @@ +/* + * 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. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +# include /* XXX should use */ +# include /* XXX should use */ + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1174 +#endif + +// Set buf_start, buf_end, and buf_ptr appropriately, filling tmp_buf +// if necessary. Assumes _M_path_end[leaf_index] and leaf_pos are correct. +// Results in a valid buf_ptr if the iterator can be legitimately +// dereferenced. +template +void _Rope_iterator_base<_CharT,_Alloc>::_S_setbuf( + _Rope_iterator_base<_CharT,_Alloc>& __x) +{ + const _RopeRep* __leaf = __x._M_path_end[__x._M_leaf_index]; + size_t __leaf_pos = __x._M_leaf_pos; + size_t __pos = __x._M_current_pos; + + switch(__leaf->_M_tag) { + case _RopeRep::_S_leaf: + __x._M_buf_start = + ((_Rope_RopeLeaf<_CharT,_Alloc>*)__leaf)->_M_data; + __x._M_buf_ptr = __x._M_buf_start + (__pos - __leaf_pos); + __x._M_buf_end = __x._M_buf_start + __leaf->_M_size; + break; + case _RopeRep::_S_function: + case _RopeRep::_S_substringfn: + { + size_t __len = _S_iterator_buf_len; + size_t __buf_start_pos = __leaf_pos; + size_t __leaf_end = __leaf_pos + __leaf->_M_size; + char_producer<_CharT>* __fn = + ((_Rope_RopeFunction<_CharT,_Alloc>*)__leaf)->_M_fn; + + if (__buf_start_pos + __len <= __pos) { + __buf_start_pos = __pos - __len/4; + if (__buf_start_pos + __len > __leaf_end) { + __buf_start_pos = __leaf_end - __len; + } + } + if (__buf_start_pos + __len > __leaf_end) { + __len = __leaf_end - __buf_start_pos; + } + (*__fn)(__buf_start_pos - __leaf_pos, __len, __x._M_tmp_buf); + __x._M_buf_ptr = __x._M_tmp_buf + (__pos - __buf_start_pos); + __x._M_buf_start = __x._M_tmp_buf; + __x._M_buf_end = __x._M_tmp_buf + __len; + } + break; + default: + __stl_assert(0); + } +} + +// Set path and buffer inside a rope iterator. We assume that +// pos and root are already set. +template +void _Rope_iterator_base<_CharT,_Alloc>::_S_setcache +(_Rope_iterator_base<_CharT,_Alloc>& __x) +{ + const _RopeRep* __path[_RopeRep::_S_max_rope_depth+1]; + const _RopeRep* __curr_rope; + int __curr_depth = -1; /* index into path */ + size_t __curr_start_pos = 0; + size_t __pos = __x._M_current_pos; + unsigned char __dirns = 0; // Bit vector marking right turns in the path + + __stl_assert(__pos <= __x._M_root->_M_size); + if (__pos >= __x._M_root->_M_size) { + __x._M_buf_ptr = 0; + return; + } + __curr_rope = __x._M_root; + if (0 != __curr_rope->_M_c_string) { + /* Treat the root as a leaf. */ + __x._M_buf_start = __curr_rope->_M_c_string; + __x._M_buf_end = __curr_rope->_M_c_string + __curr_rope->_M_size; + __x._M_buf_ptr = __curr_rope->_M_c_string + __pos; + __x._M_path_end[0] = __curr_rope; + __x._M_leaf_index = 0; + __x._M_leaf_pos = 0; + return; + } + for(;;) { + ++__curr_depth; + __stl_assert(__curr_depth <= _RopeRep::_S_max_rope_depth); + __path[__curr_depth] = __curr_rope; + switch(__curr_rope->_M_tag) { + case _RopeRep::_S_leaf: + case _RopeRep::_S_function: + case _RopeRep::_S_substringfn: + __x._M_leaf_pos = __curr_start_pos; + goto done; + case _RopeRep::_S_concat: + { + _Rope_RopeConcatenation<_CharT,_Alloc>* __c = + (_Rope_RopeConcatenation<_CharT,_Alloc>*)__curr_rope; + _RopeRep* __left = __c->_M_left; + size_t __left_len = __left->_M_size; + + __dirns <<= 1; + if (__pos >= __curr_start_pos + __left_len) { + __dirns |= 1; + __curr_rope = __c->_M_right; + __curr_start_pos += __left_len; + } else { + __curr_rope = __left; + } + } + break; + } + } + done: + // Copy last section of path into _M_path_end. + { + int __i = -1; + int __j = __curr_depth + 1 - _S_path_cache_len; + + if (__j < 0) __j = 0; + while (__j <= __curr_depth) { + __x._M_path_end[++__i] = __path[__j++]; + } + __x._M_leaf_index = __i; + } + __x._M_path_directions = __dirns; + _S_setbuf(__x); +} + +// Specialized version of the above. Assumes that +// the path cache is valid for the previous position. +template +void _Rope_iterator_base<_CharT,_Alloc>::_S_setcache_for_incr +(_Rope_iterator_base<_CharT,_Alloc>& __x) +{ + int __current_index = __x._M_leaf_index; + const _RopeRep* __current_node = __x._M_path_end[__current_index]; + size_t __len = __current_node->_M_size; + size_t __node_start_pos = __x._M_leaf_pos; + unsigned char __dirns = __x._M_path_directions; + _Rope_RopeConcatenation<_CharT,_Alloc>* __c; + + __stl_assert(__x._M_current_pos <= __x._M_root->_M_size); + if (__x._M_current_pos - __node_start_pos < __len) { + /* More stuff in this leaf, we just didn't cache it. */ + _S_setbuf(__x); + return; + } + __stl_assert(__node_start_pos + __len == __x._M_current_pos); + // node_start_pos is starting position of last_node. + while (--__current_index >= 0) { + if (!(__dirns & 1) /* Path turned left */) + break; + __current_node = __x._M_path_end[__current_index]; + __c = (_Rope_RopeConcatenation<_CharT,_Alloc>*)__current_node; + // Otherwise we were in the right child. Thus we should pop + // the concatenation node. + __node_start_pos -= __c->_M_left->_M_size; + __dirns >>= 1; + } + if (__current_index < 0) { + // We underflowed the cache. Punt. + _S_setcache(__x); + return; + } + __current_node = __x._M_path_end[__current_index]; + __c = (_Rope_RopeConcatenation<_CharT,_Alloc>*)__current_node; + // current_node is a concatenation node. We are positioned on the first + // character in its right child. + // node_start_pos is starting position of current_node. + __node_start_pos += __c->_M_left->_M_size; + __current_node = __c->_M_right; + __x._M_path_end[++__current_index] = __current_node; + __dirns |= 1; + while (_RopeRep::_S_concat == __current_node->_M_tag) { + ++__current_index; + if (_S_path_cache_len == __current_index) { + int __i; + for (__i = 0; __i < _S_path_cache_len-1; __i++) { + __x._M_path_end[__i] = __x._M_path_end[__i+1]; + } + --__current_index; + } + __current_node = + ((_Rope_RopeConcatenation<_CharT,_Alloc>*)__current_node)->_M_left; + __x._M_path_end[__current_index] = __current_node; + __dirns <<= 1; + // node_start_pos is unchanged. + } + __x._M_leaf_index = __current_index; + __x._M_leaf_pos = __node_start_pos; + __x._M_path_directions = __dirns; + _S_setbuf(__x); +} + +template +void _Rope_iterator_base<_CharT,_Alloc>::_M_incr(size_t __n) { + _M_current_pos += __n; + if (0 != _M_buf_ptr) { + size_t __chars_left = _M_buf_end - _M_buf_ptr; + if (__chars_left > __n) { + _M_buf_ptr += __n; + } else if (__chars_left == __n) { + _M_buf_ptr += __n; + _S_setcache_for_incr(*this); + } else { + _M_buf_ptr = 0; + } + } +} + +template +void _Rope_iterator_base<_CharT,_Alloc>::_M_decr(size_t __n) { + if (0 != _M_buf_ptr) { + size_t __chars_left = _M_buf_ptr - _M_buf_start; + if (__chars_left >= __n) { + _M_buf_ptr -= __n; + } else { + _M_buf_ptr = 0; + } + } + _M_current_pos -= __n; +} + +template +void _Rope_iterator<_CharT,_Alloc>::_M_check() { + if (_M_root_rope->_M_tree_ptr != _M_root) { + // _Rope was modified. Get things fixed up. + _RopeRep::_S_unref(_M_root); + _M_root = _M_root_rope->_M_tree_ptr; + _RopeRep::_S_ref(_M_root); + _M_buf_ptr = 0; + } +} + +template +inline +_Rope_const_iterator<_CharT, _Alloc>::_Rope_const_iterator( + const _Rope_iterator<_CharT,_Alloc>& __x) +: _Rope_iterator_base<_CharT,_Alloc>(__x) +{ } + +template +inline _Rope_iterator<_CharT,_Alloc>::_Rope_iterator( + rope<_CharT,_Alloc>& __r, size_t __pos) +: _Rope_iterator_base<_CharT,_Alloc>(__r._M_tree_ptr, __pos), + _M_root_rope(&__r) +{ + _RopeRep::_S_ref(_M_root); +} + +template +inline size_t +rope<_CharT,_Alloc>::_S_char_ptr_len(const _CharT* __s) +{ + const _CharT* __p = __s; + + while (!_S_is0(*__p)) { ++__p; } + return (__p - __s); +} + + +#ifndef __GC + +template +inline void _Rope_RopeRep<_CharT,_Alloc>::_M_free_c_string() +{ + _CharT* __cstr = _M_c_string; + if (0 != __cstr) { + size_t __size = _M_size + 1; + destroy(__cstr, __cstr + __size); + _Data_deallocate(__cstr, __size); + } +} + + +template +#ifdef __STL_USE_STD_ALLOCATORS + inline void _Rope_RopeRep<_CharT,_Alloc>::_S_free_string(_CharT* __s, + size_t __n, + allocator_type __a) +#else + inline void _Rope_RopeRep<_CharT,_Alloc>::_S_free_string(_CharT* __s, + size_t __n) +#endif +{ + if (!_S_is_basic_char_type((_CharT*)0)) { + destroy(__s, __s + __n); + } +// This has to be a static member, so this gets a bit messy +# ifdef __STL_USE_STD_ALLOCATORS + __a.deallocate( + __s, _Rope_RopeLeaf<_CharT,_Alloc>::_S_rounded_up_size(__n)); +# else + _Data_deallocate( + __s, _Rope_RopeLeaf<_CharT,_Alloc>::_S_rounded_up_size(__n)); +# endif +} + + +// There are several reasons for not doing this with virtual destructors +// and a class specific delete operator: +// - A class specific delete operator can't easily get access to +// allocator instances if we need them. +// - Any virtual function would need a 4 or byte vtable pointer; +// this only requires a one byte tag per object. +template +void _Rope_RopeRep<_CharT,_Alloc>::_M_free_tree() +{ + switch(_M_tag) { + case _S_leaf: + { + _Rope_RopeLeaf<_CharT,_Alloc>* __l + = (_Rope_RopeLeaf<_CharT,_Alloc>*)this; + __l->_Rope_RopeLeaf<_CharT,_Alloc>::~_Rope_RopeLeaf(); + _L_deallocate(__l, 1); + break; + } + case _S_concat: + { + _Rope_RopeConcatenation<_CharT,_Alloc>* __c + = (_Rope_RopeConcatenation<_CharT,_Alloc>*)this; + __c->_Rope_RopeConcatenation<_CharT,_Alloc>:: + ~_Rope_RopeConcatenation(); + _C_deallocate(__c, 1); + break; + } + case _S_function: + { + _Rope_RopeFunction<_CharT,_Alloc>* __f + = (_Rope_RopeFunction<_CharT,_Alloc>*)this; + __f->_Rope_RopeFunction<_CharT,_Alloc>::~_Rope_RopeFunction(); + _F_deallocate(__f, 1); + break; + } + case _S_substringfn: + { + _Rope_RopeSubstring<_CharT,_Alloc>* __ss = + (_Rope_RopeSubstring<_CharT,_Alloc>*)this; + __ss->_Rope_RopeSubstring<_CharT,_Alloc>:: + ~_Rope_RopeSubstring(); + _S_deallocate(__ss, 1); + break; + } + } +} +#else + +template +#ifdef __STL_USE_STD_ALLOCATORS + inline void _Rope_RopeRep<_CharT,_Alloc>::_S_free_string + (const _CharT*, size_t, allocator_type) +#else + inline void _Rope_RopeRep<_CharT,_Alloc>::_S_free_string + (const _CharT*, size_t) +#endif +{} + +#endif + + +// Concatenate a C string onto a leaf rope by copying the rope data. +// Used for short ropes. +template +rope<_CharT,_Alloc>::_RopeLeaf* +rope<_CharT,_Alloc>::_S_leaf_concat_char_iter + (_RopeLeaf* __r, const _CharT* __iter, size_t __len) +{ + size_t __old_len = __r->_M_size; + _CharT* __new_data = (_CharT*) + _Data_allocate(_S_rounded_up_size(__old_len + __len)); + _RopeLeaf* __result; + + uninitialized_copy_n(__r->_M_data, __old_len, __new_data); + uninitialized_copy_n(__iter, __len, __new_data + __old_len); + _S_cond_store_eos(__new_data[__old_len + __len]); + __STL_TRY { + __result = _S_new_RopeLeaf(__new_data, __old_len + __len, + __r->get_allocator()); + } + __STL_UNWIND(_RopeRep::__STL_FREE_STRING(__new_data, __old_len + __len, + __r->get_allocator())); + return __result; +} + +#ifndef __GC +// As above, but it's OK to clobber original if refcount is 1 +template +rope<_CharT,_Alloc>::_RopeLeaf* +rope<_CharT,_Alloc>::_S_destr_leaf_concat_char_iter + (_RopeLeaf* __r, const _CharT* __iter, size_t __len) +{ + __stl_assert(__r->_M_refcount >= 1); + if (__r->_M_refcount > 1) + return _S_leaf_concat_char_iter(__r, __iter, __len); + size_t __old_len = __r->_M_size; + if (_S_allocated_capacity(__old_len) >= __old_len + __len) { + // The space has been partially initialized for the standard + // character types. But that doesn't matter for those types. + uninitialized_copy_n(__iter, __len, __r->_M_data + __old_len); + if (_S_is_basic_char_type((_CharT*)0)) { + _S_cond_store_eos(__r->_M_data[__old_len + __len]); + __stl_assert(__r->_M_c_string == __r->_M_data); + } else if (__r->_M_c_string != __r->_M_data && 0 != __r->_M_c_string) { + __r->_M_free_c_string(); + __r->_M_c_string = 0; + } + __r->_M_size = __old_len + __len; + __stl_assert(__r->_M_refcount == 1); + __r->_M_refcount = 2; + return __r; + } else { + _RopeLeaf* __result = _S_leaf_concat_char_iter(__r, __iter, __len); + __stl_assert(__result->_M_refcount == 1); + return __result; + } +} +#endif + +// Assumes left and right are not 0. +// Does not increment (nor decrement on exception) child reference counts. +// Result has ref count 1. +template +rope<_CharT,_Alloc>::_RopeRep* +rope<_CharT,_Alloc>::_S_tree_concat (_RopeRep* __left, _RopeRep* __right) +{ + _RopeConcatenation* __result = + _S_new_RopeConcatenation(__left, __right, __left->get_allocator()); + size_t __depth = __result->_M_depth; + +# ifdef __STL_USE_STD_ALLOCATORS + __stl_assert(__left->get_allocator() == __right->get_allocator()); +# endif + if (__depth > 20 && (__result->_M_size < 1000 || + __depth > _RopeRep::_S_max_rope_depth)) { + _RopeRep* __balanced; + + __STL_TRY { + __balanced = _S_balance(__result); +# ifndef __GC + if (__result != __balanced) { + __stl_assert(1 == __result->_M_refcount + && 1 == __balanced->_M_refcount); + } +# endif + __result->_M_unref_nonnil(); + } + __STL_UNWIND((_C_deallocate(__result,1))); + // In case of exception, we need to deallocate + // otherwise dangling result node. But caller + // still owns its children. Thus unref is + // inappropriate. + return __balanced; + } else { + return __result; + } +} + +template +rope<_CharT,_Alloc>::_RopeRep* rope<_CharT,_Alloc>::_S_concat_char_iter + (_RopeRep* __r, const _CharT*__s, size_t __slen) +{ + _RopeRep* __result; + if (0 == __slen) { + _S_ref(__r); + return __r; + } + if (0 == __r) + return __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, + __r->get_allocator()); + if (_RopeRep::_S_leaf == __r->_M_tag && + __r->_M_size + __slen <= _S_copy_max) { + __result = _S_leaf_concat_char_iter((_RopeLeaf*)__r, __s, __slen); +# ifndef __GC + __stl_assert(1 == __result->_M_refcount); +# endif + return __result; + } + if (_RopeRep::_S_concat == __r->_M_tag + && _RopeRep::_S_leaf == ((_RopeConcatenation*)__r)->_M_right->_M_tag) { + _RopeLeaf* __right = + (_RopeLeaf* )(((_RopeConcatenation* )__r)->_M_right); + if (__right->_M_size + __slen <= _S_copy_max) { + _RopeRep* __left = ((_RopeConcatenation*)__r)->_M_left; + _RopeRep* __nright = + _S_leaf_concat_char_iter((_RopeLeaf*)__right, __s, __slen); + __left->_M_ref_nonnil(); + __STL_TRY { + __result = _S_tree_concat(__left, __nright); + } + __STL_UNWIND(_S_unref(__left); _S_unref(__nright)); +# ifndef __GC + __stl_assert(1 == __result->_M_refcount); +# endif + return __result; + } + } + _RopeRep* __nright = + __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __r->get_allocator()); + __STL_TRY { + __r->_M_ref_nonnil(); + __result = _S_tree_concat(__r, __nright); + } + __STL_UNWIND(_S_unref(__r); _S_unref(__nright)); +# ifndef __GC + __stl_assert(1 == __result->_M_refcount); +# endif + return __result; +} + +#ifndef __GC +template +rope<_CharT,_Alloc>::_RopeRep* +rope<_CharT,_Alloc>::_S_destr_concat_char_iter( + _RopeRep* __r, const _CharT* __s, size_t __slen) +{ + _RopeRep* __result; + if (0 == __r) + return __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, + __r->get_allocator()); + size_t __count = __r->_M_refcount; + size_t __orig_size = __r->_M_size; + __stl_assert(__count >= 1); + if (__count > 1) return _S_concat_char_iter(__r, __s, __slen); + if (0 == __slen) { + __r->_M_refcount = 2; // One more than before + return __r; + } + if (__orig_size + __slen <= _S_copy_max && + _RopeRep::_S_leaf == __r->_M_tag) { + __result = _S_destr_leaf_concat_char_iter((_RopeLeaf*)__r, __s, __slen); + return __result; + } + if (_RopeRep::_S_concat == __r->_M_tag) { + _RopeLeaf* __right = (_RopeLeaf*)(((_RopeConcatenation*)__r)->_M_right); + if (_RopeRep::_S_leaf == __right->_M_tag + && __right->_M_size + __slen <= _S_copy_max) { + _RopeRep* __new_right = + _S_destr_leaf_concat_char_iter(__right, __s, __slen); + if (__right == __new_right) { + __stl_assert(__new_right->_M_refcount == 2); + __new_right->_M_refcount = 1; + } else { + __stl_assert(__new_right->_M_refcount >= 1); + __right->_M_unref_nonnil(); + } + __stl_assert(__r->_M_refcount == 1); + __r->_M_refcount = 2; // One more than before. + ((_RopeConcatenation*)__r)->_M_right = __new_right; + __r->_M_size = __orig_size + __slen; + if (0 != __r->_M_c_string) { + __r->_M_free_c_string(); + __r->_M_c_string = 0; + } + return __r; + } + } + _RopeRep* __right = + __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __r->get_allocator()); + __r->_M_ref_nonnil(); + __STL_TRY { + __result = _S_tree_concat(__r, __right); + } + __STL_UNWIND(_S_unref(__r); _S_unref(__right)) + __stl_assert(1 == __result->_M_refcount); + return __result; +} +#endif /* !__GC */ + +template +rope<_CharT,_Alloc>::_RopeRep* +rope<_CharT,_Alloc>::_S_concat(_RopeRep* __left, _RopeRep* __right) +{ + if (0 == __left) { + _S_ref(__right); + return __right; + } + if (0 == __right) { + __left->_M_ref_nonnil(); + return __left; + } + if (_RopeRep::_S_leaf == __right->_M_tag) { + if (_RopeRep::_S_leaf == __left->_M_tag) { + if (__right->_M_size + __left->_M_size <= _S_copy_max) { + return _S_leaf_concat_char_iter((_RopeLeaf*)__left, + ((_RopeLeaf*)__right)->_M_data, + __right->_M_size); + } + } else if (_RopeRep::_S_concat == __left->_M_tag + && _RopeRep::_S_leaf == + ((_RopeConcatenation*)__left)->_M_right->_M_tag) { + _RopeLeaf* __leftright = + (_RopeLeaf*)(((_RopeConcatenation*)__left)->_M_right); + if (__leftright->_M_size + __right->_M_size <= _S_copy_max) { + _RopeRep* __leftleft = ((_RopeConcatenation*)__left)->_M_left; + _RopeRep* __rest = _S_leaf_concat_char_iter(__leftright, + ((_RopeLeaf*)__right)->_M_data, + __right->_M_size); + __leftleft->_M_ref_nonnil(); + __STL_TRY { + return(_S_tree_concat(__leftleft, __rest)); + } + __STL_UNWIND(_S_unref(__leftleft); _S_unref(__rest)) + } + } + } + __left->_M_ref_nonnil(); + __right->_M_ref_nonnil(); + __STL_TRY { + return(_S_tree_concat(__left, __right)); + } + __STL_UNWIND(_S_unref(__left); _S_unref(__right)); +} + +template +rope<_CharT,_Alloc>::_RopeRep* +rope<_CharT,_Alloc>::_S_substring(_RopeRep* __base, + size_t __start, size_t __endp1) +{ + if (0 == __base) return 0; + size_t __len = __base->_M_size; + size_t __adj_endp1; + const size_t __lazy_threshold = 128; + + if (__endp1 >= __len) { + if (0 == __start) { + __base->_M_ref_nonnil(); + return __base; + } else { + __adj_endp1 = __len; + } + } else { + __adj_endp1 = __endp1; + } + switch(__base->_M_tag) { + case _RopeRep::_S_concat: + { + _RopeConcatenation* __c = (_RopeConcatenation*)__base; + _RopeRep* __left = __c->_M_left; + _RopeRep* __right = __c->_M_right; + size_t __left_len = __left->_M_size; + _RopeRep* __result; + + if (__adj_endp1 <= __left_len) { + return _S_substring(__left, __start, __endp1); + } else if (__start >= __left_len) { + return _S_substring(__right, __start - __left_len, + __adj_endp1 - __left_len); + } + _Self_destruct_ptr __left_result( + _S_substring(__left, __start, __left_len)); + _Self_destruct_ptr __right_result( + _S_substring(__right, 0, __endp1 - __left_len)); + __result = _S_concat(__left_result, __right_result); +# ifndef __GC + __stl_assert(1 == __result->_M_refcount); +# endif + return __result; + } + case _RopeRep::_S_leaf: + { + _RopeLeaf* __l = (_RopeLeaf*)__base; + _RopeLeaf* __result; + size_t __result_len; + if (__start >= __adj_endp1) return 0; + __result_len = __adj_endp1 - __start; + if (__result_len > __lazy_threshold) goto lazy; +# ifdef __GC + const _CharT* __section = __l->_M_data + __start; + __result = _S_new_RopeLeaf(__section, __result_len, + __base->get_allocator()); + __result->_M_c_string = 0; // Not eos terminated. +# else + // We should sometimes create substring node instead. + __result = __STL_ROPE_FROM_UNOWNED_CHAR_PTR( + __l->_M_data + __start, __result_len, + __base->get_allocator()); +# endif + return __result; + } + case _RopeRep::_S_substringfn: + // Avoid introducing multiple layers of substring nodes. + { + _RopeSubstring* __old = (_RopeSubstring*)__base; + size_t __result_len; + if (__start >= __adj_endp1) return 0; + __result_len = __adj_endp1 - __start; + if (__result_len > __lazy_threshold) { + _RopeSubstring* __result = + _S_new_RopeSubstring(__old->_M_base, + __start + __old->_M_start, + __adj_endp1 - __start, + __base->get_allocator()); + return __result; + + } // *** else fall through: *** + } + case _RopeRep::_S_function: + { + _RopeFunction* __f = (_RopeFunction*)__base; + _CharT* __section; + size_t __result_len; + if (__start >= __adj_endp1) return 0; + __result_len = __adj_endp1 - __start; + + if (__result_len > __lazy_threshold) goto lazy; + __section = (_CharT*) + _Data_allocate(_S_rounded_up_size(__result_len)); + __STL_TRY { + (*(__f->_M_fn))(__start, __result_len, __section); + } + __STL_UNWIND(_RopeRep::__STL_FREE_STRING( + __section, __result_len, __base->get_allocator())); + _S_cond_store_eos(__section[__result_len]); + return _S_new_RopeLeaf(__section, __result_len, + __base->get_allocator()); + } + } + /*NOTREACHED*/ + __stl_assert(false); + lazy: + { + // Create substring node. + return _S_new_RopeSubstring(__base, __start, __adj_endp1 - __start, + __base->get_allocator()); + } +} + +template +class _Rope_flatten_char_consumer : public _Rope_char_consumer<_CharT> { + private: + _CharT* _M_buf_ptr; + public: + // _CharT* _M_buffer; // XXX not used + + _Rope_flatten_char_consumer(_CharT* __buffer) { + _M_buf_ptr = __buffer; + }; + ~_Rope_flatten_char_consumer() {} + bool operator() (const _CharT* __leaf, size_t __n) { + uninitialized_copy_n(__leaf, __n, _M_buf_ptr); + _M_buf_ptr += __n; + return true; + } +}; + +template +class _Rope_find_char_char_consumer : public _Rope_char_consumer<_CharT> { + private: + _CharT _M_pattern; + public: + size_t _M_count; // Number of nonmatching characters + _Rope_find_char_char_consumer(_CharT __p) + : _M_pattern(__p), _M_count(0) {} + ~_Rope_find_char_char_consumer() {} + bool operator() (const _CharT* __leaf, size_t __n) { + size_t __i; + for (__i = 0; __i < __n; __i++) { + if (__leaf[__i] == _M_pattern) { + _M_count += __i; return false; + } + } + _M_count += __n; return true; + } +}; + +template +class _Rope_insert_char_consumer : public _Rope_char_consumer<_CharT> { + private: + typedef ostream _Insert_ostream; + _Insert_ostream& _M_o; + public: + // _CharT* buffer; // XXX not used + _Rope_insert_char_consumer(_Insert_ostream& __writer) + : _M_o(__writer) {}; + ~_Rope_insert_char_consumer() { }; + // Caller is presumed to own the ostream + bool operator() (const _CharT* __leaf, size_t __n); + // Returns true to continue traversal. +}; + +template +bool _Rope_insert_char_consumer<_CharT>::operator() + (const _CharT* __leaf, size_t __n) +{ + size_t __i; + // We assume that formatting is set up correctly for each element. + for (__i = 0; __i < __n; __i++) _M_o << __leaf[__i]; + return true; +} + +inline bool _Rope_insert_char_consumer::operator() + (const char* __leaf, size_t __n) +{ + size_t __i; + for (__i = 0; __i < __n; __i++) _M_o.put(__leaf[__i]); + return true; +} + +#if 0 +// I couldn't get this to work work with the VC++ version of basic_ostream. +// It also doesn't really do the right thing unless o is a wide stream. +// Given that wchar_t is often 4 bytes, its not clear to me how useful +// this stuff is anyway. +inline bool _Rope_insert_char_consumer::operator() + (const wchar_t* __leaf, size_t __n) +{ + size_t __i; + for (__i = 0; __i < __n; __i++) _M_o.put(__leaf[__i]); + return true; +} +#endif /* !_MSC_VER && !BORLAND */ + +template +bool rope<_CharT, _Alloc>::_S_apply_to_pieces( + _Rope_char_consumer<_CharT>& __c, + const _RopeRep* __r, + size_t __begin, size_t __end) +{ + if (0 == __r) return true; + switch(__r->_M_tag) { + case _RopeRep::_S_concat: + { + _RopeConcatenation* __conc = (_RopeConcatenation*)__r; + _RopeRep* __left = __conc->_M_left; + size_t __left_len = __left->_M_size; + if (__begin < __left_len) { + size_t __left_end = min(__left_len, __end); + if (!_S_apply_to_pieces(__c, __left, __begin, __left_end)) + return false; + } + if (__end > __left_len) { + _RopeRep* __right = __conc->_M_right; + size_t __right_start = max(__left_len, __begin); + if (!_S_apply_to_pieces(__c, __right, + __right_start - __left_len, + __end - __left_len)) { + return false; + } + } + } + return true; + case _RopeRep::_S_leaf: + { + _RopeLeaf* __l = (_RopeLeaf*)__r; + return __c(__l->_M_data + __begin, __end - __begin); + } + case _RopeRep::_S_function: + case _RopeRep::_S_substringfn: + { + _RopeFunction* __f = (_RopeFunction*)__r; + size_t __len = __end - __begin; + bool __result; + _CharT* __buffer = + (_CharT*)alloc::allocate(__len * sizeof(_CharT)); + __STL_TRY { + (*(__f->_M_fn))(__begin, __end, __buffer); + __result = __c(__buffer, __len); + alloc::deallocate(__buffer, __len * sizeof(_CharT)); + } + __STL_UNWIND((alloc::deallocate(__buffer, + __len * sizeof(_CharT)))) + return __result; + } + default: + __stl_assert(false); + /*NOTREACHED*/ + return false; + } +} + +inline void _Rope_fill(ostream& __o, size_t __n) +{ + char __f = __o.fill(); + size_t __i; + + for (__i = 0; __i < __n; __i++) __o.put(__f); +} + + +template inline bool _Rope_is_simple(_CharT*) { return false; } +inline bool _Rope_is_simple(char*) { return true; } +inline bool _Rope_is_simple(wchar_t*) { return true; } + + +template +ostream& operator<< (ostream& __o, const rope<_CharT, _Alloc>& __r) +{ + size_t __w = __o.width(); + bool __left = bool(__o.flags() & ios::left); + size_t __pad_len; + size_t __rope_len = __r.size(); + _Rope_insert_char_consumer<_CharT> __c(__o); + bool __is_simple = _Rope_is_simple((_CharT*)0); + + if (__rope_len < __w) { + __pad_len = __w - __rope_len; + } else { + __pad_len = 0; + } + if (!__is_simple) __o.width(__w/__rope_len); + __STL_TRY { + if (__is_simple && !__left && __pad_len > 0) { + _Rope_fill(__o, __pad_len); + } + __r.apply_to_pieces(0, __r.size(), __c); + if (__is_simple && __left && __pad_len > 0) { + _Rope_fill(__o, __pad_len); + } + if (!__is_simple) + __o.width(__w); + } + __STL_UNWIND(if (!__is_simple) __o.width(__w)) + return __o; +} + +template +_CharT* +rope<_CharT,_Alloc>::_S_flatten(_RopeRep* __r, + size_t __start, size_t __len, + _CharT* __buffer) +{ + _Rope_flatten_char_consumer<_CharT> __c(__buffer); + _S_apply_to_pieces(__c, __r, __start, __start + __len); + return(__buffer + __len); +} + +template +size_t +rope<_CharT,_Alloc>::find(_CharT __pattern, size_t __start) const +{ + _Rope_find_char_char_consumer<_CharT> __c(__pattern); + _S_apply_to_pieces(__c, _M_tree_ptr, __start, size()); + size_type __result_pos = __start + __c._M_count; +# ifndef __STL_OLD_ROPE_SEMANTICS + if (__result_pos == size()) __result_pos = npos; +# endif + return __result_pos; +} + +template +_CharT* +rope<_CharT,_Alloc>::_S_flatten(_RopeRep* __r, _CharT* __buffer) +{ + if (0 == __r) return __buffer; + switch(__r->_M_tag) { + case _RopeRep::_S_concat: + { + _RopeConcatenation* __c = (_RopeConcatenation*)__r; + _RopeRep* __left = __c->_M_left; + _RopeRep* __right = __c->_M_right; + _CharT* __rest = _S_flatten(__left, __buffer); + return _S_flatten(__right, __rest); + } + case _RopeRep::_S_leaf: + { + _RopeLeaf* __l = (_RopeLeaf*)__r; + return copy_n(__l->_M_data, __l->_M_size, __buffer).second; + } + case _RopeRep::_S_function: + case _RopeRep::_S_substringfn: + // We dont yet do anything with substring nodes. + // This needs to be fixed before ropefiles will work well. + { + _RopeFunction* __f = (_RopeFunction*)__r; + (*(__f->_M_fn))(0, __f->_M_size, __buffer); + return __buffer + __f->_M_size; + } + default: + __stl_assert(false); + /*NOTREACHED*/ + return 0; + } +} + + +// This needs work for _CharT != char +template +void +rope<_CharT,_Alloc>::_S_dump(_RopeRep* __r, int __indent) +{ + for (int __i = 0; __i < __indent; __i++) putchar(' '); + if (0 == __r) { + printf("NULL\n"); return; + } + if (_RopeRep::_S_concat == __r->_M_tag) { + _RopeConcatenation* __c = (_RopeConcatenation*)__r; + _RopeRep* __left = __c->_M_left; + _RopeRep* __right = __c->_M_right; + +# ifdef __GC + printf("Concatenation %p (depth = %d, len = %ld, %s balanced)\n", + __r, __r->_M_depth, __r->_M_size, __r->_M_is_balanced? "" : "not"); +# else + printf("Concatenation %p (rc = %ld, depth = %d, " + "len = %ld, %s balanced)\n", + __r, __r->_M_refcount, __r->_M_depth, __r->_M_size, + __r->_M_is_balanced? "" : "not"); +# endif + _S_dump(__left, __indent + 2); + _S_dump(__right, __indent + 2); + return; + } else { + char* __kind; + + switch (__r->_M_tag) { + case _RopeRep::_S_leaf: + __kind = "Leaf"; + break; + case _RopeRep::_S_function: + __kind = "Function"; + break; + case _RopeRep::_S_substringfn: + __kind = "Function representing substring"; + break; + default: + __kind = "(corrupted kind field!)"; + } +# ifdef __GC + printf("%s %p (depth = %d, len = %ld) ", + __kind, __r, __r->_M_depth, __r->_M_size); +# else + printf("%s %p (rc = %ld, depth = %d, len = %ld) ", + __kind, __r, __r->_M_refcount, __r->_M_depth, __r->_M_size); +# endif + if (_S_is_one_byte_char_type((_CharT*)0)) { + const int __max_len = 40; + _Self_destruct_ptr __prefix(_S_substring(__r, 0, __max_len)); + _CharT __buffer[__max_len + 1]; + bool __too_big = __r->_M_size > __prefix->_M_size; + + _S_flatten(__prefix, __buffer); + __buffer[__prefix->_M_size] = _S_eos((_CharT*)0); + printf("%s%s\n", + (char*)__buffer, __too_big? "...\n" : "\n"); + } else { + printf("\n"); + } + } +} + +template +const unsigned long +rope<_CharT,_Alloc>::_S_min_len[ + _Rope_RopeRep<_CharT,_Alloc>::_S_max_rope_depth + 1] = { +/* 0 */1, /* 1 */2, /* 2 */3, /* 3 */5, /* 4 */8, /* 5 */13, /* 6 */21, +/* 7 */34, /* 8 */55, /* 9 */89, /* 10 */144, /* 11 */233, /* 12 */377, +/* 13 */610, /* 14 */987, /* 15 */1597, /* 16 */2584, /* 17 */4181, +/* 18 */6765, /* 19 */10946, /* 20 */17711, /* 21 */28657, /* 22 */46368, +/* 23 */75025, /* 24 */121393, /* 25 */196418, /* 26 */317811, +/* 27 */514229, /* 28 */832040, /* 29 */1346269, /* 30 */2178309, +/* 31 */3524578, /* 32 */5702887, /* 33 */9227465, /* 34 */14930352, +/* 35 */24157817, /* 36 */39088169, /* 37 */63245986, /* 38 */102334155, +/* 39 */165580141, /* 40 */267914296, /* 41 */433494437, +/* 42 */701408733, /* 43 */1134903170, /* 44 */1836311903, +/* 45 */2971215073u }; +// These are Fibonacci numbers < 2**32. + +template +rope<_CharT,_Alloc>::_RopeRep* +rope<_CharT,_Alloc>::_S_balance(_RopeRep* __r) +{ + _RopeRep* __forest[_RopeRep::_S_max_rope_depth + 1]; + _RopeRep* __result = 0; + int __i; + // Invariant: + // The concatenation of forest in descending order is equal to __r. + // __forest[__i]._M_size >= _S_min_len[__i] + // __forest[__i]._M_depth = __i + // References from forest are included in refcount. + + for (__i = 0; __i <= _RopeRep::_S_max_rope_depth; ++__i) + __forest[__i] = 0; + __STL_TRY { + _S_add_to_forest(__r, __forest); + for (__i = 0; __i <= _RopeRep::_S_max_rope_depth; ++__i) + if (0 != __forest[__i]) { +# ifndef __GC + _Self_destruct_ptr __old(__result); +# endif + __result = _S_concat(__forest[__i], __result); + __forest[__i]->_M_unref_nonnil(); +# if !defined(__GC) && defined(__STL_USE_EXCEPTIONS) + __forest[__i] = 0; +# endif + } + } + __STL_UNWIND(for(__i = 0; __i <= _RopeRep::_S_max_rope_depth; __i++) + _S_unref(__forest[__i])) + if (__result->_M_depth > _RopeRep::_S_max_rope_depth) abort(); + return(__result); +} + + +template +void +rope<_CharT,_Alloc>::_S_add_to_forest(_RopeRep* __r, _RopeRep** __forest) +{ + if (__r->_M_is_balanced) { + _S_add_leaf_to_forest(__r, __forest); + return; + } + __stl_assert(__r->_M_tag == _RopeRep::_S_concat); + { + _RopeConcatenation* __c = (_RopeConcatenation*)__r; + + _S_add_to_forest(__c->_M_left, __forest); + _S_add_to_forest(__c->_M_right, __forest); + } +} + + +template +void +rope<_CharT,_Alloc>::_S_add_leaf_to_forest(_RopeRep* __r, _RopeRep** __forest) +{ + _RopeRep* __insertee; // included in refcount + _RopeRep* __too_tiny = 0; // included in refcount + int __i; // forest[0..__i-1] is empty + size_t __s = __r->_M_size; + + for (__i = 0; __s >= _S_min_len[__i+1]/* not this bucket */; ++__i) { + if (0 != __forest[__i]) { +# ifndef __GC + _Self_destruct_ptr __old(__too_tiny); +# endif + __too_tiny = _S_concat_and_set_balanced(__forest[__i], __too_tiny); + __forest[__i]->_M_unref_nonnil(); + __forest[__i] = 0; + } + } + { +# ifndef __GC + _Self_destruct_ptr __old(__too_tiny); +# endif + __insertee = _S_concat_and_set_balanced(__too_tiny, __r); + } + // Too_tiny dead, and no longer included in refcount. + // Insertee is live and included. + __stl_assert(_S_is_almost_balanced(__insertee)); + __stl_assert(__insertee->_M_depth <= __r->_M_depth + 1); + for (;; ++__i) { + if (0 != __forest[__i]) { +# ifndef __GC + _Self_destruct_ptr __old(__insertee); +# endif + __insertee = _S_concat_and_set_balanced(__forest[__i], __insertee); + __forest[__i]->_M_unref_nonnil(); + __forest[__i] = 0; + __stl_assert(_S_is_almost_balanced(__insertee)); + } + __stl_assert(_S_min_len[__i] <= __insertee->_M_size); + __stl_assert(__forest[__i] == 0); + if (__i == _RopeRep::_S_max_rope_depth || + __insertee->_M_size < _S_min_len[__i+1]) { + __forest[__i] = __insertee; + // refcount is OK since __insertee is now dead. + return; + } + } +} + +template +_CharT +rope<_CharT,_Alloc>::_S_fetch(_RopeRep* __r, size_type __i) +{ + __GC_CONST _CharT* __cstr = __r->_M_c_string; + + __stl_assert(__i < __r->_M_size); + if (0 != __cstr) return __cstr[__i]; + for(;;) { + switch(__r->_M_tag) { + case _RopeRep::_S_concat: + { + _RopeConcatenation* __c = (_RopeConcatenation*)__r; + _RopeRep* __left = __c->_M_left; + size_t __left_len = __left->_M_size; + + if (__i >= __left_len) { + __i -= __left_len; + __r = __c->_M_right; + } else { + __r = __left; + } + } + break; + case _RopeRep::_S_leaf: + { + _RopeLeaf* __l = (_RopeLeaf*)__r; + return __l->_M_data[__i]; + } + case _RopeRep::_S_function: + case _RopeRep::_S_substringfn: + { + _RopeFunction* __f = (_RopeFunction*)__r; + _CharT __result; + + (*(__f->_M_fn))(__i, 1, &__result); + return __result; + } + } + } +} + +# ifndef __GC +// Return a uniquely referenced character slot for the given +// position, or 0 if that's not possible. +template +_CharT* +rope<_CharT,_Alloc>::_S_fetch_ptr(_RopeRep* __r, size_type __i) +{ + _RopeRep* __clrstack[_RopeRep::_S_max_rope_depth]; + size_t __csptr = 0; + + for(;;) { + if (__r->_M_refcount > 1) return 0; + switch(__r->_M_tag) { + case _RopeRep::_S_concat: + { + _RopeConcatenation* __c = (_RopeConcatenation*)__r; + _RopeRep* __left = __c->_M_left; + size_t __left_len = __left->_M_size; + + if (__c->_M_c_string != 0) __clrstack[__csptr++] = __c; + if (__i >= __left_len) { + __i -= __left_len; + __r = __c->_M_right; + } else { + __r = __left; + } + } + break; + case _RopeRep::_S_leaf: + { + _RopeLeaf* __l = (_RopeLeaf*)__r; + if (__l->_M_c_string != __l->_M_data && __l->_M_c_string != 0) + __clrstack[__csptr++] = __l; + while (__csptr > 0) { + -- __csptr; + _RopeRep* __d = __clrstack[__csptr]; + __d->_M_free_c_string(); + __d->_M_c_string = 0; + } + return __l->_M_data + __i; + } + case _RopeRep::_S_function: + case _RopeRep::_S_substringfn: + return 0; + } + } +} +# endif /* __GC */ + +// The following could be implemented trivially using +// lexicographical_compare_3way. +// We do a little more work to avoid dealing with rope iterators for +// flat strings. +template +int +rope<_CharT,_Alloc>::_S_compare (const _RopeRep* __left, + const _RopeRep* __right) +{ + size_t __left_len; + size_t __right_len; + + if (0 == __right) return 0 != __left; + if (0 == __left) return -1; + __left_len = __left->_M_size; + __right_len = __right->_M_size; + if (_RopeRep::_S_leaf == __left->_M_tag) { + _RopeLeaf* __l = (_RopeLeaf*) __left; + if (_RopeRep::_S_leaf == __right->_M_tag) { + _RopeLeaf* __r = (_RopeLeaf*) __right; + return lexicographical_compare_3way( + __l->_M_data, __l->_M_data + __left_len, + __r->_M_data, __r->_M_data + __right_len); + } else { + const_iterator __rstart(__right, 0); + const_iterator __rend(__right, __right_len); + return lexicographical_compare_3way( + __l->_M_data, __l->_M_data + __left_len, + __rstart, __rend); + } + } else { + const_iterator __lstart(__left, 0); + const_iterator __lend(__left, __left_len); + if (_RopeRep::_S_leaf == __right->_M_tag) { + _RopeLeaf* __r = (_RopeLeaf*) __right; + return lexicographical_compare_3way( + __lstart, __lend, + __r->_M_data, __r->_M_data + __right_len); + } else { + const_iterator __rstart(__right, 0); + const_iterator __rend(__right, __right_len); + return lexicographical_compare_3way( + __lstart, __lend, + __rstart, __rend); + } + } +} + +// Assignment to reference proxies. +template +_Rope_char_ref_proxy<_CharT, _Alloc>& +_Rope_char_ref_proxy<_CharT, _Alloc>::operator= (_CharT __c) { + _RopeRep* __old = _M_root->_M_tree_ptr; +# ifndef __GC + // First check for the case in which everything is uniquely + // referenced. In that case we can do this destructively. + _CharT* __ptr = _My_rope::_S_fetch_ptr(__old, _M_pos); + if (0 != __ptr) { + *__ptr = __c; + return *this; + } +# endif + _Self_destruct_ptr __left( + _My_rope::_S_substring(__old, 0, _M_pos)); + _Self_destruct_ptr __right( + _My_rope::_S_substring(__old, _M_pos+1, __old->_M_size)); + _Self_destruct_ptr __result_left( + _My_rope::_S_destr_concat_char_iter(__left, &__c, 1)); + +# ifndef __GC + __stl_assert(__left == __result_left || 1 == __result_left->_M_refcount); +# endif + _RopeRep* __result = + _My_rope::_S_concat(__result_left, __right); +# ifndef __GC + __stl_assert(1 <= __result->_M_refcount); + _RopeRep::_S_unref(__old); +# endif + _M_root->_M_tree_ptr = __result; + return *this; +} + +template +inline _Rope_char_ref_proxy<_CharT, _Alloc>::operator _CharT () const +{ + if (_M_current_valid) { + return _M_current; + } else { + return _My_rope::_S_fetch(_M_root->_M_tree_ptr, _M_pos); + } +} +template +_Rope_char_ptr_proxy<_CharT, _Alloc> +_Rope_char_ref_proxy<_CharT, _Alloc>::operator& () const { + return _Rope_char_ptr_proxy<_CharT, _Alloc>(*this); +} + +template +rope<_CharT, _Alloc>::rope(size_t __n, _CharT __c, + const allocator_type& __a) +: _Base(__a) +{ + rope<_CharT,_Alloc> __result; + const size_t __exponentiate_threshold = 32; + size_t __exponent; + size_t __rest; + _CharT* __rest_buffer; + _RopeRep* __remainder; + rope<_CharT,_Alloc> __remainder_rope; + + if (0 == __n) + return; + + __exponent = __n / __exponentiate_threshold; + __rest = __n % __exponentiate_threshold; + if (0 == __rest) { + __remainder = 0; + } else { + __rest_buffer = _Data_allocate(_S_rounded_up_size(__rest)); + uninitialized_fill_n(__rest_buffer, __rest, __c); + _S_cond_store_eos(__rest_buffer[__rest]); + __STL_TRY { + __remainder = _S_new_RopeLeaf(__rest_buffer, __rest, __a); + } + __STL_UNWIND(_RopeRep::__STL_FREE_STRING(__rest_buffer, __rest, __a)) + } + __remainder_rope._M_tree_ptr = __remainder; + if (__exponent != 0) { + _CharT* __base_buffer = + _Data_allocate(_S_rounded_up_size(__exponentiate_threshold)); + _RopeLeaf* __base_leaf; + rope __base_rope; + uninitialized_fill_n(__base_buffer, __exponentiate_threshold, __c); + _S_cond_store_eos(__base_buffer[__exponentiate_threshold]); + __STL_TRY { + __base_leaf = _S_new_RopeLeaf(__base_buffer, + __exponentiate_threshold, __a); + } + __STL_UNWIND(_RopeRep::__STL_FREE_STRING(__base_buffer, + __exponentiate_threshold, __a)) + __base_rope._M_tree_ptr = __base_leaf; + if (1 == __exponent) { + __result = __base_rope; +# ifndef __GC + __stl_assert(2 == __result._M_tree_ptr->_M_refcount); + // One each for base_rope and __result +# endif + } else { + // XXX what is power()? + __result = power(__base_rope, __exponent, _Concat_fn()); + } + if (0 != __remainder) { + __result += __remainder_rope; + } + } else { + __result = __remainder_rope; + } + _M_tree_ptr = __result._M_tree_ptr; + _M_tree_ptr->_M_ref_nonnil(); +} + +template + _CharT rope<_CharT,_Alloc>::_S_empty_c_str[1]; + +# ifdef __STL_PTHREADS + template + pthread_mutex_t + rope<_CharT,_Alloc>::_S_swap_lock = PTHREAD_MUTEX_INITIALIZER; +# endif + +template +const _CharT* rope<_CharT,_Alloc>::c_str() const { + if (0 == _M_tree_ptr) { + _S_empty_c_str[0] = _S_eos((_CharT*)0); // Possibly redundant, + // but probably fast. + return _S_empty_c_str; + } + __GC_CONST _CharT* __old_c_string = _M_tree_ptr->_M_c_string; + if (0 != __old_c_string) return(__old_c_string); + size_t __s = size(); + _CharT* __result = _Data_allocate(__s + 1); + _S_flatten(_M_tree_ptr, __result); + __result[__s] = _S_eos((_CharT*)0); +# ifdef __GC + _M_tree_ptr->_M_c_string = __result; +# else + if ((__old_c_string = + _S_atomic_swap(&(_M_tree_ptr->_M_c_string), __result)) != 0) { + // It must have been added in the interim. Hence it had to have been + // separately allocated. Deallocate the old copy, since we just + // replaced it. + destroy(__old_c_string, __old_c_string + __s + 1); + _Data_deallocate(__old_c_string, __s + 1); + } +# endif + return(__result); +} + +template +const _CharT* rope<_CharT,_Alloc>::replace_with_c_str() { + if (0 == _M_tree_ptr) { + _S_empty_c_str[0] = _S_eos((_CharT*)0); + return _S_empty_c_str; + } + __GC_CONST _CharT* __old_c_string = _M_tree_ptr->_M_c_string; + if (_RopeRep::_S_leaf == _M_tree_ptr->_M_tag && 0 != __old_c_string) { + return(__old_c_string); + } + size_t __s = size(); + _CharT* __result = _Data_allocate(_S_rounded_up_size(__s)); + _S_flatten(_M_tree_ptr, __result); + __result[__s] = _S_eos((_CharT*)0); + _M_tree_ptr->_M_unref_nonnil(); + _M_tree_ptr = _S_new_RopeLeaf(__result, __s, get_allocator()); + return(__result); +} + +// Algorithm specializations. More should be added. + +#ifndef _MSC_VER +// I couldn't get this to work with VC++ +template +void +_Rope_rotate(_Rope_iterator<_CharT,_Alloc> __first, + _Rope_iterator<_CharT,_Alloc> __middle, + _Rope_iterator<_CharT,_Alloc> __last) +{ + __stl_assert(__first.container() == __middle.container() + && __middle.container() == __last.container()); + rope<_CharT,_Alloc>& __r(__first.container()); + rope<_CharT,_Alloc> __prefix = __r.substr(0, __first.index()); + rope<_CharT,_Alloc> __suffix = + __r.substr(__last.index(), __r.size() - __last.index()); + rope<_CharT,_Alloc> __part1 = + __r.substr(__middle.index(), __last.index() - __middle.index()); + rope<_CharT,_Alloc> __part2 = + __r.substr(__first.index(), __middle.index() - __first.index()); + __r = __prefix; + __r += __part1; + __r += __part2; + __r += __suffix; +} + +#if !defined(__GNUC__) +// Appears to confuse g++ +inline void rotate(_Rope_iterator __first, + _Rope_iterator __middle, + _Rope_iterator __last) { + _Rope_rotate(__first, __middle, __last); +} +#endif + +# if 0 +// Probably not useful for several reasons: +// - for SGIs 7.1 compiler and probably some others, +// this forces lots of rope instantiations, creating a +// code bloat and compile time problem. (Fixed in 7.2.) +// - wchar_t is 4 bytes wide on most UNIX platforms, making it unattractive +// for unicode strings. Unsigned short may be a better character +// type. +inline void rotate( + _Rope_iterator __first, + _Rope_iterator __middle, + _Rope_iterator __last) { + _Rope_rotate(__first, __middle, __last); +} +# endif +#endif /* _MSC_VER */ + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#endif + +__STL_END_NAMESPACE + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/set b/headers/cpp/set new file mode 100644 index 0000000000..c836c4596d --- /dev/null +++ b/headers/cpp/set @@ -0,0 +1,40 @@ +/* + * + * 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,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_SET +#define __SGI_STL_SET + +#ifndef __SGI_STL_INTERNAL_TREE_H +#include +#endif +#include +#include + +#endif /* __SGI_STL_SET */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/set.h b/headers/cpp/set.h new file mode 100644 index 0000000000..9004d2e047 --- /dev/null +++ b/headers/cpp/set.h @@ -0,0 +1,41 @@ +/* + * + * 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,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_SET_H +#define __SGI_STL_SET_H + +#include +#include + +#ifdef __STL_USE_NAMESPACES +using __STD::set; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_SET_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/slist b/headers/cpp/slist new file mode 100644 index 0000000000..c3ec74204c --- /dev/null +++ b/headers/cpp/slist @@ -0,0 +1,28 @@ +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef __SGI_STL_SLIST +#define __SGI_STL_SLIST + +#include +#include +#include +#include +#include + +#endif /* __SGI_STL_SLIST */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/slist.h b/headers/cpp/slist.h new file mode 100644 index 0000000000..d2377b0cf5 --- /dev/null +++ b/headers/cpp/slist.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef __SGI_STL_SLIST_H +#define __SGI_STL_SLIST_H + +#include +#include +#include + +#ifdef __STL_USE_NAMESPACES +using __STD::slist; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_SLIST_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/sstream b/headers/cpp/sstream new file mode 100644 index 0000000000..45393b1476 --- /dev/null +++ b/headers/cpp/sstream @@ -0,0 +1,343 @@ +/* This is part of libio/iostream, providing -*- C++ -*- input/output. +Copyright (C) 2000 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + +/* Written by Magnus Fromreide (magfr@lysator.liu.se). */ +/* seekoff and ideas for overflow is largely borrowed from libstdc++-v3 */ + +#ifndef __SSTREAM__ +#define __SSTREAM__ + +#include +#include +#include + +namespace std +{ + class stringbuf : public streambuf + { + public: + typedef char char_type; + typedef int int_type; + typedef streampos pos_type; + typedef streamoff off_type; + + explicit + stringbuf(int which=ios::in|ios::out) + : streambuf(), mode(static_cast(which)), + stream(NULL), stream_len(0) + { + stringbuf_init(); + } + + explicit + stringbuf(const string &str, int which=ios::in|ios::out) + : streambuf(), mode(static_cast(which)), + stream(NULL), stream_len(0) + { + if (mode & (ios::in|ios::out)) + { + stream_len = str.size(); + stream = new char_type[stream_len]; + str.copy(stream, stream_len); + } + stringbuf_init(); + } + + virtual + ~stringbuf() + { + delete[] stream; + } + + string + str() const + { + if (pbase() != 0) + return string(stream, pptr()-pbase()); + else + return string(); + } + + void + str(const string& str) + { + delete[] stream; + stream_len = str.size(); + stream = new char_type[stream_len]; + str.copy(stream, stream_len); + stringbuf_init(); + } + + protected: + // The buffer is already in gptr, so if it ends then it is out of data. + virtual int + underflow() + { + return EOF; + } + + virtual int + overflow(int c = EOF) + { + int res; + if (mode & ios::out) + { + if (c != EOF) + { + streamsize old_stream_len = stream_len; + stream_len += 1; + char_type* new_stream = new char_type[stream_len]; + memcpy(new_stream, stream, old_stream_len); + delete[] stream; + stream = new_stream; + stringbuf_sync(gptr()-eback(), pptr()-pbase()); + sputc(c); + res = c; + } + else + res = EOF; + } + else + res = 0; + return res; + } + + virtual streambuf* + setbuf(char_type* s, streamsize n) + { + if (n != 0) + { + delete[] stream; + stream = new char_type[n]; + memcpy(stream, s, n); + stream_len = n; + stringbuf_sync(0, 0); + } + return this; + } + + virtual pos_type + seekoff(off_type off, ios::seek_dir way, int which = ios::in | ios::out) + { + pos_type ret = pos_type(off_type(-1)); + bool testin = which & ios::in && mode & ios::in; + bool testout = which & ios::out && mode & ios::out; + bool testboth = testin && testout && way != ios::cur; + + if (stream_len && ((testin != testout) || testboth)) + { + char_type* beg = stream; + char_type* curi = NULL; + char_type* curo = NULL; + char_type* endi = NULL; + char_type* endo = NULL; + + if (testin) + { + curi = gptr(); + endi = egptr(); + } + if (testout) + { + curo = pptr(); + endo = epptr(); + } + + off_type newoffi = 0; + off_type newoffo = 0; + if (way == ios::beg) + { + newoffi = beg - curi; + newoffo = beg - curo; + } + else if (way == ios::end) + { + newoffi = endi - curi; + newoffo = endo - curo; + } + + if (testin && newoffi + off + curi - beg >= 0 && + endi - beg >= newoffi + off + curi - beg) + { + gbump(newoffi + off); + ret = pos_type(newoffi + off + curi); + } + if (testout && newoffo + off + curo - beg >= 0 && + endo - beg >= newoffo + off + curo - beg) + { + pbump(newoffo + off); + ret = pos_type(newoffo + off + curo); + } + } + return ret; + } + + virtual pos_type + seekpos(pos_type sp, int which = ios::in | ios::out) + { + pos_type ret = seekoff(sp, ios::beg, which); + return ret; + } + + private: + void + stringbuf_sync(streamsize i, streamsize o) + { + if (mode & ios::in) + setg(stream, stream + i, stream + stream_len); + if (mode & ios::out) + { + setp(stream, stream + stream_len); + pbump(o); + } + } + void + stringbuf_init() + { + if (mode & ios::ate) + stringbuf_sync(0, stream_len); + else + stringbuf_sync(0, 0); + } + + private: + ios::open_mode mode; + char_type* stream; + streamsize stream_len; + }; + + class istringstream : public istream { + public: + typedef char char_type; + typedef int int_type; + typedef streampos pos_type; + typedef streamoff off_type; + + explicit + istringstream(int which=ios::in) + : istream(&sb), sb(which | ios::in) + { } + + explicit + istringstream(const string& str, int which=ios::in) + : istream(&sb), sb(str, which | ios::in) + { } + + stringbuf* + rdbuf() const + { + return const_cast(&sb); + } + + string + str() const + { + return rdbuf()->str(); + } + void + str(const string& s) + { + rdbuf()->str(s); + } + private: + stringbuf sb; + }; + + class ostringstream : public ostream { + public: + typedef char char_type; + typedef int int_type; + typedef streampos pos_type; + typedef streamoff off_type; + + explicit + ostringstream(int which=ios::out) + : ostream(&sb), sb(which | ios::out) + { } + + explicit + ostringstream(const string& str, int which=ios::out) + : ostream(&sb), sb(str, which | ios::out) + { } + + stringbuf* + rdbuf() const + { + return const_cast(&sb); + } + + string + str() const + { + return rdbuf()->str(); + } + + void str(const string& s) + { + rdbuf()->str(s); + } + private: + stringbuf sb; + }; + + class stringstream : public iostream { + public: + typedef char char_type; + typedef int int_type; + typedef streampos pos_type; + typedef streamoff off_type; + + explicit + stringstream(int which=ios::out|ios::in) + : iostream(&sb), sb(which) + { } + + explicit + stringstream(const string& str, int which=ios::out|ios::in) + : iostream(&sb), sb(str, which) + { } + + stringbuf* + rdbuf() const + { + return const_cast(&sb); + } + + string + str() const + { + return rdbuf()->str(); + } + + void + str(const string& s) + { + rdbuf()->str(s); + } + private: + stringbuf sb; + }; +}; + +#endif /* not __STRSTREAM__ */ diff --git a/headers/cpp/stack b/headers/cpp/stack new file mode 100644 index 0000000000..36461d95b8 --- /dev/null +++ b/headers/cpp/stack @@ -0,0 +1,41 @@ +/* + * + * 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,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_STACK +#define __SGI_STL_STACK + +#include +#include +#include +#include +#include +#include + +#endif /* __SGI_STL_STACK */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/stack.h b/headers/cpp/stack.h new file mode 100644 index 0000000000..89beca82f1 --- /dev/null +++ b/headers/cpp/stack.h @@ -0,0 +1,46 @@ +/* + * + * 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,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_STACK_H +#define __SGI_STL_STACK_H + +#include +#include +#include +#include +#include + +#ifdef __STL_USE_NAMESPACES +using __STD::stack; +using __STD::queue; +using __STD::priority_queue; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_STACK_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/std/bastring.cc b/headers/cpp/std/bastring.cc new file mode 100644 index 0000000000..c37941a0b1 --- /dev/null +++ b/headers/cpp/std/bastring.cc @@ -0,0 +1,524 @@ +// Member templates for the -*- C++ -*- string classes. +// Copyright (C) 1994, 1999 Free Software Foundation + +// This file is part of the GNU ANSI C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// As a special exception, if you link this library with files +// compiled with a GNU compiler to produce an executable, this does not cause +// the resulting executable to be covered by the GNU General Public License. +// This exception does not however invalidate any other reasons why +// the executable file might be covered by the GNU General Public License. + +// Written by Jason Merrill based upon the specification by Takanori Adachi +// in ANSI X3J16/94-0013R2. + +extern "C++" { +template +inline void * basic_string ::Rep:: +operator new (size_t s, size_t extra) +{ + return Allocator::allocate(s + extra * sizeof (charT)); +} + +template +inline void basic_string ::Rep:: +operator delete (void * ptr) +{ + Allocator::deallocate(ptr, sizeof(Rep) + + reinterpret_cast(ptr)->res * + sizeof (charT)); +} + +template +inline size_t basic_string ::Rep:: +frob_size (size_t s) +{ + size_t i = 16; + while (i < s) i *= 2; + return i; +} + +template +inline basic_string ::Rep * +basic_string ::Rep:: +create (size_t extra) +{ + extra = frob_size (extra + 1); + Rep *p = new (extra) Rep; + p->res = extra; + p->ref = 1; + p->selfish = false; + return p; +} + +template +charT * basic_string ::Rep:: +clone () +{ + Rep *p = Rep::create (len); + p->copy (0, data (), len); + p->len = len; + return p->data (); +} + +template +inline bool basic_string ::Rep:: +excess_slop (size_t s, size_t r) +{ + return 2 * (s <= 16 ? 16 : s) < r; +} + +template +inline bool basic_string :: +check_realloc (basic_string::size_type s) const +{ + s += sizeof (charT); + rep ()->selfish = false; + return (rep ()->ref > 1 + || s > capacity () + || Rep::excess_slop (s, capacity ())); +} + +template +void basic_string :: +alloc (basic_string::size_type __size, bool __save) +{ + if (! check_realloc (__size)) + return; + + Rep *p = Rep::create (__size); + + if (__save) + { + p->copy (0, data (), length ()); + p->len = length (); + } + else + p->len = 0; + + repup (p); +} + +template +basic_string & +basic_string :: +replace (size_type pos1, size_type n1, + const basic_string& _str, size_type pos2, size_type n2) +{ + const size_t len2 = _str.length (); + + if (pos1 == 0 && n1 >= length () && pos2 == 0 && n2 >= len2) + return operator= (_str); + + OUTOFRANGE (pos2 > len2); + + if (n2 > len2 - pos2) + n2 = len2 - pos2; + + return replace (pos1, n1, _str.data () + pos2, n2); +} + +template +inline void basic_string ::Rep:: +copy (size_t pos, const charT *s, size_t n) +{ + if (n) + traits::copy (data () + pos, s, n); +} + +template +inline void basic_string ::Rep:: +move (size_t pos, const charT *s, size_t n) +{ + if (n) + traits::move (data () + pos, s, n); +} + +template +basic_string & +basic_string :: +replace (size_type pos, size_type n1, const charT* s, size_type n2) +{ + const size_type len = length (); + OUTOFRANGE (pos > len); + if (n1 > len - pos) + n1 = len - pos; + LENGTHERROR (len - n1 > max_size () - n2); + size_t newlen = len - n1 + n2; + + if (check_realloc (newlen)) + { + Rep *p = Rep::create (newlen); + p->copy (0, data (), pos); + p->copy (pos + n2, data () + pos + n1, len - (pos + n1)); + p->copy (pos, s, n2); + repup (p); + } + else + { + rep ()->move (pos + n2, data () + pos + n1, len - (pos + n1)); + rep ()->copy (pos, s, n2); + } + rep ()->len = newlen; + + return *this; +} + +template +inline void basic_string ::Rep:: +set (size_t pos, const charT c, size_t n) +{ + traits::set (data () + pos, c, n); +} + +template +basic_string & basic_string :: +replace (size_type pos, size_type n1, size_type n2, charT c) +{ + const size_t len = length (); + OUTOFRANGE (pos > len); + if (n1 > len - pos) + n1 = len - pos; + LENGTHERROR (len - n1 > max_size () - n2); + size_t newlen = len - n1 + n2; + + if (check_realloc (newlen)) + { + Rep *p = Rep::create (newlen); + p->copy (0, data (), pos); + p->copy (pos + n2, data () + pos + n1, len - (pos + n1)); + p->set (pos, c, n2); + repup (p); + } + else + { + rep ()->move (pos + n2, data () + pos + n1, len - (pos + n1)); + rep ()->set (pos, c, n2); + } + rep ()->len = newlen; + + return *this; +} + +template +void basic_string :: +resize (size_type n, charT c) +{ + LENGTHERROR (n > max_size ()); + + if (n > length ()) + append (n - length (), c); + else + erase (n); +} + +template +basic_string ::size_type +basic_string :: +copy (charT* s, size_type n, size_type pos) const +{ + OUTOFRANGE (pos > length ()); + + if (n > length () - pos) + n = length () - pos; + + traits::copy (s, data () + pos, n); + return n; +} + +template +basic_string ::size_type +basic_string :: +find (const charT* s, size_type pos, size_type n) const +{ + size_t xpos = pos; + for (; xpos + n <= length (); ++xpos) + if (traits::eq (data () [xpos], *s) + && traits::compare (data () + xpos, s, n) == 0) + return xpos; + return npos; +} + +template +inline basic_string ::size_type +basic_string :: +_find (const charT* ptr, charT c, size_type xpos, size_type len) +{ + for (; xpos < len; ++xpos) + if (traits::eq (ptr [xpos], c)) + return xpos; + return npos; +} + +template +basic_string ::size_type +basic_string :: +find (charT c, size_type pos) const +{ + return _find (data (), c, pos, length ()); +} + +template +basic_string ::size_type +basic_string :: +rfind (const charT* s, size_type pos, size_type n) const +{ + if (n > length ()) + return npos; + + size_t xpos = length () - n; + if (xpos > pos) + xpos = pos; + + for (++xpos; xpos-- > 0; ) + if (traits::eq (data () [xpos], *s) + && traits::compare (data () + xpos, s, n) == 0) + return xpos; + return npos; +} + +template +basic_string ::size_type +basic_string :: +rfind (charT c, size_type pos) const +{ + if (1 > length ()) + return npos; + + size_t xpos = length () - 1; + if (xpos > pos) + xpos = pos; + + for (++xpos; xpos-- > 0; ) + if (traits::eq (data () [xpos], c)) + return xpos; + return npos; +} + +template +basic_string ::size_type +basic_string :: +find_first_of (const charT* s, size_type pos, size_type n) const +{ + size_t xpos = pos; + for (; xpos < length (); ++xpos) + if (_find (s, data () [xpos], 0, n) != npos) + return xpos; + return npos; +} + +template +basic_string ::size_type +basic_string :: +find_last_of (const charT* s, size_type pos, size_type n) const +{ + if (length() == 0) + return npos; + size_t xpos = length () - 1; + if (xpos > pos) + xpos = pos; + for (++xpos; xpos-- > 0;) + if (_find (s, data () [xpos], 0, n) != npos) + return xpos; + return npos; +} + +template +basic_string ::size_type +basic_string :: +find_first_not_of (const charT* s, size_type pos, size_type n) const +{ + size_t xpos = pos; + for (; xpos < length (); ++xpos) + if (_find (s, data () [xpos], 0, n) == npos) + return xpos; + return npos; +} + +template +basic_string ::size_type +basic_string :: +find_first_not_of (charT c, size_type pos) const +{ + size_t xpos = pos; + for (; xpos < length (); ++xpos) + if (traits::ne (data () [xpos], c)) + return xpos; + return npos; +} + +template +basic_string ::size_type +basic_string :: +find_last_not_of (const charT* s, size_type pos, size_type n) const +{ + if (length() == 0) + return npos; + size_t xpos = length () - 1; + if (xpos > pos) + xpos = pos; + for (++xpos; xpos-- > 0;) + if (_find (s, data () [xpos], 0, n) == npos) + return xpos; + return npos; +} + +template +basic_string ::size_type +basic_string :: +find_last_not_of (charT c, size_type pos) const +{ + if (length() == 0) + return npos; + size_t xpos = length () - 1; + if (xpos > pos) + xpos = pos; + for (++xpos; xpos-- > 0;) + if (traits::ne (data () [xpos], c)) + return xpos; + return npos; +} + +template +int basic_string :: +compare (const basic_string& _str, size_type pos, size_type n) const +{ + OUTOFRANGE (pos > length ()); + + size_t rlen = length () - pos; + if (rlen > n) + rlen = n; + if (rlen > _str.length ()) + rlen = _str.length (); + int r = traits::compare (data () + pos, _str.data (), rlen); + if (r != 0) + return r; + if (rlen == n) + return 0; + return (length () - pos) - _str.length (); +} + +template +int basic_string :: +compare (const charT* s, size_type pos, size_type n) const +{ + OUTOFRANGE (pos > length ()); + + size_t rlen = length () - pos; + if (rlen > n) + rlen = n; + int r = traits::compare (data () + pos, s, rlen); + if (r != 0) + return r; + return (length () - pos) - n; +} + +#include + +template +istream & +operator>> (istream &is, basic_string &s) +{ + int w = is.width (0); + if (is.ipfx0 ()) + { + register streambuf *sb = is.rdbuf (); + s.resize (0); + while (1) + { + int ch = sb->sbumpc (); + if (ch == EOF) + { + is.setstate (ios::eofbit); + break; + } + else if (traits::is_del (ch)) + { + sb->sungetc (); + break; + } + s += static_cast (ch); + if (--w == 1) + break; + } + } + + is.isfx (); + if (s.length () == 0) + is.setstate (ios::failbit); + + return is; +} + +template +ostream & +operator<< (ostream &o, const basic_string & s) +{ + return o.write (s.data (), s.length ()); +} + +template +istream& +getline (istream &is, basic_string & s, charT delim) +{ + if (is.ipfx1 ()) + { + _IO_size_t _count = 0; + streambuf *sb = is.rdbuf (); + s.resize (0); + + while (1) + { + int ch = sb->sbumpc (); + if (ch == EOF) + { + is.setstate (_count == 0 + ? (ios::failbit|ios::eofbit) + : ios::eofbit); + break; + } + + ++_count; + + if (ch == delim) + break; + + s += static_cast (ch); + + if (s.length () == s.npos - 1) + { + is.setstate (ios::failbit); + break; + } + } + } + + // We need to be friends with istream to do this. + // is._gcount = _count; + is.isfx (); + + return is; +} + +template +basic_string ::Rep +basic_string::nilRep = { 0, 0, 1, false }; + +template +const basic_string ::size_type +basic_string ::npos; + +} // extern "C++" diff --git a/headers/cpp/std/bastring.h b/headers/cpp/std/bastring.h new file mode 100644 index 0000000000..d477af83ec --- /dev/null +++ b/headers/cpp/std/bastring.h @@ -0,0 +1,668 @@ +// Main templates for the -*- C++ -*- string classes. +// Copyright (C) 1994, 1995, 1999 Free Software Foundation + +// This file is part of the GNU ANSI C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// As a special exception, if you link this library with files +// compiled with a GNU compiler to produce an executable, this does not cause +// the resulting executable to be covered by the GNU General Public License. +// This exception does not however invalidate any other reasons why +// the executable file might be covered by the GNU General Public License. + +// Written by Jason Merrill based upon the specification by Takanori Adachi +// in ANSI X3J16/94-0013R2. + +#ifndef __BASTRING__ +#define __BASTRING__ + +#ifdef __GNUG__ +#pragma interface +#endif + +#include +#include + +// NOTE : This does NOT conform to the draft standard and is likely to change +#include + +extern "C++" { +class istream; class ostream; + +#include + +#ifdef __STL_USE_EXCEPTIONS + +extern void __out_of_range (const char *); +extern void __length_error (const char *); + +#define OUTOFRANGE(cond) \ + do { if (cond) __out_of_range (#cond); } while (0) +#define LENGTHERROR(cond) \ + do { if (cond) __length_error (#cond); } while (0) + +#else + +#include +#define OUTOFRANGE(cond) assert (!(cond)) +#define LENGTHERROR(cond) assert (!(cond)) + +#endif + +#ifdef __BEOS__ +// Needed for atomic_add(): +typedef long int32; +typedef volatile long vint32; +extern "C" int32 atomic_add(vint32* value, int32 addvalue); +#endif /* __BEOS__ */ + +template , + class Allocator = alloc > +class basic_string +{ +private: + struct Rep { + size_t len, res, ref; + bool selfish; + + charT* data () { return reinterpret_cast(this + 1); } + charT& operator[] (size_t s) { return data () [s]; } +#ifdef __BEOS__ + charT* grab () { if (selfish) return clone (); atomic_add((vint32*) &ref, 1); return data (); } + void release() { if (atomic_add((int32*) &ref, -1) == 1) delete this; } +#else + charT* grab () { if (selfish) return clone (); ++ref; return data (); } +#if defined __i486__ || defined __i586__ || defined __i686__ + void release () + { + size_t __val; + // This opcode exists as a .byte instead of as a mnemonic for the + // benefit of SCO OpenServer 5. The system assembler (which is + // essentially required on this target) can't assemble xaddl in + //COFF mode. + asm (".byte 0xf0, 0x0f, 0xc1, 0x02" // lock; xaddl %eax, (%edx) + : "=a" (__val) + : "0" (-1), "m" (ref), "d" (&ref) + : "memory"); + + if (__val == 1) + delete this; + } +#elif defined __sparcv9__ + void release () + { + size_t __newval, __oldval = ref; + do + { + __newval = __oldval - 1; + __asm__ ("cas [%4], %2, %0" + : "=r" (__oldval), "=m" (ref) + : "r" (__oldval), "m" (ref), "r"(&(ref)), "0" (__newval)); + } + while (__newval != __oldval); + + if (__oldval == 0) + delete this; + } +#else + void release () { if (--ref == 0) delete this; } +#endif +#endif /* __BEOS__ */ + inline static void * operator new (size_t, size_t); + inline static void operator delete (void *); + inline static Rep* create (size_t); + charT* clone (); + + inline void copy (size_t, const charT *, size_t); + inline void move (size_t, const charT *, size_t); + inline void set (size_t, const charT, size_t); + + inline static bool excess_slop (size_t, size_t); + inline static size_t frob_size (size_t); + + private: + Rep &operator= (const Rep &); + }; + +public: +// types: + typedef traits traits_type; + typedef typename traits::char_type value_type; + typedef Allocator allocator_type; + + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef charT& reference; + typedef const charT& const_reference; + typedef charT* pointer; + typedef const charT* const_pointer; + typedef pointer iterator; + typedef const_pointer const_iterator; + typedef ::reverse_iterator reverse_iterator; + typedef ::reverse_iterator const_reverse_iterator; + static const size_type npos = static_cast(-1); + +private: + Rep *rep () const { return reinterpret_cast(dat) - 1; } + void repup (Rep *p) { rep ()->release (); dat = p->data (); } + +public: + const charT* data () const + { return rep ()->data(); } + size_type length () const + { return rep ()->len; } + size_type size () const + { return rep ()->len; } + size_type capacity () const + { return rep ()->res; } + size_type max_size () const + { return (npos - 1)/sizeof (charT); } // XXX + bool empty () const + { return size () == 0; } + +// _lib.string.cons_ construct/copy/destroy: + basic_string& operator= (const basic_string& str) + { + if (&str != this) { rep ()->release (); dat = str.rep ()->grab (); } + return *this; + } + + explicit basic_string (): dat (nilRep.grab ()) { } + basic_string (const basic_string& _str): dat (_str.rep ()->grab ()) { } + basic_string (const basic_string& _str, size_type pos, size_type n = npos) + : dat (nilRep.grab ()) { assign (_str, pos, n); } + basic_string (const charT* s, size_type n) + : dat (nilRep.grab ()) { assign (s, n); } + basic_string (const charT* s) + : dat (nilRep.grab ()) { assign (s); } + basic_string (size_type n, charT c) + : dat (nilRep.grab ()) { assign (n, c); } +#ifdef __STL_MEMBER_TEMPLATES + template + basic_string(InputIterator __begin, InputIterator __end) +#else + basic_string(const_iterator __begin, const_iterator __end) +#endif + : dat (nilRep.grab ()) { assign (__begin, __end); } + + ~basic_string () + { rep ()->release (); } + + void swap (basic_string &s) { charT *d = dat; dat = s.dat; s.dat = d; } + + basic_string& append (const basic_string& _str, size_type pos = 0, + size_type n = npos) + { return replace (length (), 0, _str, pos, n); } + basic_string& append (const charT* s, size_type n) + { return replace (length (), 0, s, n); } + basic_string& append (const charT* s) + { return append (s, traits::length (s)); } + basic_string& append (size_type n, charT c) + { return replace (length (), 0, n, c); } +#ifdef __STL_MEMBER_TEMPLATES + template + basic_string& append(InputIterator first, InputIterator last) +#else + basic_string& append(const_iterator first, const_iterator last) +#endif + { return replace (iend (), iend (), first, last); } + + void push_back(charT __c) + { append(1, __c); } + + basic_string& assign (const basic_string& str, size_type pos = 0, + size_type n = npos) + { return replace (0, npos, str, pos, n); } + basic_string& assign (const charT* s, size_type n) + { return replace (0, npos, s, n); } + basic_string& assign (const charT* s) + { return assign (s, traits::length (s)); } + basic_string& assign (size_type n, charT c) + { return replace (0, npos, n, c); } +#ifdef __STL_MEMBER_TEMPLATES + template + basic_string& assign(InputIterator first, InputIterator last) +#else + basic_string& assign(const_iterator first, const_iterator last) +#endif + { return replace (ibegin (), iend (), first, last); } + + basic_string& operator= (const charT* s) + { return assign (s); } + basic_string& operator= (charT c) + { return assign (1, c); } + + basic_string& operator+= (const basic_string& rhs) + { return append (rhs); } + basic_string& operator+= (const charT* s) + { return append (s); } + basic_string& operator+= (charT c) + { return append (1, c); } + + basic_string& insert (size_type pos1, const basic_string& str, + size_type pos2 = 0, size_type n = npos) + { return replace (pos1, 0, str, pos2, n); } + basic_string& insert (size_type pos, const charT* s, size_type n) + { return replace (pos, 0, s, n); } + basic_string& insert (size_type pos, const charT* s) + { return insert (pos, s, traits::length (s)); } + basic_string& insert (size_type pos, size_type n, charT c) + { return replace (pos, 0, n, c); } + iterator insert(iterator p, charT c) + { size_type __o = p - ibegin (); + insert (p - ibegin (), 1, c); selfish (); + return ibegin () + __o; } + iterator insert(iterator p, size_type n, charT c) + { size_type __o = p - ibegin (); + insert (p - ibegin (), n, c); selfish (); + return ibegin () + __o; } +#ifdef __STL_MEMBER_TEMPLATES + template + void insert(iterator p, InputIterator first, InputIterator last) +#else + void insert(iterator p, const_iterator first, const_iterator last) +#endif + { replace (p, p, first, last); } + + basic_string& erase (size_type pos = 0, size_type n = npos) + { return replace (pos, n, (size_type)0, (charT)0); } + iterator erase(iterator p) + { size_type __o = p - begin(); + replace (__o, 1, (size_type)0, (charT)0); selfish (); + return ibegin() + __o; } + iterator erase(iterator f, iterator l) + { size_type __o = f - ibegin(); + replace (__o, l-f, (size_type)0, (charT)0);selfish (); + return ibegin() + __o; } + + basic_string& replace (size_type pos1, size_type n1, const basic_string& str, + size_type pos2 = 0, size_type n2 = npos); + basic_string& replace (size_type pos, size_type n1, const charT* s, + size_type n2); + basic_string& replace (size_type pos, size_type n1, const charT* s) + { return replace (pos, n1, s, traits::length (s)); } + basic_string& replace (size_type pos, size_type n1, size_type n2, charT c); + basic_string& replace (size_type pos, size_type n, charT c) + { return replace (pos, n, 1, c); } + basic_string& replace (iterator i1, iterator i2, const basic_string& str) + { return replace (i1 - ibegin (), i2 - i1, str); } + basic_string& replace (iterator i1, iterator i2, const charT* s, size_type n) + { return replace (i1 - ibegin (), i2 - i1, s, n); } + basic_string& replace (iterator i1, iterator i2, const charT* s) + { return replace (i1 - ibegin (), i2 - i1, s); } + basic_string& replace (iterator i1, iterator i2, size_type n, charT c) + { return replace (i1 - ibegin (), i2 - i1, n, c); } +#ifdef __STL_MEMBER_TEMPLATES + template + basic_string& replace(iterator i1, iterator i2, + InputIterator j1, InputIterator j2); +#else + basic_string& replace(iterator i1, iterator i2, + const_iterator j1, const_iterator j2); +#endif + +private: + static charT eos () { return traits::eos (); } + void unique () { if (rep ()->ref > 1) alloc (length (), true); } + void selfish () { unique (); rep ()->selfish = true; } + +public: + charT operator[] (size_type pos) const + { + if (pos == length ()) + return eos (); + return data ()[pos]; + } + + reference operator[] (size_type pos) + { selfish (); return (*rep ())[pos]; } + + reference at (size_type pos) + { + OUTOFRANGE (pos >= length ()); + return (*this)[pos]; + } + const_reference at (size_type pos) const + { + OUTOFRANGE (pos >= length ()); + return data ()[pos]; + } + +private: + void terminate () const + { traits::assign ((*rep ())[length ()], eos ()); } + +public: + const charT* c_str () const + { if (length () == 0) return ""; terminate (); return data (); } + void resize (size_type n, charT c); + void resize (size_type n) + { resize (n, eos ()); } + void reserve (size_type) { } + + size_type copy (charT* s, size_type n, size_type pos = 0) const; + + size_type find (const basic_string& str, size_type pos = 0) const + { return find (str.data(), pos, str.length()); } + size_type find (const charT* s, size_type pos, size_type n) const; + size_type find (const charT* _s, size_type pos = 0) const + { return find (_s, pos, traits::length (_s)); } + size_type find (charT c, size_type pos = 0) const; + + size_type rfind (const basic_string& str, size_type pos = npos) const + { return rfind (str.data(), pos, str.length()); } + size_type rfind (const charT* s, size_type pos, size_type n) const; + size_type rfind (const charT* s, size_type pos = npos) const + { return rfind (s, pos, traits::length (s)); } + size_type rfind (charT c, size_type pos = npos) const; + + size_type find_first_of (const basic_string& str, size_type pos = 0) const + { return find_first_of (str.data(), pos, str.length()); } + size_type find_first_of (const charT* s, size_type pos, size_type n) const; + size_type find_first_of (const charT* s, size_type pos = 0) const + { return find_first_of (s, pos, traits::length (s)); } + size_type find_first_of (charT c, size_type pos = 0) const + { return find (c, pos); } + + size_type find_last_of (const basic_string& str, size_type pos = npos) const + { return find_last_of (str.data(), pos, str.length()); } + size_type find_last_of (const charT* s, size_type pos, size_type n) const; + size_type find_last_of (const charT* s, size_type pos = npos) const + { return find_last_of (s, pos, traits::length (s)); } + size_type find_last_of (charT c, size_type pos = npos) const + { return rfind (c, pos); } + + size_type find_first_not_of (const basic_string& str, size_type pos = 0) const + { return find_first_not_of (str.data(), pos, str.length()); } + size_type find_first_not_of (const charT* s, size_type pos, size_type n) const; + size_type find_first_not_of (const charT* s, size_type pos = 0) const + { return find_first_not_of (s, pos, traits::length (s)); } + size_type find_first_not_of (charT c, size_type pos = 0) const; + + size_type find_last_not_of (const basic_string& str, size_type pos = npos) const + { return find_last_not_of (str.data(), pos, str.length()); } + size_type find_last_not_of (const charT* s, size_type pos, size_type n) const; + size_type find_last_not_of (const charT* s, size_type pos = npos) const + { return find_last_not_of (s, pos, traits::length (s)); } + size_type find_last_not_of (charT c, size_type pos = npos) const; + + basic_string substr (size_type pos = 0, size_type n = npos) const + { return basic_string (*this, pos, n); } + + int compare (const basic_string& str, size_type pos = 0, size_type n = npos) const; + // There is no 'strncmp' equivalent for charT pointers. + int compare (const charT* s, size_type pos, size_type n) const; + int compare (const charT* s, size_type pos = 0) const + { return compare (s, pos, traits::length (s)); } + + iterator begin () { selfish (); return &(*this)[0]; } + iterator end () { selfish (); return &(*this)[length ()]; } + +private: + iterator ibegin () const { return &(*rep ())[0]; } + iterator iend () const { return &(*rep ())[length ()]; } + +public: + const_iterator begin () const { return ibegin (); } + const_iterator end () const { return iend (); } + + reverse_iterator rbegin() { return reverse_iterator (end ()); } + const_reverse_iterator rbegin() const + { return const_reverse_iterator (end ()); } + reverse_iterator rend() { return reverse_iterator (begin ()); } + const_reverse_iterator rend() const + { return const_reverse_iterator (begin ()); } + +private: + void alloc (size_type size, bool save); + static size_type _find (const charT* ptr, charT c, size_type xpos, size_type len); + inline bool check_realloc (size_type s) const; + + static Rep nilRep; + charT *dat; +}; + +#ifdef __STL_MEMBER_TEMPLATES +template template +basic_string & basic_string :: +replace (iterator i1, iterator i2, InputIterator j1, InputIterator j2) +#else +template +basic_string & basic_string :: +replace (iterator i1, iterator i2, const_iterator j1, const_iterator j2) +#endif +{ + const size_type len = length (); + size_type pos = i1 - ibegin (); + size_type n1 = i2 - i1; + size_type n2 = j2 - j1; + + OUTOFRANGE (pos > len); + if (n1 > len - pos) + n1 = len - pos; + LENGTHERROR (len - n1 > max_size () - n2); + size_t newlen = len - n1 + n2; + + if (check_realloc (newlen)) + { + Rep *p = Rep::create (newlen); + p->copy (0, data (), pos); + p->copy (pos + n2, data () + pos + n1, len - (pos + n1)); + for (; j1 != j2; ++j1, ++pos) + traits::assign ((*p)[pos], *j1); + repup (p); + } + else + { + rep ()->move (pos + n2, data () + pos + n1, len - (pos + n1)); + for (; j1 != j2; ++j1, ++pos) + traits::assign ((*rep ())[pos], *j1); + } + rep ()->len = newlen; + + return *this; +} + +template +inline basic_string +operator+ (const basic_string & lhs, + const basic_string & rhs) +{ + basic_string _str (lhs); + _str.append (rhs); + return _str; +} + +template +inline basic_string +operator+ (const charT* lhs, const basic_string & rhs) +{ + basic_string _str (lhs); + _str.append (rhs); + return _str; +} + +template +inline basic_string +operator+ (charT lhs, const basic_string & rhs) +{ + basic_string _str (1, lhs); + _str.append (rhs); + return _str; +} + +template +inline basic_string +operator+ (const basic_string & lhs, const charT* rhs) +{ + basic_string _str (lhs); + _str.append (rhs); + return _str; +} + +template +inline basic_string +operator+ (const basic_string & lhs, charT rhs) +{ + basic_string str (lhs); + str.append (1, rhs); + return str; +} + +template +inline bool +operator== (const basic_string & lhs, + const basic_string & rhs) +{ + return (lhs.compare (rhs) == 0); +} + +template +inline bool +operator== (const charT* lhs, const basic_string & rhs) +{ + return (rhs.compare (lhs) == 0); +} + +template +inline bool +operator== (const basic_string & lhs, const charT* rhs) +{ + return (lhs.compare (rhs) == 0); +} + +template +inline bool +operator!= (const charT* lhs, const basic_string & rhs) +{ + return (rhs.compare (lhs) != 0); +} + +template +inline bool +operator!= (const basic_string & lhs, const charT* rhs) +{ + return (lhs.compare (rhs) != 0); +} + +template +inline bool +operator< (const basic_string & lhs, + const basic_string & rhs) +{ + return (lhs.compare (rhs) < 0); +} + +template +inline bool +operator< (const charT* lhs, const basic_string & rhs) +{ + return (rhs.compare (lhs) > 0); +} + +template +inline bool +operator< (const basic_string & lhs, const charT* rhs) +{ + return (lhs.compare (rhs) < 0); +} + +template +inline bool +operator> (const charT* lhs, const basic_string & rhs) +{ + return (rhs.compare (lhs) < 0); +} + +template +inline bool +operator> (const basic_string & lhs, const charT* rhs) +{ + return (lhs.compare (rhs) > 0); +} + +template +inline bool +operator<= (const charT* lhs, const basic_string & rhs) +{ + return (rhs.compare (lhs) >= 0); +} + +template +inline bool +operator<= (const basic_string & lhs, const charT* rhs) +{ + return (lhs.compare (rhs) <= 0); +} + +template +inline bool +operator>= (const charT* lhs, const basic_string & rhs) +{ + return (rhs.compare (lhs) <= 0); +} + +template +inline bool +operator>= (const basic_string & lhs, const charT* rhs) +{ + return (lhs.compare (rhs) >= 0); +} + +template +inline bool +operator!= (const basic_string & lhs, + const basic_string & rhs) +{ + return (lhs.compare (rhs) != 0); +} + +template +inline bool +operator> (const basic_string & lhs, + const basic_string & rhs) +{ + return (lhs.compare (rhs) > 0); +} + +template +inline bool +operator<= (const basic_string & lhs, + const basic_string & rhs) +{ + return (lhs.compare (rhs) <= 0); +} + +template +inline bool +operator>= (const basic_string & lhs, + const basic_string & rhs) +{ + return (lhs.compare (rhs) >= 0); +} + +class istream; class ostream; +template istream& +operator>> (istream&, basic_string &); +template ostream& +operator<< (ostream&, const basic_string &); +template istream& +getline (istream&, basic_string &, charT delim = '\n'); + +} // extern "C++" + +#include + +#endif diff --git a/headers/cpp/std/complext.cc b/headers/cpp/std/complext.cc new file mode 100644 index 0000000000..60227f2132 --- /dev/null +++ b/headers/cpp/std/complext.cc @@ -0,0 +1,273 @@ +// Member templates for the -*- C++ -*- complex number classes. +// Copyright (C) 1994 Free Software Foundation + +// This file is part of the GNU ANSI C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// As a special exception, if you link this library with files +// compiled with a GNU compiler to produce an executable, this does not cause +// the resulting executable to be covered by the GNU General Public License. +// This exception does not however invalidate any other reasons why +// the executable file might be covered by the GNU General Public License. + +// Written by Jason Merrill based upon the specification in the 27 May 1994 +// C++ working paper, ANSI document X3J16/94-0098. + +#include + +extern "C++" { +template complex +cos (const complex& x) +{ + return complex (cos (real (x)) * cosh (imag (x)), + - sin (real (x)) * sinh (imag (x))); +} + +template complex +cosh (const complex& x) +{ + return complex (cosh (real (x)) * cos (imag (x)), + sinh (real (x)) * sin (imag (x))); +} + +template complex +exp (const complex& x) +{ + return polar (FLOAT (exp (real (x))), imag (x)); +} + +template complex +log (const complex& x) +{ + return complex (log (abs (x)), arg (x)); +} + +template complex +pow (const complex& x, const complex& y) +{ + FLOAT logr = log (abs (x)); + FLOAT t = arg (x); + + return polar (FLOAT (exp (logr * real (y) - imag (y) * t)), + FLOAT (imag (y) * logr + real (y) * t)); +} + +template complex +pow (const complex& x, FLOAT y) +{ + return exp (FLOAT (y) * log (x)); +} + +template complex +pow (FLOAT x, const complex& y) +{ + return exp (y * FLOAT (log (x))); +} + +template complex +sin (const complex& x) +{ + return complex (sin (real (x)) * cosh (imag (x)), + cos (real (x)) * sinh (imag (x))); +} + +template complex +sinh (const complex& x) +{ + return complex (sinh (real (x)) * cos (imag (x)), + cosh (real (x)) * sin (imag (x))); +} + +#include + +template istream& +operator >> (istream& is, complex& x) +{ + FLOAT re, im = 0; + char ch = 0; + + if (is.ipfx0 ()) + { + if (is.peek () == '(') + is >> ch; + is >> re; + if (ch == '(') + { + is >> ch; + if (ch == ',') + is >> im >> ch; + } + } + is.isfx (); + + if (ch != 0 && ch != ')') + is.setstate (ios::failbit); + else if (is.good ()) + x = complex (re, im); + + return is; +} + +template ostream& +operator << (ostream& os, const complex& x) +{ + return os << '(' << real (x) << ',' << imag (x) << ')'; +} + +// The code below is adapted from f2c's libF77, and is subject to this +// copyright: + +/**************************************************************** +Copyright 1990, 1991, 1992, 1993 by AT&T Bell Laboratories and Bellcore. + +Permission to use, copy, modify, and distribute this software +and its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the names of AT&T Bell Laboratories or +Bellcore or any of their entities not be used in advertising or +publicity pertaining to distribution of the software without +specific, written prior permission. + +AT&T and Bellcore disclaim all warranties with regard to this +software, including all implied warranties of merchantability +and fitness. In no event shall AT&T or Bellcore be liable for +any special, indirect or consequential damages or any damages +whatsoever resulting from loss of use, data or profits, whether +in an action of contract, negligence or other tortious action, +arising out of or in connection with the use or performance of +this software. +****************************************************************/ + +template complex& +__doadv (complex* ths, const complex& y) +{ + FLOAT ar = abs (y.re); + FLOAT ai = abs (y.im); + FLOAT nr, ni; + FLOAT t, d; + if (ar <= ai) + { + t = y.re / y.im; + d = y.im * (1 + t*t); + nr = (ths->re * t + ths->im) / d; + ni = (ths->im * t - ths->re) / d; + } + else + { + t = y.im / y.re; + d = y.re * (1 + t*t); + nr = (ths->re + ths->im * t) / d; + ni = (ths->im - ths->re * t) / d; + } + ths->re = nr; + ths->im = ni; + return *ths; +} + +template complex +operator / (const complex& x, const complex& y) +{ + FLOAT ar = abs (real (y)); + FLOAT ai = abs (imag (y)); + FLOAT nr, ni; + FLOAT t, d; + if (ar <= ai) + { + t = real (y) / imag (y); + d = imag (y) * (1 + t*t); + nr = (real (x) * t + imag (x)) / d; + ni = (imag (x) * t - real (x)) / d; + } + else + { + t = imag (y) / real (y); + d = real (y) * (1 + t*t); + nr = (real (x) + imag (x) * t) / d; + ni = (imag (x) - real (x) * t) / d; + } + return complex (nr, ni); +} + +template complex +operator / (FLOAT x, const complex& y) +{ + FLOAT ar = abs (real (y)); + FLOAT ai = abs (imag (y)); + FLOAT nr, ni; + FLOAT t, d; + if (ar <= ai) + { + t = real (y) / imag (y); + d = imag (y) * (1 + t*t); + nr = x * t / d; + ni = -x / d; + } + else + { + t = imag (y) / real (y); + d = real (y) * (1 + t*t); + nr = x / d; + ni = -x * t / d; + } + return complex (nr, ni); +} + +template complex +pow (const complex& xin, int y) +{ + if (y == 0) + return complex (1.0); + complex r (1.0); + complex x (xin); + if (y < 0) + { + y = -y; + x = FLOAT(1)/x; + } + for (;;) + { + if (y & 1) + r *= x; + if (y >>= 1) + x *= x; + else + return r; + } +} + +template complex +sqrt (const complex& x) +{ + FLOAT r = abs (x); + FLOAT nr, ni; + if (r == 0.0) + nr = ni = r; + else if (real (x) > 0) + { + nr = sqrt (0.5 * (r + real (x))); + ni = imag (x) / nr / 2; + } + else + { + ni = sqrt (0.5 * (r - real (x))); + if (imag (x) < 0) + ni = - ni; + nr = imag (x) / ni / 2; + } + return complex (nr, ni); +} +} // extern "C++" diff --git a/headers/cpp/std/complext.h b/headers/cpp/std/complext.h new file mode 100644 index 0000000000..6c55037bf9 --- /dev/null +++ b/headers/cpp/std/complext.h @@ -0,0 +1,400 @@ +// The template and inlines for the -*- C++ -*- complex number classes. +// Copyright (C) 1994 Free Software Foundation + +// This file is part of the GNU ANSI C++ Library. This library is free +// software; you can redistribute it and/or modify it under the terms of +// the GNU General Public License as published by the Free Software +// Foundation; either version 2, or (at your option) any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// As a special exception, if you link this library with files compiled +// with a GNU compiler to produce an executable, this does not cause the +// resulting executable to be covered by the GNU General Public License. +// This exception does not however invalidate any other reasons why the +// executable file might be covered by the GNU General Public License. + +// Written by Jason Merrill based upon the specification in the 27 May 1994 +// C++ working paper, ANSI document X3J16/94-0098. + +#ifndef __COMPLEXT__ +#define __COMPLEXT__ + +#ifdef __GNUG__ +#pragma interface +#endif + +#include + +#if ! defined (__GNUG__) && ! defined (__attribute__) +#define __attribute__(foo) /* Ignore. */ +#endif + +class istream; +class ostream; + +extern "C++" { +template class complex; +template complex<_FLT>& + __doapl (complex<_FLT>* ths, const complex<_FLT>& r); +template complex<_FLT>& + __doami (complex<_FLT>* ths, const complex<_FLT>& r); +template complex<_FLT>& + __doaml (complex<_FLT>* ths, const complex<_FLT>& r); +template complex<_FLT>& + __doadv (complex<_FLT>* ths, const complex<_FLT>& r); + +template +class complex +{ +public: + complex (_FLT r = 0, _FLT i = 0): re (r), im (i) { } + complex& operator += (const complex&); + complex& operator -= (const complex&); + complex& operator *= (const complex&); + complex& operator /= (const complex&); + _FLT real () const { return re; } + _FLT imag () const { return im; } +private: + _FLT re, im; + + friend complex& __doapl<> (complex *, const complex&); + friend complex& __doami<> (complex *, const complex&); + friend complex& __doaml<> (complex *, const complex&); + friend complex& __doadv<> (complex *, const complex&); +}; + +// Declare specializations. +class complex; +class complex; +class complex; + +template +inline complex<_FLT>& +__doapl (complex<_FLT>* ths, const complex<_FLT>& r) +{ + ths->re += r.re; + ths->im += r.im; + return *ths; +} +template +inline complex<_FLT>& +complex<_FLT>::operator += (const complex<_FLT>& r) +{ + return __doapl (this, r); +} + +template +inline complex<_FLT>& +__doami (complex<_FLT>* ths, const complex<_FLT>& r) +{ + ths->re -= r.re; + ths->im -= r.im; + return *ths; +} +template +inline complex<_FLT>& +complex<_FLT>::operator -= (const complex<_FLT>& r) +{ + return __doami (this, r); +} + +template +inline complex<_FLT>& +__doaml (complex<_FLT>* ths, const complex<_FLT>& r) +{ + _FLT f = ths->re * r.re - ths->im * r.im; + ths->im = ths->re * r.im + ths->im * r.re; + ths->re = f; + return *ths; +} +template +inline complex<_FLT>& +complex<_FLT>::operator *= (const complex<_FLT>& r) +{ + return __doaml (this, r); +} + +template +inline complex<_FLT>& +complex<_FLT>::operator /= (const complex<_FLT>& r) +{ + return __doadv (this, r); +} + +template inline _FLT +imag (const complex<_FLT>& x) __attribute__ ((const)); + +template inline _FLT +imag (const complex<_FLT>& x) +{ + return x.imag (); +} + +template inline _FLT +real (const complex<_FLT>& x) __attribute__ ((const)); + +template inline _FLT +real (const complex<_FLT>& x) +{ + return x.real (); +} + +template inline complex<_FLT> +operator + (const complex<_FLT>& x, const complex<_FLT>& y) __attribute__ ((const)); + +template inline complex<_FLT> +operator + (const complex<_FLT>& x, const complex<_FLT>& y) +{ + return complex<_FLT> (real (x) + real (y), imag (x) + imag (y)); +} + +template inline complex<_FLT> +operator + (const complex<_FLT>& x, _FLT y) __attribute__ ((const)); + +template inline complex<_FLT> +operator + (const complex<_FLT>& x, _FLT y) +{ + return complex<_FLT> (real (x) + y, imag (x)); +} + +template inline complex<_FLT> +operator + (_FLT x, const complex<_FLT>& y) __attribute__ ((const)); + +template inline complex<_FLT> +operator + (_FLT x, const complex<_FLT>& y) +{ + return complex<_FLT> (x + real (y), imag (y)); +} + +template inline complex<_FLT> +operator - (const complex<_FLT>& x, const complex<_FLT>& y) __attribute__ ((const)); + +template inline complex<_FLT> +operator - (const complex<_FLT>& x, const complex<_FLT>& y) +{ + return complex<_FLT> (real (x) - real (y), imag (x) - imag (y)); +} + +template inline complex<_FLT> +operator - (const complex<_FLT>& x, _FLT y) __attribute__ ((const)); + +template inline complex<_FLT> +operator - (const complex<_FLT>& x, _FLT y) +{ + return complex<_FLT> (real (x) - y, imag (x)); +} + +template inline complex<_FLT> +operator - (_FLT x, const complex<_FLT>& y) __attribute__ ((const)); + +template inline complex<_FLT> +operator - (_FLT x, const complex<_FLT>& y) +{ + return complex<_FLT> (x - real (y), - imag (y)); +} + +template inline complex<_FLT> +operator * (const complex<_FLT>& x, const complex<_FLT>& y) __attribute__ ((const)); + +template inline complex<_FLT> +operator * (const complex<_FLT>& x, const complex<_FLT>& y) +{ + return complex<_FLT> (real (x) * real (y) - imag (x) * imag (y), + real (x) * imag (y) + imag (x) * real (y)); +} + +template inline complex<_FLT> +operator * (const complex<_FLT>& x, _FLT y) __attribute__ ((const)); + +template inline complex<_FLT> +operator * (const complex<_FLT>& x, _FLT y) +{ + return complex<_FLT> (real (x) * y, imag (x) * y); +} + +template inline complex<_FLT> +operator * (_FLT x, const complex<_FLT>& y) __attribute__ ((const)); + +template inline complex<_FLT> +operator * (_FLT x, const complex<_FLT>& y) +{ + return complex<_FLT> (x * real (y), x * imag (y)); +} + +template complex<_FLT> +operator / (const complex<_FLT>& x, _FLT y) __attribute__ ((const)); + +template complex<_FLT> +operator / (const complex<_FLT>& x, _FLT y) +{ + return complex<_FLT> (real (x) / y, imag (x) / y); +} + +template inline complex<_FLT> +operator + (const complex<_FLT>& x) __attribute__ ((const)); + +template inline complex<_FLT> +operator + (const complex<_FLT>& x) +{ + return x; +} + +template inline complex<_FLT> +operator - (const complex<_FLT>& x) __attribute__ ((const)); + +template inline complex<_FLT> +operator - (const complex<_FLT>& x) +{ + return complex<_FLT> (-real (x), -imag (x)); +} + +template inline bool +operator == (const complex<_FLT>& x, const complex<_FLT>& y) __attribute__ ((const)); + +template inline bool +operator == (const complex<_FLT>& x, const complex<_FLT>& y) +{ + return real (x) == real (y) && imag (x) == imag (y); +} + +template inline bool +operator == (const complex<_FLT>& x, _FLT y) __attribute__ ((const)); + +template inline bool +operator == (const complex<_FLT>& x, _FLT y) +{ + return real (x) == y && imag (x) == 0; +} + +template inline bool +operator == (_FLT x, const complex<_FLT>& y) __attribute__ ((const)); + +template inline bool +operator == (_FLT x, const complex<_FLT>& y) +{ + return x == real (y) && imag (y) == 0; +} + +template inline bool +operator != (const complex<_FLT>& x, const complex<_FLT>& y) __attribute__ ((const)); + +template inline bool +operator != (const complex<_FLT>& x, const complex<_FLT>& y) +{ + return real (x) != real (y) || imag (x) != imag (y); +} + +template inline bool +operator != (const complex<_FLT>& x, _FLT y) __attribute__ ((const)); + +template inline bool +operator != (const complex<_FLT>& x, _FLT y) +{ + return real (x) != y || imag (x) != 0; +} + +template inline bool +operator != (_FLT x, const complex<_FLT>& y) __attribute__ ((const)); + +template inline bool +operator != (_FLT x, const complex<_FLT>& y) +{ + return x != real (y) || imag (y) != 0; +} + +// Some targets don't provide a prototype for hypot when -ansi. +extern "C" double hypot (double, double) __attribute__ ((const)); + +template inline _FLT +abs (const complex<_FLT>& x) __attribute__ ((const)); + +template inline _FLT +abs (const complex<_FLT>& x) +{ + return hypot (real (x), imag (x)); +} + +template inline _FLT +arg (const complex<_FLT>& x) __attribute__ ((const)); + +template inline _FLT +arg (const complex<_FLT>& x) +{ + return atan2 (imag (x), real (x)); +} + +template inline complex<_FLT> +polar (_FLT r, _FLT t) __attribute__ ((const)); + +template inline complex<_FLT> +polar (_FLT r, _FLT t) +{ + return complex<_FLT> (r * cos (t), r * sin (t)); +} + +template inline complex<_FLT> +conj (const complex<_FLT>& x) __attribute__ ((const)); + +template inline complex<_FLT> +conj (const complex<_FLT>& x) +{ + return complex<_FLT> (real (x), -imag (x)); +} + +template inline _FLT +norm (const complex<_FLT>& x) __attribute__ ((const)); + +template inline _FLT +norm (const complex<_FLT>& x) +{ + return real (x) * real (x) + imag (x) * imag (x); +} + +// Declarations of templates in complext.ccI + +template complex<_FLT> + operator / (const complex<_FLT>&, const complex<_FLT>&) __attribute__ ((const)); +template complex<_FLT> + operator / (_FLT, const complex<_FLT>&) __attribute__ ((const)); +template complex<_FLT> + cos (const complex<_FLT>&) __attribute__ ((const)); +template complex<_FLT> + cosh (const complex<_FLT>&) __attribute__ ((const)); +template complex<_FLT> + exp (const complex<_FLT>&) __attribute__ ((const)); +template complex<_FLT> + log (const complex<_FLT>&) __attribute__ ((const)); +template complex<_FLT> + pow (const complex<_FLT>&, const complex<_FLT>&) __attribute__ ((const)); +template complex<_FLT> + pow (const complex<_FLT>&, _FLT) __attribute__ ((const)); +template complex<_FLT> + pow (const complex<_FLT>&, int) __attribute__ ((const)); +template complex<_FLT> + pow (_FLT, const complex<_FLT>&) __attribute__ ((const)); +template complex<_FLT> + sin (const complex<_FLT>&) __attribute__ ((const)); +template complex<_FLT> + sinh (const complex<_FLT>&) __attribute__ ((const)); +template complex<_FLT> + sqrt (const complex<_FLT>&) __attribute__ ((const)); + +template istream& operator >> (istream&, complex<_FLT>&); +template ostream& operator << (ostream&, const complex<_FLT>&); +} // extern "C++" + +// Specializations and such + +#include +#include +#include + +#endif diff --git a/headers/cpp/std/dcomplex.h b/headers/cpp/std/dcomplex.h new file mode 100644 index 0000000000..5812d9fa7d --- /dev/null +++ b/headers/cpp/std/dcomplex.h @@ -0,0 +1,91 @@ +// The -*- C++ -*- double_complex class. +// Copyright (C) 1994 Free Software Foundation + +// This file is part of the GNU ANSI C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// As a special exception, if you link this library with files +// compiled with a GNU compiler to produce an executable, this does not cause +// the resulting executable to be covered by the GNU General Public License. +// This exception does not however invalidate any other reasons why +// the executable file might be covered by the GNU General Public License. + +// Written by Jason Merrill based upon the specification in the 27 May 1994 +// C++ working paper, ANSI document X3J16/94-0098. + +#ifndef __DCOMPLEX__ +#define __DCOMPLEX__ + +#ifdef __GNUG__ +#pragma interface "dcomplex" +#endif + +extern "C++" { +class complex +{ +public: + complex (double r = 0, double i = 0): re (r), im (i) { } + complex (const complex& r): re (r.real ()), im (r.imag ()) { } + explicit complex (const complex& r); + + complex& operator+= (const complex& r) { return __doapl (this, r); } + complex& operator-= (const complex& r) { return __doami (this, r); } + complex& operator*= (const complex& r) { return __doaml (this, r); } + complex& operator/= (const complex& r) { return __doadv (this, r); } + + double real () const { return re; } + double imag () const { return im; } +private: + double re, im; + + friend complex& __doapl<> (complex *, const complex&); + friend complex& __doami<> (complex *, const complex&); + friend complex& __doaml<> (complex *, const complex&); + friend complex& __doadv<> (complex *, const complex&); + +#ifndef __STRICT_ANSI__ + friend inline complex operator + (const complex& x, double y) + { return operator+<> (x, y); } + friend inline complex operator + (double x, const complex& y) + { return operator+<> (x, y); } + friend inline complex operator - (const complex& x, double y) + { return operator-<> (x, y); } + friend inline complex operator - (double x, const complex& y) + { return operator-<> (x, y); } + friend inline complex operator * (const complex& x, double y) + { return operator*<> (x, y); } + friend inline complex operator * (double x, const complex& y) + { return operator*<> (x, y); } + friend inline complex operator / (const complex& x, double y) + { return operator/<> (x, y); } + friend inline complex operator / (double x, const complex& y) + { return operator/<> (x, y); } + friend inline bool operator == (const complex& x, double y) + { return operator==<> (x, y); } + friend inline bool operator == (double x, const complex& y) + { return operator==<> (x, y); } + friend inline bool operator != (const complex& x, double y) + { return operator!=<> (x, y); } + friend inline bool operator != (double x, const complex& y) + { return operator!=<> (x, y); } +#endif /* __STRICT_ANSI__ */ +}; + +inline complex::complex (const complex& r) +: re (r.real ()), im (r.imag ()) +{ } +} // extern "C++" + +#endif diff --git a/headers/cpp/std/fcomplex.h b/headers/cpp/std/fcomplex.h new file mode 100644 index 0000000000..cd9af1a2e0 --- /dev/null +++ b/headers/cpp/std/fcomplex.h @@ -0,0 +1,87 @@ +// The -*- C++ -*- float_complex class. +// Copyright (C) 1994 Free Software Foundation + +// This file is part of the GNU ANSI C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// As a special exception, if you link this library with files +// compiled with a GNU compiler to produce an executable, this does not cause +// the resulting executable to be covered by the GNU General Public License. +// This exception does not however invalidate any other reasons why +// the executable file might be covered by the GNU General Public License. + +// Written by Jason Merrill based upon the specification in the 27 May 1994 +// C++ working paper, ANSI document X3J16/94-0098. + +#ifndef __FCOMPLEX__ +#define __FCOMPLEX__ + +#ifdef __GNUG__ +#pragma interface "fcomplex" +#endif + +extern "C++" { +class complex +{ +public: + complex (float r = 0, float i = 0): re (r), im (i) { } + explicit complex (const complex& r); + explicit complex (const complex& r); + + complex& operator+= (const complex& r) { return __doapl (this, r); } + complex& operator-= (const complex& r) { return __doami (this, r); } + complex& operator*= (const complex& r) { return __doaml (this, r); } + complex& operator/= (const complex& r) { return __doadv (this, r); } + + float real () const { return re; } + float imag () const { return im; } +private: + float re, im; + + friend complex& __doapl<> (complex *, const complex&); + friend complex& __doami<> (complex *, const complex&); + friend complex& __doaml<> (complex *, const complex&); + friend complex& __doadv<> (complex *, const complex&); + +#ifndef __STRICT_ANSI__ + friend inline complex operator + (const complex& x, float y) + { return operator+<> (x, y); } + friend inline complex operator + (float x, const complex& y) + { return operator+<> (x, y); } + friend inline complex operator - (const complex& x, float y) + { return operator-<> (x, y); } + friend inline complex operator - (float x, const complex& y) + { return operator-<> (x, y); } + friend inline complex operator * (const complex& x, float y) + { return operator*<> (x, y); } + friend inline complex operator * (float x, const complex& y) + { return operator*<> (x, y); } + friend inline complex operator / (const complex& x, float y) + { return operator/<> (x, y); } + friend inline complex operator / (float x, const complex& y) + { return operator/<> (x, y); } + friend inline bool operator == (const complex& x, float y) + { return operator==<> (x, y); } + friend inline bool operator == (float x, const complex& y) + { return operator==<> (x, y); } + friend inline bool operator != (const complex& x, float y) + { return operator!=<> (x, y); } + friend inline bool operator != (float x, const complex& y) + { return operator!=<> (x, y); } +#endif /* __STRICT_ANSI__ */ +}; +} // extern "C++" + +#endif diff --git a/headers/cpp/std/gslice.h b/headers/cpp/std/gslice.h new file mode 100644 index 0000000000..4f6e854a14 --- /dev/null +++ b/headers/cpp/std/gslice.h @@ -0,0 +1,111 @@ +// The template and inlines for the -*- C++ -*- gslice class. + +// Copyright (C) 1997-1999 Cygnus Solutions +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis + +#ifndef __GSLICE__ +#define __GSLICE__ + +extern "C++" { + +struct _Indexer { + size_t _M_count; + size_t _M_start; + valarray _M_size; + valarray _M_stride; + valarray _M_index; + _Indexer(size_t, const valarray&, const valarray&); + void _M_increment_use() { ++_M_count; } + size_t _M_decrement_use() { return --_M_count; } +}; + + +class gslice +{ +public: + gslice (); + gslice (size_t, const valarray&, const valarray&); + gslice(const gslice&); + ~gslice(); + + gslice& operator= (const gslice&); + size_t start () const; + valarray size () const; + valarray stride () const; + +private: + _Indexer* _M_index; + + template friend class valarray; +}; + +inline size_t +gslice::start () const +{ return _M_index ? _M_index->_M_start : 0; } + +inline valarray +gslice::size () const +{ return _M_index ? _M_index->_M_size : valarray(); } + +inline valarray +gslice::stride () const +{ return _M_index ? _M_index->_M_stride : valarray(); } + +inline gslice::gslice () : _M_index(0) {} + +inline +gslice::gslice(size_t __o, const valarray& __l, + const valarray& __s) + : _M_index(new _Indexer(__o, __l, __s)) {} + +inline +gslice::gslice(const gslice& __g) : _M_index(__g._M_index) +{ if (_M_index) _M_index->_M_increment_use(); } + +inline +gslice::~gslice() +{ if (_M_index && _M_index->_M_decrement_use() == 0) delete _M_index; } + +inline gslice& +gslice::operator= (const gslice& __g) +{ + if (__g._M_index) __g._M_index->_M_increment_use(); + if (_M_index && _M_index->_M_decrement_use() == 0) delete _M_index; + _M_index = __g._M_index; + return *this; +} + + +} // extern "C++" + +#endif // __GSLICE__ + +// Local Variables: +// mode:c++ +// End: diff --git a/headers/cpp/std/gslice_array.h b/headers/cpp/std/gslice_array.h new file mode 100644 index 0000000000..8a67cac905 --- /dev/null +++ b/headers/cpp/std/gslice_array.h @@ -0,0 +1,170 @@ +// The template and inlines for the -*- C++ -*- gslice_array class. + +// Copyright (C) 1997-1999 Cygnus Solutions +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis + +#ifndef __GSLICE_ARRAY__ +#define __GSLICE_ARRAY__ + +extern "C++" { + +template class gslice_array +{ +public: + typedef _Tp value_type; + + void operator= (const valarray<_Tp>&) const; + void operator*= (const valarray<_Tp>&) const; + void operator/= (const valarray<_Tp>&) const; + void operator%= (const valarray<_Tp>&) const; + void operator+= (const valarray<_Tp>&) const; + void operator-= (const valarray<_Tp>&) const; + void operator^= (const valarray<_Tp>&) const; + void operator&= (const valarray<_Tp>&) const; + void operator|= (const valarray<_Tp>&) const; + void operator<<=(const valarray<_Tp>&) const; + void operator>>=(const valarray<_Tp>&) const; + void operator=(const _Tp&); + + template + void operator= (const _Expr<_Dom,_Tp>&) const; + template + void operator*= (const _Expr<_Dom,_Tp>&) const; + template + void operator/= (const _Expr<_Dom,_Tp>&) const; + template + void operator%= (const _Expr<_Dom,_Tp>&) const; + template + void operator+= (const _Expr<_Dom,_Tp>&) const; + template + void operator-= (const _Expr<_Dom,_Tp>&) const; + template + void operator^= (const _Expr<_Dom,_Tp>&) const; + template + void operator&= (const _Expr<_Dom,_Tp>&) const; + template + void operator|= (const _Expr<_Dom,_Tp>&) const; + template + void operator<<= (const _Expr<_Dom,_Tp>&) const; + template + void operator>>= (const _Expr<_Dom,_Tp>&) const; + +private: + _Array<_Tp> _M_array; + const valarray& _M_index; + + friend class valarray<_Tp>; + + gslice_array (_Array<_Tp>, const valarray&); + + // this constructor needs to be implemented. + gslice_array (const gslice_array&); + + // not implemented + gslice_array(); + gslice_array& operator= (const gslice_array&); +}; + +template +inline +gslice_array<_Tp>::gslice_array (_Array<_Tp> __a, + const valarray& __i) + : _M_array (__a), _M_index (__i) {} + + +template +inline +gslice_array<_Tp>::gslice_array (const gslice_array<_Tp>& __a) + : _M_array (__a._M_array), _M_index (__a._M_index) {} + + +template +inline void +gslice_array<_Tp>::operator= (const _Tp& __t) +{ + __valarray_fill (_M_array, _Array(_M_index), + _M_index.size(), __t); +} + +template +inline void +gslice_array<_Tp>::operator= (const valarray<_Tp>& __v) const +{ + __valarray_copy (_Array<_Tp> (__v), __v.size (), + _M_array, _Array(_M_index)); +} + +template +template +inline void +gslice_array<_Tp>::operator= (const _Expr& __e) const +{ + __valarray_copy (__e, _M_index.size(), _M_array, + _Array(_M_index)); +} + +#undef _DEFINE_VALARRAY_OPERATOR +#define _DEFINE_VALARRAY_OPERATOR(op, name) \ +template \ +inline void \ +gslice_array<_Tp>::operator##op##= (const valarray<_Tp>& __v) const \ +{ \ + _Array_augmented_##name (_M_array, _Array(_M_index), \ + _Array<_Tp> (__v), __v.size ()); \ +} \ + \ +template template \ +inline void \ +gslice_array<_Tp>::operator##op##= (const _Expr& __e) const \ +{ \ + _Array_augmented_##name (_M_array, _Array(_M_index), __e, \ + _M_index.size()); \ +} + +_DEFINE_VALARRAY_OPERATOR(*, multiplies) +_DEFINE_VALARRAY_OPERATOR(/, divides) +_DEFINE_VALARRAY_OPERATOR(%, modulus) +_DEFINE_VALARRAY_OPERATOR(+, plus) +_DEFINE_VALARRAY_OPERATOR(-, minus) +_DEFINE_VALARRAY_OPERATOR(^, xor) +_DEFINE_VALARRAY_OPERATOR(&, and) +_DEFINE_VALARRAY_OPERATOR(|, or) +_DEFINE_VALARRAY_OPERATOR(<<, shift_left) +_DEFINE_VALARRAY_OPERATOR(>>, shift_right) + +#undef _DEFINE_VALARRAY_OPERATOR + +} // extern "C++" + + +#endif // __GSLICE_ARRAY__ + +// Local Variables: +// mode:c++ +// End: diff --git a/headers/cpp/std/indirect_array.h b/headers/cpp/std/indirect_array.h new file mode 100644 index 0000000000..bb5b79fb83 --- /dev/null +++ b/headers/cpp/std/indirect_array.h @@ -0,0 +1,157 @@ +// The template and inlines for the -*- C++ -*- indirect_array class. + +// Copyright (C) 1997-1999 Cygnus Solutions +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis + +#ifndef __INDIRECT_ARRAY__ +#define __INDIRECT_ARRAY__ + +extern "C++" { + +template class indirect_array +{ +public: + typedef _Tp value_type; + + void operator= (const valarray<_Tp>&) const; + void operator*= (const valarray<_Tp>&) const; + void operator/= (const valarray<_Tp>&) const; + void operator%= (const valarray<_Tp>&) const; + void operator+= (const valarray<_Tp>&) const; + void operator-= (const valarray<_Tp>&) const; + void operator^= (const valarray<_Tp>&) const; + void operator&= (const valarray<_Tp>&) const; + void operator|= (const valarray<_Tp>&) const; + void operator<<= (const valarray<_Tp>&) const; + void operator>>= (const valarray<_Tp>&) const; + void operator= (const _Tp&); + + template + void operator= (const _Expr<_Dom, _Tp>&) const; + template + void operator*= (const _Expr<_Dom, _Tp>&) const; + template + void operator/= (const _Expr<_Dom, _Tp>&) const; + template + void operator%= (const _Expr<_Dom, _Tp>&) const; + template + void operator+= (const _Expr<_Dom, _Tp>&) const; + template + void operator-= (const _Expr<_Dom, _Tp>&) const; + template + void operator^= (const _Expr<_Dom, _Tp>&) const; + template + void operator&= (const _Expr<_Dom, _Tp>&) const; + template + void operator|= (const _Expr<_Dom, _Tp>&) const; + template + void operator<<= (const _Expr<_Dom, _Tp>&) const; + template + void operator>>= (const _Expr<_Dom, _Tp>&) const; + +private: + indirect_array (const indirect_array&); + indirect_array (_Array<_Tp>, size_t, _Array); + + friend class valarray<_Tp>; + friend class gslice_array<_Tp>; + + const size_t _M_sz; + const _Array _M_index; + const _Array<_Tp> _M_array; + + // not implemented + indirect_array (); + indirect_array& operator= (const indirect_array&); +}; + +template +inline indirect_array<_Tp>::indirect_array(const indirect_array<_Tp>& __a) + : _M_sz (__a._M_sz), _M_index (__a._M_index), + _M_array (__a._M_array) {} + +template +inline +indirect_array<_Tp>::indirect_array (_Array<_Tp> __a, size_t __s, + _Array __i) + : _M_sz (__s), _M_index (__i), _M_array (__a) {} + + +template +inline void +indirect_array<_Tp>::operator= (const _Tp& __t) +{ __valarray_fill(_M_array, _M_index, _M_sz, __t); } + +template +inline void +indirect_array<_Tp>::operator= (const valarray<_Tp>& __v) const +{ __valarray_copy (_Array<_Tp> (__v), _M_sz, _M_array, _M_index); } + +template +template +inline void +indirect_array<_Tp>::operator= (const _Expr<_Dom,_Tp>& __e) const +{ __valarray_copy (__e, _M_sz, _M_array, _M_index); } + +#undef _DEFINE_VALARRAY_OPERATOR +#define _DEFINE_VALARRAY_OPERATOR(op, name) \ +template \ +inline void \ +indirect_array<_Tp>::operator##op##= (const valarray<_Tp>& __v) const \ +{ \ + _Array_augmented_##name (_M_array, _M_index, _Array<_Tp> (__v), _M_sz); \ +} \ + \ +template template \ +inline void \ +indirect_array<_Tp>::operator##op##= (const _Expr<_Dom,_Tp>& __e) const \ +{ \ + _Array_augmented_##name (_M_array, _M_index, __e, _M_sz); \ +} + +_DEFINE_VALARRAY_OPERATOR(*, multiplies) +_DEFINE_VALARRAY_OPERATOR(/, divides) +_DEFINE_VALARRAY_OPERATOR(%, modulus) +_DEFINE_VALARRAY_OPERATOR(+, plus) +_DEFINE_VALARRAY_OPERATOR(-, minus) +_DEFINE_VALARRAY_OPERATOR(^, xor) +_DEFINE_VALARRAY_OPERATOR(&, and) +_DEFINE_VALARRAY_OPERATOR(|, or) +_DEFINE_VALARRAY_OPERATOR(<<, shift_left) +_DEFINE_VALARRAY_OPERATOR(>>, shift_right) + +#undef _DEFINE_VALARRAY_OPERATOR + +} // extern "C++" + +#endif // __INDIRECT_ARRAY__ + +// Local Variables: +// mode:c++ +// End: diff --git a/headers/cpp/std/ldcomplex.h b/headers/cpp/std/ldcomplex.h new file mode 100644 index 0000000000..bc91fa422b --- /dev/null +++ b/headers/cpp/std/ldcomplex.h @@ -0,0 +1,95 @@ +// The -*- C++ -*- long_double_complex class. +// Copyright (C) 1994 Free Software Foundation + +// This file is part of the GNU ANSI C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// As a special exception, if you link this library with files +// compiled with a GNU compiler to produce an executable, this does not cause +// the resulting executable to be covered by the GNU General Public License. +// This exception does not however invalidate any other reasons why +// the executable file might be covered by the GNU General Public License. + +// Written by Jason Merrill based upon the specification in the 27 May 1994 +// C++ working paper, ANSI document X3J16/94-0098. + +#ifndef __LDCOMPLEX__ +#define __LDCOMPLEX__ + +#ifdef __GNUG__ +#pragma interface "ldcomplex" +#endif + +extern "C++" { +class complex +{ +public: + complex (long double r = 0, long double i = 0): re (r), im (i) { } + complex (const complex& r): re (r.real ()), im (r.imag ()) { } + complex (const complex& r): re (r.real ()), im (r.imag ()) { } + + complex& operator+= (const complex& r) { return __doapl (this, r); } + complex& operator-= (const complex& r) { return __doami (this, r); } + complex& operator*= (const complex& r) { return __doaml (this, r); } + complex& operator/= (const complex& r) { return __doadv (this, r); } + + long double real () const { return re; } + long double imag () const { return im; } +private: + long double re, im; + + friend complex& __doapl<> (complex *, const complex&); + friend complex& __doami<> (complex *, const complex&); + friend complex& __doaml<> (complex *, const complex&); + friend complex& __doadv<> (complex *, const complex&); + +#ifndef __STRICT_ANSI__ + friend inline complex operator + (const complex& x, long double y) + { return operator+<> (x, y); } + friend inline complex operator + (long double x, const complex& y) + { return operator+<> (x, y); } + friend inline complex operator - (const complex& x, long double y) + { return operator-<> (x, y); } + friend inline complex operator - (long double x, const complex& y) + { return operator-<> (x, y); } + friend inline complex operator * (const complex& x, long double y) + { return operator*<> (x, y); } + friend inline complex operator * (long double x, const complex& y) + { return operator*<> (x, y); } + friend inline complex operator / (const complex& x, long double y) + { return operator/<> (x, y); } + friend inline complex operator / (long double x, const complex& y) + { return operator/<> (x, y); } + friend inline bool operator == (const complex& x, long double y) + { return operator==<> (x, y); } + friend inline bool operator == (long double x, const complex& y) + { return operator==<> (x, y); } + friend inline bool operator != (const complex& x, long double y) + { return operator!=<> (x, y); } + friend inline bool operator != (long double x, const complex& y) + { return operator!=<> (x, y); } +#endif /* __STRICT_ANSI__ */ +}; + +inline complex::complex (const complex& r) +: re (r.real ()), im (r.imag ()) +{ } + +inline complex::complex (const complex& r) +: re (r.real ()), im (r.imag ()) +{ } +} // extern "C++" + +#endif diff --git a/headers/cpp/std/mask_array.h b/headers/cpp/std/mask_array.h new file mode 100644 index 0000000000..d431be4e97 --- /dev/null +++ b/headers/cpp/std/mask_array.h @@ -0,0 +1,154 @@ +// The template and inlines for the -*- C++ -*- mask_array class. + +// Copyright (C) 1997-1999 Cygnus Solutions +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis + +#ifndef __MASK_ARRAY__ +#define __MASK_ARRAY__ + +extern "C++" { + +template class mask_array +{ +public: + typedef _T value_type; + + void operator= (const valarray<_T>&) const; + void operator*= (const valarray<_T>&) const; + void operator/= (const valarray<_T>&) const; + void operator%= (const valarray<_T>&) const; + void operator+= (const valarray<_T>&) const; + void operator-= (const valarray<_T>&) const; + void operator^= (const valarray<_T>&) const; + void operator&= (const valarray<_T>&) const; + void operator|= (const valarray<_T>&) const; + void operator<<=(const valarray<_T>&) const; + void operator>>=(const valarray<_T>&) const; + void operator= (const _T&); + + template + void operator= (const _Expr<_Dom,_T>&) const; + template + void operator*= (const _Expr<_Dom,_T>&) const; + template + void operator/= (const _Expr<_Dom,_T>&) const; + template + void operator%= (const _Expr<_Dom,_T>&) const; + template + void operator+= (const _Expr<_Dom,_T>&) const; + template + void operator-= (const _Expr<_Dom,_T>&) const; + template + void operator^= (const _Expr<_Dom,_T>&) const; + template + void operator&= (const _Expr<_Dom,_T>&) const; + template + void operator|= (const _Expr<_Dom,_T>&) const; + template + void operator<<=(const _Expr<_Dom,_T>&) const; + template + void operator>>=(const _Expr<_Dom,_T>&) const; + +private: + mask_array (_Array<_T>, size_t, _Array); + friend class valarray<_T>; + + const size_t _M_sz; + const _Array _M_mask; + const _Array<_T> _M_array; + + mask_array (const mask_array&); + + // not implemented + mask_array (); + mask_array& operator= (const mask_array&); +}; + +template +inline mask_array<_Tp>::mask_array (const mask_array<_Tp>& a) + : _M_sz (a._M_sz), _M_mask (a._M_mask), _M_array (a._M_array) {} + +template +inline +mask_array<_T>::mask_array (_Array<_T> __a, size_t __s, _Array __m) + : _M_sz (__s), _M_mask (__m), _M_array (__a) {} + +template +inline void +mask_array<_T>::operator= (const _T& __t) +{ __valarray_fill (_M_array, _M_sz, _M_mask, __t); } + +template +inline void +mask_array<_T>::operator= (const valarray<_T>& __v) const +{ __valarray_copy (_Array<_T> (__v), __v.size (), _M_array, _M_mask); } + +template +template +inline void +mask_array<_T>::operator= (const _Expr& __e) const +{ __valarray_copy (__e, __e.size (), _M_array, _M_mask); } + +#undef _DEFINE_VALARRAY_OPERATOR +#define _DEFINE_VALARRAY_OPERATOR(op, name) \ +template \ +inline void \ +mask_array<_T>::operator##op##= (const valarray<_T>& __v) const \ +{ \ + _Array_augmented_##name (_M_array, _M_mask, \ + _Array<_T> (__v), __v.size ()); \ +} \ + \ +template template \ +inline void \ +mask_array<_T>::operator##op##= (const _Expr& __e) const \ +{ \ + _Array_augmented_##name (_M_array, _M_mask, __e, __e.size ()); \ +} + +_DEFINE_VALARRAY_OPERATOR(*, multiplies) +_DEFINE_VALARRAY_OPERATOR(/, divides) +_DEFINE_VALARRAY_OPERATOR(%, modulus) +_DEFINE_VALARRAY_OPERATOR(+, plus) +_DEFINE_VALARRAY_OPERATOR(-, minus) +_DEFINE_VALARRAY_OPERATOR(^, xor) +_DEFINE_VALARRAY_OPERATOR(&, and) +_DEFINE_VALARRAY_OPERATOR(|, or) +_DEFINE_VALARRAY_OPERATOR(<<, shift_left) +_DEFINE_VALARRAY_OPERATOR(>>, shift_right) + +#undef _DEFINE_VALARRAY_OPERATOR + +} // extern "C++" + +#endif // __MASK_ARRAY__ + +// Local Variables: +// mode:c++ +// End: diff --git a/headers/cpp/std/slice.h b/headers/cpp/std/slice.h new file mode 100644 index 0000000000..cf2fb283de --- /dev/null +++ b/headers/cpp/std/slice.h @@ -0,0 +1,76 @@ +// The template and inlines for the -*- C++ -*- slice class. + +// Copyright (C) 1997-1999 Cygnus Solutions +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis + +#ifndef __SLICE__ +#define __SLICE__ + +extern "C++" { + +class slice +{ +public: + slice (); + slice (size_t, size_t, size_t); + + size_t start () const; + size_t size () const; + size_t stride () const; + +private: + size_t _M_off; // offset + size_t _M_sz; // size + size_t _M_st; // stride unit +}; + +inline slice::slice () {} + +inline slice::slice (size_t __o, size_t __d, size_t __s) + : _M_off (__o), _M_sz (__d), _M_st (__s) {} + +inline size_t +slice::start () const + { return _M_off; } + +inline size_t +slice::size () const + { return _M_sz; } + +inline size_t +slice::stride () const + { return _M_st; } + +} // extern "C++" + +#endif // __SLICE__ + +// Local Variables: +// mode:c++ +// End: diff --git a/headers/cpp/std/slice_array.h b/headers/cpp/std/slice_array.h new file mode 100644 index 0000000000..dc1aa34d35 --- /dev/null +++ b/headers/cpp/std/slice_array.h @@ -0,0 +1,156 @@ +// The template and inlines for the -*- C++ -*- slice_array class. + +// Copyright (C) 1997-1999 Cygnus Solutions +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis + +#ifndef __SLICE_ARRAY__ +#define __SLICE_ARRAY__ + +extern "C++" { + +template +class slice_array +{ +public: + typedef _T value_type; + + void operator= (const valarray<_T>&) const; + void operator*= (const valarray<_T>&) const; + void operator/= (const valarray<_T>&) const; + void operator%= (const valarray<_T>&) const; + void operator+= (const valarray<_T>&) const; + void operator-= (const valarray<_T>&) const; + void operator^= (const valarray<_T>&) const; + void operator&= (const valarray<_T>&) const; + void operator|= (const valarray<_T>&) const; + void operator<<= (const valarray<_T>&) const; + void operator>>= (const valarray<_T>&) const; + void operator= (const _T &); + + template + void operator= (const _Expr<_Dom,_T>&) const; + template + void operator*= (const _Expr<_Dom,_T>&) const; + template + void operator/= (const _Expr<_Dom,_T>&) const; + template + void operator%= (const _Expr<_Dom,_T>&) const; + template + void operator+= (const _Expr<_Dom,_T>&) const; + template + void operator-= (const _Expr<_Dom,_T>&) const; + template + void operator^= (const _Expr<_Dom,_T>&) const; + template + void operator&= (const _Expr<_Dom,_T>&) const; + template + void operator|= (const _Expr<_Dom,_T>&) const; + template + void operator<<= (const _Expr<_Dom,_T>&) const; + template + void operator>>= (const _Expr<_Dom,_T>&) const; + +private: + friend class valarray<_T>; + slice_array(_Array<_T>, const slice&); + + const size_t _M_sz; + const size_t _M_stride; + const _Array<_T> _M_array; + + // this constructor is implemented since we need to return a value. + slice_array (const slice_array&); + + // not implemented + slice_array (); + slice_array& operator= (const slice_array&); +}; + +template +inline slice_array<_T>::slice_array (_Array<_T> __a, const slice& __s) + : _M_sz (__s.size ()), _M_stride (__s.stride ()), + _M_array (__a.begin () + __s.start ()) {} + +template +inline slice_array<_Tp>::slice_array(const slice_array<_Tp>& a) + : _M_sz(a._M_sz), _M_stride(a._M_stride), _M_array(a._M_array) {} + +template +inline void +slice_array<_T>::operator= (const _T& __t) +{ __valarray_fill (_M_array, _M_sz, _M_stride, __t); } + +template +inline void +slice_array<_T>::operator= (const valarray<_T>& __v) const +{ __valarray_copy (_Array<_T> (__v), _M_array, _M_sz, _M_stride); } + +template +template +inline void +slice_array<_T>::operator= (const _Expr<_Dom,_T>& __e) const +{ __valarray_copy (__e, _M_sz, _M_array, _M_stride); } + +#undef _DEFINE_VALARRAY_OPERATOR +#define _DEFINE_VALARRAY_OPERATOR(op, name) \ +template \ +inline void \ +slice_array<_T>::operator##op##= (const valarray<_T>& __v) const \ +{ \ + _Array_augmented_##name (_M_array, _M_sz, _M_stride, _Array<_T> (__v));\ +} \ + \ +template template \ +inline void \ +slice_array<_T>::operator##op##= (const _Expr<_Dom,_T>& __e) const \ +{ \ + _Array_augmented_##name (_M_array, _M_stride, __e, _M_sz); \ +} + + +_DEFINE_VALARRAY_OPERATOR(*, multiplies) +_DEFINE_VALARRAY_OPERATOR(/, divides) +_DEFINE_VALARRAY_OPERATOR(%, modulus) +_DEFINE_VALARRAY_OPERATOR(+, plus) +_DEFINE_VALARRAY_OPERATOR(-, minus) +_DEFINE_VALARRAY_OPERATOR(^, xor) +_DEFINE_VALARRAY_OPERATOR(&, and) +_DEFINE_VALARRAY_OPERATOR(|, or) +_DEFINE_VALARRAY_OPERATOR(<<, shift_left) +_DEFINE_VALARRAY_OPERATOR(>>, shift_right) + +#undef _DEFINE_VALARRAY_OPERATOR + +} // extern "C++" + +#endif // __SLICE_ARRAY__ + +// Local Variables: +// mode:c++ +// End: diff --git a/headers/cpp/std/std_valarray.h b/headers/cpp/std/std_valarray.h new file mode 100644 index 0000000000..b300655554 --- /dev/null +++ b/headers/cpp/std/std_valarray.h @@ -0,0 +1,728 @@ +// The template and inlines for the -*- C++ -*- valarray class. + +// Copyright (C) 1997-1999 Cygnus Solutions +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis + +#ifndef __STD_VALARRAY__ +#define __STD_VALARRAY__ +#define _G_NO_VALARRAY_TEMPLATE_EXPORT 1 + +#include +#include +#include +#include +#include +#include + +#ifndef alloca +#ifdef __GNUC__ +#define alloca __builtin_alloca +#else /* not GNU C. */ +#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) +#include +#else /* not sparc */ +#if defined (MSDOS) && !defined (__TURBOC__) +#include +#else /* not MSDOS, or __TURBOC__ */ +#if defined(_AIX) +#include + #pragma alloca +#else /* not MSDOS, __TURBOC__, or _AIX */ +#ifdef __hpux +#endif /* __hpux */ +#endif /* not _AIX */ +#endif /* not MSDOS, or __TURBOC__ */ +#endif /* not sparc. */ +#endif /* not GNU C. */ +#endif /* alloca not defined. */ + +extern "C" { + void* alloca(size_t); +} + + +extern "C++" { + +template class _Expr; + +template class _ValArray; + +template class _Oper, + template class _Meta, class _Dom> struct _UnClos; + +template class _Oper, + template class _Meta1, + template class _Meta2, + class _Dom1, class _Dom2> class _BinClos; + +template class _Meta, class _Dom> class _SClos; + +template class _Meta, class _Dom> class _GClos; + +template class _Meta, class _Dom> class _IClos; + +template class _Meta, class _Dom> class _ValFunClos; + +template class _Meta, class _Dom> class _RefFunClos; + +template struct _Unary_plus; +template struct _Bitwise_and; +template struct _Bitwise_or; +template struct _Bitwise_xor; +template struct _Bitwise_not; +template struct _Shift_left; +template struct _Shift_right; + +template class valarray; // An array of type _Tp +class slice; // BLAS-like slice out of an array +template class slice_array; +class gslice; // generalized slice out of an array +template class gslice_array; +template class mask_array; // masked array +template class indirect_array; // indirected array + +} // extern "C++" + +#include +#include + +extern "C++" { + +template class valarray +{ +public: + typedef _Tp value_type; + + // _lib.valarray.cons_ construct/destroy: + valarray(); + explicit valarray(size_t); + valarray(const _Tp&, size_t); + valarray(const _Tp* __restrict__, size_t); + valarray(const valarray&); + valarray(const slice_array<_Tp>&); + valarray(const gslice_array<_Tp>&); + valarray(const mask_array<_Tp>&); + valarray(const indirect_array<_Tp>&); + template + valarray(const _Expr<_Dom,_Tp>& __e); + ~valarray(); + + // _lib.valarray.assign_ assignment: + valarray<_Tp>& operator=(const valarray<_Tp>&); + valarray<_Tp>& operator=(const _Tp&); + valarray<_Tp>& operator=(const slice_array<_Tp>&); + valarray<_Tp>& operator=(const gslice_array<_Tp>&); + valarray<_Tp>& operator=(const mask_array<_Tp>&); + valarray<_Tp>& operator=(const indirect_array<_Tp>&); + + template valarray<_Tp>& + operator= (const _Expr<_Dom,_Tp>&); + + // _lib.valarray.access_ element access: + _Tp operator[](size_t) const; + _Tp& operator[](size_t); + // _lib.valarray.sub_ subset operations: + _Expr<_SClos<_ValArray,_Tp>, _Tp> operator[](slice) const; + slice_array<_Tp> operator[](slice); + _Expr<_GClos<_ValArray,_Tp>, _Tp> operator[](const gslice&) const; + gslice_array<_Tp> operator[](const gslice&); + valarray<_Tp> operator[](const valarray&) const; + mask_array<_Tp> operator[](const valarray&); + _Expr<_IClos<_ValArray, _Tp>, _Tp> + operator[](const valarray&) const; + indirect_array<_Tp> operator[](const valarray&); + + // _lib.valarray.unary_ unary operators: + _Expr<_UnClos<_Unary_plus,_ValArray,_Tp>,_Tp> operator+ () const; + _Expr<_UnClos,_Tp> operator- () const; + _Expr<_UnClos<_Bitwise_not,_ValArray,_Tp>,_Tp> operator~ () const; + _Expr<_UnClos,bool> operator! () const; + + // _lib.valarray.cassign_ computed assignment: + valarray<_Tp>& operator*= (const _Tp&); + valarray<_Tp>& operator/= (const _Tp&); + valarray<_Tp>& operator%= (const _Tp&); + valarray<_Tp>& operator+= (const _Tp&); + valarray<_Tp>& operator-= (const _Tp&); + valarray<_Tp>& operator^= (const _Tp&); + valarray<_Tp>& operator&= (const _Tp&); + valarray<_Tp>& operator|= (const _Tp&); + valarray<_Tp>& operator<<=(const _Tp&); + valarray<_Tp>& operator>>=(const _Tp&); + valarray<_Tp>& operator*= (const valarray<_Tp>&); + valarray<_Tp>& operator/= (const valarray<_Tp>&); + valarray<_Tp>& operator%= (const valarray<_Tp>&); + valarray<_Tp>& operator+= (const valarray<_Tp>&); + valarray<_Tp>& operator-= (const valarray<_Tp>&); + valarray<_Tp>& operator^= (const valarray<_Tp>&); + valarray<_Tp>& operator|= (const valarray<_Tp>&); + valarray<_Tp>& operator&= (const valarray<_Tp>&); + valarray<_Tp>& operator<<=(const valarray<_Tp>&); + valarray<_Tp>& operator>>=(const valarray<_Tp>&); + + template + valarray<_Tp>& operator*= (const _Expr<_Dom,_Tp>&); + template + valarray<_Tp>& operator/= (const _Expr<_Dom,_Tp>&); + template + valarray<_Tp>& operator%= (const _Expr<_Dom,_Tp>&); + template + valarray<_Tp>& operator+= (const _Expr<_Dom,_Tp>&); + template + valarray<_Tp>& operator-= (const _Expr<_Dom,_Tp>&); + template + valarray<_Tp>& operator^= (const _Expr<_Dom,_Tp>&); + template + valarray<_Tp>& operator|= (const _Expr<_Dom,_Tp>&); + template + valarray<_Tp>& operator&= (const _Expr<_Dom,_Tp>&); + template + valarray<_Tp>& operator<<=(const _Expr<_Dom,_Tp>&); + template + valarray<_Tp>& operator>>=(const _Expr<_Dom,_Tp>&); + + + // _lib.valarray.members_ member functions: + size_t size() const; + _Tp sum() const; + _Tp min() const; + _Tp max() const; + + // FIXME: Extension + _Tp product () const; + + valarray<_Tp> shift (int) const; + valarray<_Tp> cshift(int) const; + _Expr<_ValFunClos<_ValArray,_Tp>,_Tp> apply(_Tp func(_Tp)) const; + _Expr<_RefFunClos<_ValArray,_Tp>,_Tp> apply(_Tp func(const _Tp&)) const; + void resize(size_t __size, _Tp __c = _Tp()); + +private: + size_t _M_size; + _Tp* __restrict__ _M_data; + + friend class _Array<_Tp>; +}; + + +template struct _Unary_plus : unary_function<_Tp,_Tp> { + _Tp operator() (const _Tp& __t) const { return __t; } +}; + +template struct _Bitwise_and : binary_function<_Tp,_Tp,_Tp> { + _Tp operator() (_Tp __x, _Tp __y) const { return __x & __y; } +}; + +template struct _Bitwise_or : binary_function<_Tp,_Tp,_Tp> { + _Tp operator() (_Tp __x, _Tp __y) const { return __x | __y; } +}; + +template struct _Bitwise_xor : binary_function<_Tp,_Tp,_Tp> { + _Tp operator() (_Tp __x, _Tp __y) const { return __x ^ __y; } +}; + +template struct _Bitwise_not : unary_function<_Tp,_Tp> { + _Tp operator() (_Tp __t) const { return ~__t; } +}; + +template struct _Shift_left : unary_function<_Tp,_Tp> { + _Tp operator() (_Tp __x, _Tp __y) const { return __x << __y; } +}; + +template struct _Shift_right : unary_function<_Tp,_Tp> { + _Tp operator() (_Tp __x, _Tp __y) const { return __x >> __y; } +}; + + +template +inline _Tp +valarray<_Tp>::operator[] (size_t __i) const +{ return _M_data[__i]; } + +template +inline _Tp& +valarray<_Tp>::operator[] (size_t __i) +{ return _M_data[__i]; } + +} // extern "C++" + +#include +#include +#include +#include +#include +#include + +extern "C++" { + +template +inline valarray<_Tp>::valarray () : _M_size (0), _M_data (0) {} + +template +inline valarray<_Tp>::valarray (size_t __n) + : _M_size (__n), _M_data (new _Tp[__n]) {} + +template +inline valarray<_Tp>::valarray (const _Tp& __t, size_t __n) + : _M_size (__n), _M_data (new _Tp[__n]) +{ __valarray_fill (_M_data, _M_size, __t); } + +template +inline valarray<_Tp>::valarray (const _Tp* __restrict__ __pT, size_t __n) + : _M_size (__n), _M_data (new _Tp[__n]) +{ __valarray_copy (__pT, __n, _M_data); } + +template +inline valarray<_Tp>::valarray (const valarray<_Tp>& __v) + : _M_size (__v._M_size), _M_data (new _Tp[__v._M_size]) +{ __valarray_copy (__v._M_data, _M_size, _M_data); } + +template +inline valarray<_Tp>::valarray (const slice_array<_Tp>& __sa) + : _M_size (__sa._M_sz), _M_data (new _Tp[__sa._M_sz]) +{ __valarray_copy (__sa._M_array, __sa._M_sz, __sa._M_stride, + _Array<_Tp>(_M_data)); } + +template +inline valarray<_Tp>::valarray (const gslice_array<_Tp>& __ga) + : _M_size (__ga._M_index.size()), _M_data (new _Tp[_M_size]) +{ __valarray_copy (__ga._M_array, _Array(__ga._M_index), + _Array<_Tp>(_M_data), _M_size); } + +template +inline valarray<_Tp>::valarray (const mask_array<_Tp>& __ma) + : _M_size (__ma._M_sz), _M_data (new _Tp[__ma._M_sz]) +{ __valarray_copy (__ma._M_array, __ma._M_mask, + _Array<_Tp>(_M_data), _M_size); } + +template +inline valarray<_Tp>::valarray (const indirect_array<_Tp>& __ia) + : _M_size (__ia._M_sz), _M_data (new _Tp[__ia._M_sz]) +{ __valarray_copy (__ia._M_array, __ia._M_index, + _Array<_Tp>(_M_data), _M_size); } + +template template +inline valarray<_Tp>::valarray (const _Expr<_Dom, _Tp>& __e) + : _M_size (__e.size ()), _M_data (new _Tp[_M_size]) +{ __valarray_copy (__e, _M_size, _Array<_Tp>(_M_data)); } + +template +inline valarray<_Tp>::~valarray () { delete[] _M_data; } + +template +inline valarray<_Tp>& +valarray<_Tp>::operator= (const valarray<_Tp>& __v) +{ + __valarray_copy(__v._M_data, _M_size, _M_data); + return *this; +} + +template +inline valarray<_Tp>& +valarray<_Tp>::operator= (const _Tp& __t) +{ + __valarray_fill (_M_data, _M_size, __t); + return *this; +} + +template +inline valarray<_Tp>& +valarray<_Tp>::operator= (const slice_array<_Tp>& __sa) +{ + __valarray_copy (__sa._M_array, __sa._M_sz, + __sa._M_stride, _Array<_Tp>(_M_data)); + return *this; +} + +template +inline valarray<_Tp>& +valarray<_Tp>::operator= (const gslice_array<_Tp>& __ga) +{ + __valarray_copy (__ga._M_array, _Array(__ga._M_index), + _Array<_Tp>(_M_data), _M_size); + return *this; +} + +template +inline valarray<_Tp>& +valarray<_Tp>::operator= (const mask_array<_Tp>& __ma) +{ + __valarray_copy (__ma._M_array, __ma._M_mask, + _Array<_Tp>(_M_data), _M_size); + return *this; +} + +template +inline valarray<_Tp>& +valarray<_Tp>::operator= (const indirect_array<_Tp>& __ia) +{ + __valarray_copy (__ia._M_array, __ia._M_index, + _Array<_Tp>(_M_data), _M_size); + return *this; +} + +template template +inline valarray<_Tp>& +valarray<_Tp>::operator= (const _Expr<_Dom, _Tp>& __e) +{ + __valarray_copy (__e, _M_size, _Array<_Tp>(_M_data)); + return *this; +} + +template +inline _Expr<_SClos<_ValArray,_Tp>, _Tp> +valarray<_Tp>::operator[] (slice __s) const +{ + typedef _SClos<_ValArray,_Tp> _Closure; + return _Expr<_Closure, _Tp> (_Closure (_Array<_Tp>(_M_data), __s)); +} + +template +inline slice_array<_Tp> +valarray<_Tp>::operator[] (slice __s) +{ + return slice_array<_Tp> (_Array<_Tp>(_M_data), __s); +} + +template +inline _Expr<_GClos<_ValArray,_Tp>, _Tp> +valarray<_Tp>::operator[] (const gslice& __gs) const +{ + typedef _GClos<_ValArray,_Tp> _Closure; + return _Expr<_Closure, _Tp> + (_Closure (_Array<_Tp>(_M_data), __gs._M_index->_M_index)); +} + +template +inline gslice_array<_Tp> +valarray<_Tp>::operator[] (const gslice& __gs) +{ + return gslice_array<_Tp> + (_Array<_Tp>(_M_data), __gs._M_index->_M_index); +} + +template +inline valarray<_Tp> +valarray<_Tp>::operator[] (const valarray& __m) const +{ + size_t __s (0); + size_t __e (__m.size ()); + for (size_t __i=0; __i<__e; ++__i) + if (__m[__i]) ++__s; + return valarray<_Tp> (mask_array<_Tp> (_Array<_Tp>(_M_data), __s, + _Array (__m))); +} + +template +inline mask_array<_Tp> +valarray<_Tp>::operator[] (const valarray& __m) +{ + size_t __s (0); + size_t __e (__m.size ()); + for (size_t __i=0; __i<__e; ++__i) + if (__m[__i]) ++__s; + return mask_array<_Tp> (_Array<_Tp>(_M_data), __s, _Array (__m)); +} + +template +inline _Expr<_IClos<_ValArray,_Tp>, _Tp> +valarray<_Tp>::operator[] (const valarray& __i) const +{ + typedef _IClos<_ValArray,_Tp> _Closure; + return _Expr<_Closure, _Tp> (_Closure (*this, __i)); +} + +template +inline indirect_array<_Tp> +valarray<_Tp>::operator[] (const valarray& __i) +{ + return indirect_array<_Tp> (_Array<_Tp>(_M_data), __i.size(), + _Array (__i)); +} + +template +inline size_t valarray<_Tp>::size () const { return _M_size; } + +template +inline _Tp +valarray<_Tp>::sum () const +{ + return accumulate (_M_data, _M_data + _M_size, _Tp ()); +} + +template +inline _Tp +valarray<_Tp>::product () const +{ + return accumulate (_M_data, _M_data+_M_size, _Tp(1), multiplies<_Tp> ()); +} + +template +inline valarray<_Tp> +valarray<_Tp>::shift (int __n) const +{ + _Tp* const __a = static_cast<_Tp*> (alloca (sizeof(_Tp) * _M_size)); + if (! __n) // __n == 0: no shift + __valarray_copy (_M_data, _M_size, __a); + else if (__n > 0) { // __n > 0: shift left + if (__n > _M_size) + __valarray_fill(__a, __n, _Tp()); + else { + __valarray_copy (_M_data+__n, _M_size-__n, __a); + __valarray_fill (__a+_M_size-__n, __n, _Tp()); + } + } + else { // __n < 0: shift right + __valarray_copy (_M_data, _M_size+__n, __a-__n); + __valarray_fill(__a, -__n, _Tp()); + } + return valarray<_Tp> (__a, _M_size); +} + +template +inline valarray<_Tp> +valarray<_Tp>::cshift (int __n) const +{ + _Tp* const __a = static_cast<_Tp*> (alloca (sizeof(_Tp) * _M_size)); + if (! __n) // __n == 0: no cshift + __valarray_copy(_M_data, _M_size, __a); + else if (__n > 0) { // __n > 0: cshift left + __valarray_copy (_M_data, __n, __a + _M_size-__n); + __valarray_copy (_M_data + __n, _M_size-__n, __a); + } + else { // __n < 0: cshift right + __valarray_copy (_M_data + _M_size + __n, -__n, __a); + __valarray_copy (_M_data, _M_size + __n, __a - __n); + } + return valarray<_Tp> (__a, _M_size); +} + +template +inline void +valarray<_Tp>::resize (size_t __n, _Tp __c) +{ + if (_M_size != __n) { + delete[] _M_data; + _M_size = __n; + _M_data = new _Tp[_M_size]; + } + __valarray_fill (_M_data, _M_size, __c); +} + +template +inline _Tp +valarray<_Tp>::min() const +{ + return *min_element (_M_data, _M_data+_M_size); +} + +template +inline _Tp +valarray<_Tp>::max() const +{ + return *max_element (_M_data, _M_data+_M_size); +} + +template +inline _Expr<_ValFunClos<_ValArray,_Tp>,_Tp> +valarray<_Tp>::apply (_Tp func (_Tp)) const +{ + typedef _ValFunClos<_ValArray,_Tp> _Closure; + return _Expr<_Closure,_Tp> (_Closure (*this, func)); +} + +template +inline _Expr<_RefFunClos<_ValArray,_Tp>,_Tp> +valarray<_Tp>::apply (_Tp func (const _Tp &)) const +{ + typedef _RefFunClos<_ValArray,_Tp> _Closure; + return _Expr<_Closure,_Tp> (_Closure (*this, func)); +} + +#define _DEFINE_VALARRAY_UNARY_OPERATOR(_Op, _Name) \ + template \ + inline _Expr<_UnClos<_Name,_ValArray,_Tp>, _Tp> \ + valarray<_Tp>::operator##_Op() const \ + { \ + typedef _UnClos<_Name,_ValArray,_Tp> _Closure; \ + return _Expr<_Closure, _Tp> (_Closure (*this)); \ + } + + _DEFINE_VALARRAY_UNARY_OPERATOR(+, _Unary_plus) + _DEFINE_VALARRAY_UNARY_OPERATOR(-, negate) + _DEFINE_VALARRAY_UNARY_OPERATOR(~, _Bitwise_not) + +#undef _DEFINE_VALARRAY_UNARY_OPERATOR + + template + inline _Expr<_UnClos, bool> + valarray<_Tp>::operator!() const + { + typedef _UnClos _Closure; + return _Expr<_Closure, bool> (_Closure (*this)); + } + +#define _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(_Op, _Name) \ + template \ + inline valarray<_Tp> & \ + valarray<_Tp>::operator##_Op##= (const _Tp &__t) \ + { \ + _Array_augmented_##_Name (_Array<_Tp>(_M_data), _M_size, __t); \ + return *this; \ + } \ + \ + template \ + inline valarray<_Tp> & \ + valarray<_Tp>::operator##_Op##= (const valarray<_Tp> &__v) \ + { \ + _Array_augmented_##_Name (_Array<_Tp>(_M_data), _M_size, \ + _Array<_Tp>(__v._M_data)); \ + return *this; \ + } + +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(+, plus) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(-, minus) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(*, multiplies) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(/, divides) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(%, modulus) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(^, xor) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(&, and) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(|, or) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(<<, shift_left) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(>>, shift_right) + +#undef _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT + + +#define _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(_Op, _Name) \ + template template \ + inline valarray<_Tp> & \ + valarray<_Tp>::operator##_Op##= (const _Expr<_Dom,_Tp> &__e) \ + { \ + _Array_augmented_##_Name (_Array<_Tp>(_M_data), __e, _M_size); \ + return *this; \ + } + +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(+, plus) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(-, minus) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(*, multiplies) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(/, divides) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(%, modulus) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(^, xor) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(&, and) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(|, or) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(<<, shift_left) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(>>, shift_right) + +#undef _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT + + +#define _DEFINE_BINARY_OPERATOR(_Op, _Name) \ + template \ + inline _Expr<_BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp>, _Tp> \ + operator##_Op (const valarray<_Tp> &__v, const valarray<_Tp> &__w) \ + { \ + typedef _BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp> _Closure; \ + return _Expr<_Closure, _Tp> (_Closure (__v, __w)); \ + } \ + \ + template \ + inline _Expr<_BinClos<_Name,_ValArray,_Constant,_Tp,_Tp>,_Tp> \ + operator##_Op (const valarray<_Tp> &__v, const _Tp &__t) \ + { \ + typedef _BinClos<_Name,_ValArray,_Constant,_Tp,_Tp> _Closure; \ + return _Expr<_Closure, _Tp> (_Closure (__v, __t)); \ + } \ + \ + template \ + inline _Expr<_BinClos<_Name,_Constant,_ValArray,_Tp,_Tp>,_Tp> \ + operator##_Op (const _Tp &__t, const valarray<_Tp> &__v) \ + { \ + typedef _BinClos<_Name,_Constant,_ValArray,_Tp,_Tp> _Closure; \ + return _Expr<_Closure, _Tp> (_Closure (__t, __v)); \ + } + +_DEFINE_BINARY_OPERATOR(+, plus) +_DEFINE_BINARY_OPERATOR(-, minus) +_DEFINE_BINARY_OPERATOR(*, multiplies) +_DEFINE_BINARY_OPERATOR(/, divides) +_DEFINE_BINARY_OPERATOR(%, modulus) +_DEFINE_BINARY_OPERATOR(^, _Bitwise_xor) +_DEFINE_BINARY_OPERATOR(&, _Bitwise_and) +_DEFINE_BINARY_OPERATOR(|, _Bitwise_or) +_DEFINE_BINARY_OPERATOR(<<, _Shift_left) +_DEFINE_BINARY_OPERATOR(>>, _Shift_right) + +#undef _DEFINE_BINARY_OPERATOR + +#define _DEFINE_LOGICAL_OPERATOR(_Op, _Name) \ + template \ + inline _Expr<_BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp>,bool> \ + operator##_Op (const valarray<_Tp> &__v, const valarray<_Tp> &__w) \ + { \ + typedef _BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp> _Closure; \ + return _Expr<_Closure, bool> (_Closure (__v, __w)); \ + } \ + \ + template \ + inline _Expr<_BinClos<_Name,_ValArray,_Constant,_Tp,_Tp>,bool> \ + operator##_Op (const valarray<_Tp> &__v, const _Tp &__t) \ + { \ + typedef _BinClos<_Name,_ValArray,_Constant,_Tp,_Tp> _Closure; \ + return _Expr<_Closure, bool> (_Closure (__v, __t)); \ + } \ + \ + template \ + inline _Expr<_BinClos<_Name,_Constant,_ValArray,_Tp,_Tp>,bool> \ + operator##_Op (const _Tp &__t, const valarray<_Tp> &__v) \ + { \ + typedef _BinClos<_Name,_Constant,_ValArray,_Tp,_Tp> _Closure; \ + return _Expr<_Closure, bool> (_Closure (__t, __v)); \ + } + +_DEFINE_LOGICAL_OPERATOR(&&, logical_and) +_DEFINE_LOGICAL_OPERATOR(||, logical_or) +_DEFINE_LOGICAL_OPERATOR(==, equal_to) +_DEFINE_LOGICAL_OPERATOR(!=, not_equal_to) +_DEFINE_LOGICAL_OPERATOR(<, less) +_DEFINE_LOGICAL_OPERATOR(>, greater) +_DEFINE_LOGICAL_OPERATOR(<=, less_equal) +_DEFINE_LOGICAL_OPERATOR(>=, greater_equal) + +#undef _DEFINE_VALARRAY_OPERATOR + +#undef _G_NO_VALARRAY_TEMPLATE_EXPORT + +} // extern "C++" + +#endif // __STD_VALARRAY__ + +// Local Variables: +// mode:c++ +// End: diff --git a/headers/cpp/std/straits.h b/headers/cpp/std/straits.h new file mode 100644 index 0000000000..c80e7ab7a6 --- /dev/null +++ b/headers/cpp/std/straits.h @@ -0,0 +1,161 @@ +// Character traits template for the -*- C++ -*- string classes. +// Copyright (C) 1994 Free Software Foundation + +// This file is part of the GNU ANSI C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// As a special exception, if you link this library with files +// compiled with a GNU compiler to produce an executable, this does not cause +// the resulting executable to be covered by the GNU General Public License. +// This exception does not however invalidate any other reasons why +// the executable file might be covered by the GNU General Public License. + +// Written by Jason Merrill based upon the specification by Takanori Adachi +// in ANSI X3J16/94-0013R2. + +#ifndef __STRING_CHAR_TRAITS__ +#define __STRING_CHAR_TRAITS__ + +#ifdef __GNUG__ +// For string_char_traits +#pragma interface "std/straits.h" +#endif + +#include + +extern "C++" { +template +struct string_char_traits { + typedef charT char_type; // for users to acquire the basic character type + + // constraints + + static void assign (char_type& c1, const char_type& c2) + { c1 = c2; } + static bool eq (const char_type& c1, const char_type& c2) + { return (c1 == c2); } + static bool ne (const char_type& c1, const char_type& c2) + { return !(c1 == c2); } + static bool lt (const char_type& c1, const char_type& c2) + { return (c1 < c2); } + static char_type eos () { return char_type(); } // the null character + static bool is_del(char_type a) { return 0; } + // characteristic function for delimiters of charT + + // speed-up functions + + static int compare (const char_type* s1, const char_type* s2, size_t n) + { + size_t i; + for (i = 0; i < n; ++i) + if (ne (s1[i], s2[i])) + return lt (s1[i], s2[i]) ? -1 : 1; + + return 0; + } + + static size_t length (const char_type* s) + { + size_t l = 0; + while (ne (*s++, eos ())) + ++l; + return l; + } + + static char_type* copy (char_type* s1, const char_type* s2, size_t n) + { + for (; n--; ) + assign (s1[n], s2[n]); + return s1; + } + + static char_type* move (char_type* s1, const char_type* s2, size_t n) + { + char_type a[n]; + size_t i; + for (i = 0; i < n; ++i) + assign (a[i], s2[i]); + for (i = 0; i < n; ++i) + assign (s1[i], a[i]); + return s1; + } + + static char_type* set (char_type* s1, const char_type& c, size_t n) + { + for (; n--; ) + assign (s1[n], c); + return s1; + } +}; + +class istream; +class ostream; +#include +#include + +struct string_char_traits { + typedef char char_type; + + static void assign (char_type& c1, const char_type& c2) + { c1 = c2; } + static bool eq (const char_type & c1, const char_type& c2) + { return (c1 == c2); } + static bool ne (const char_type& c1, const char_type& c2) + { return (c1 != c2); } + static bool lt (const char_type& c1, const char_type& c2) + { return (c1 < c2); } + static char_type eos () { return 0; } + static bool is_del(char_type a) { return isspace(a); } + + static int compare (const char_type* s1, const char_type* s2, size_t n) + { return memcmp (s1, s2, n); } + static size_t length (const char_type* s) + { return strlen (s); } + static char_type* copy (char_type* s1, const char_type* s2, size_t n) + { return (char_type*) memcpy (s1, s2, n); } + static char_type* move (char_type* s1, const char_type* s2, size_t n) + { return (char_type*) memmove (s1, s2, n); } + static char_type* set (char_type* s1, const char_type& c, size_t n) + { return (char_type*) memset (s1, c, n); } +}; + +#if 0 +#include +struct string_char_traits { + typedef wchar_t char_type; + + static void assign (char_type& c1, const char_type& c2) + { c1 = c2; } + static bool eq (const char_type & c1, const char_type& c2) + { return (c1 == c2); } + static bool ne (const char_type& c1, const char_type& c2) + { return (c1 != c2); } + static bool lt (const char_type& c1, const char_type& c2) + { return (c1 < c2); } + static char_type eos () { return 0; } + static bool is_del(char_type a) { return iswspace(a); } + + static int compare (const char_type* s1, const char_type* s2, size_t n) + { return wmemcmp (s1, s2, n); } + static size_t length (const char_type* s) + { return wcslen (s); } + static char_type* copy (char_type* s1, const char_type* s2, size_t n) + { return wmemcpy (s1, s2, n); } + static char_type* set (char_type* s1, const char_type& c, size_t n) + { return wmemset (s1, c, n); } +}; +#endif +} // extern "C++" +#endif diff --git a/headers/cpp/std/valarray_array.h b/headers/cpp/std/valarray_array.h new file mode 100644 index 0000000000..a0b5818fd8 --- /dev/null +++ b/headers/cpp/std/valarray_array.h @@ -0,0 +1,346 @@ +// The template and inlines for the -*- C++ -*- internal _Array helper class. + +// Copyright (C) 1997-1999 Cygnus Solutions +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis + +#ifndef __VALARRAY_ARRAY__ +#define __VALARRAY_ARRAY__ + +#include +#include + +extern "C++" { + +// +// Helper functions on raw pointers +// + +// fill plain array __a[<__n>] with __t +template +inline void +__valarray_fill (_Tp* __restrict__ __a, size_t __n, const _Tp& __t) +{ while (__n--) *__a++ = __t; } + +// fill strided array __a[<__n-1 : __s>] with __t +template +inline void +__valarray_fill (_Tp* __restrict__ __a, size_t __n, + size_t __s, const _Tp& __t) +{ for (size_t __i=0; __i<__n; ++__i, __a+=__s) *__a = __t; } + +// fill indirect array __a[__i[<__n>]] with __i +template +inline void +__valarray_fill(_Tp* __restrict__ __a, const size_t* __restrict__ __i, + size_t __n, const _Tp& __t) +{ for (size_t __j=0; __j<__n; ++__j, ++__i) __a[*__i] = __t; } + +// copy plain array __a[<__n>] in __b[<__n>] +template +inline void +__valarray_copy (const _Tp* __restrict__ __a, size_t __n, + _Tp* __restrict__ __b) +{ memcpy (__b, __a, __n * sizeof(_Tp)); } + +// copy strided array __a[<__n : __s>] in plain __b[<__n>] +template +inline void +__valarray_copy (const _Tp* __restrict__ __a, size_t __n, size_t __s, + _Tp* __restrict__ __b) +{ for (size_t __i=0; __i<__n; ++__i, ++__b, __a += __s) *__b = *__a; } + +// copy plain __a[<__n>] in strided __b[<__n : __s>] +template +inline void +__valarray_copy (const _Tp* __restrict__ __a, _Tp* __restrict__ __b, + size_t __n, size_t __s) +{ for (size_t __i=0; __i<__n; ++__i, ++__a, __b+=__s) *__b = *__a; } + +// copy indexed __a[__i[<__n>]] in plain __b[<__n>] +template +inline void +__valarray_copy (const _Tp* __restrict__ __a, + const size_t* __restrict__ __i, + _Tp* __restrict__ __b, size_t __n) +{ for (size_t __j=0; __j<__n; ++__j, ++__b, ++__i) *__b = __a[*__i]; } + +// copy plain __a[<__n>] in indexed __b[__i[<__n>]] +template +inline void +__valarray_copy (const _Tp* __restrict__ __a, size_t __n, + _Tp* __restrict__ __b, const size_t* __restrict__ __i) +{ for (size_t __j=0; __j<__n; ++__j, ++__a, ++__i) __b[*__i] = *__a; } + +// +// Helper class _Array, first layer of valarray abstraction. +// All operations on valarray should be forwarded to this class +// whenever possible. -- gdr +// + +template struct _Array { + + explicit _Array (size_t); + explicit _Array (_Tp* const __restrict__); + explicit _Array (const valarray<_Tp>&); + _Array (const _Tp* __restrict__, size_t); + + void free_data() const; + _Tp* begin () const; + + _Tp* const __restrict__ _M_data; +}; + +template +inline void +__valarray_fill (_Array<_Tp> __a, size_t __n, const _Tp& __t) +{ __valarray_fill (__a._M_data, __n, __t); } + +template +inline void +__valarray_fill (_Array<_Tp> __a, size_t __n, size_t __s, const _Tp& __t) +{ __valarray_fill (__a._M_data, __n, __s, __t); } + +template +inline void +__valarray_fill (_Array<_Tp> __a, _Array __i, + size_t __n, const _Tp& __t) +{ __valarray_fill (__a._M_data, __i._M_data, __n, __t); } + +template +inline void +__valarray_copy (_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) +{ __valarray_copy (__a._M_data, __n, __b._M_data); } + +template +inline void +__valarray_copy (_Array<_Tp> __a, size_t __n, size_t __s, _Array<_Tp> __b) +{ __valarray_copy(__a._M_data, __n, __s, __b._M_data); } + +template +inline void +__valarray_copy (_Array<_Tp> __a, _Array<_Tp> __b, size_t __n, size_t __s) +{ __valarray_copy (__a._M_data, __b._M_data, __n, __s); } + +template +inline void +__valarray_copy (_Array<_Tp> __a, _Array __i, + _Array<_Tp> __b, size_t __n) +{ __valarray_copy (__a._M_data, __i._M_data, __b._M_data, __n); } + +template +inline void +__valarray_copy (_Array<_Tp> __a, size_t __n, _Array<_Tp> __b, + _Array __i) +{ __valarray_copy (__a._M_data, __n, __b._M_data, __i._M_data); } + +template +inline +_Array<_Tp>::_Array (size_t __n) : _M_data (new _Tp[__n]) {} + +template +inline +_Array<_Tp>::_Array (_Tp* const __restrict__ __p) : _M_data (__p) {} + +template +inline _Array<_Tp>::_Array (const valarray<_Tp>& __v) + : _M_data (__v._M_data) {} + +template +inline +_Array<_Tp>::_Array (const _Tp* __restrict__ __b, size_t __s) + : _M_data (new _Tp[__s]) { __valarray_copy (__b, __s, _M_data); } + +template +inline void +_Array<_Tp>::free_data() const { delete[] _M_data; } + +template +inline _Tp* +_Array<_Tp>::begin () const +{ return _M_data; } + +#define _DEFINE_ARRAY_FUNCTION(_Op, _Name) \ +template \ +inline void \ +_Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, const _Tp& __t) \ +{ \ + for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p) \ + *__p _Op##= __t; \ +} \ + \ +template \ +inline void \ +_Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) \ +{ \ + _Tp* __p (__a._M_data); \ + for (_Tp* __q=__b._M_data; __q<__b._M_data+__n; ++__p, ++__q) \ + *__p _Op##= *__q; \ +} \ + \ +template \ +void \ +_Array_augmented_##_Name (_Array<_Tp> __a, \ + const _Expr<_Dom,_Tp>& __e, size_t __n) \ +{ \ + _Tp* __p (__a._M_data); \ + for (size_t __i=0; __i<__n; ++__i, ++__p) *__p _Op##= __e[__i]; \ +} \ + \ +template \ +inline void \ +_Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, size_t __s, \ + _Array<_Tp> __b) \ +{ \ + _Tp* __q (__b._M_data); \ + for (_Tp* __p=__a._M_data; __p<__a._M_data+__s*__n; __p+=__s, ++__q) \ + *__p _Op##= *__q; \ +} \ + \ +template \ +inline void \ +_Array_augmented_##_Name (_Array<_Tp> __a, _Array<_Tp> __b, \ + size_t __n, size_t __s) \ +{ \ + _Tp* __q (__b._M_data); \ + for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p, __q+=__s) \ + *__p _Op##= *__q; \ +} \ + \ +template \ +void \ +_Array_augmented_##_Name (_Array<_Tp> __a, size_t __s, \ + const _Expr<_Dom,_Tp>& __e, size_t __n) \ +{ \ + _Tp* __p (__a._M_data); \ + for (size_t __i=0; __i<__n; ++__i, __p+=__s) *__p _Op##= __e[__i]; \ +} \ + \ +template \ +inline void \ +_Array_augmented_##_Name (_Array<_Tp> __a, _Array __i, \ + _Array<_Tp> __b, size_t __n) \ +{ \ + _Tp* __q (__b._M_data); \ + for (size_t* __j=__i._M_data; __j<__i._M_data+__n; ++__j, ++__q) \ + __a._M_data[*__j] _Op##= *__q; \ +} \ + \ +template \ +inline void \ +_Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, \ + _Array<_Tp> __b, _Array __i) \ +{ \ + _Tp* __p (__a._M_data); \ + for (size_t* __j=__i._M_data; __j<__i._M_data+__n; ++__j, ++__p) \ + *__p _Op##= __b._M_data[*__j]; \ +} \ + \ +template \ +void \ +_Array_augmented_##_Name (_Array<_Tp> __a, _Array __i, \ + const _Expr<_Dom, _Tp>& __e, size_t __n) \ +{ \ + size_t* __j (__i._M_data); \ + for (size_t __k=0; __k<__n; ++__k, ++__j) \ + __a._M_data[*__j] _Op##= __e[__k]; \ +} \ + \ +template \ +void \ +_Array_augmented_##_Name (_Array<_Tp> __a, _Array __m, \ + _Array<_Tp> __b, size_t __n) \ +{ \ + bool* ok (__m._M_data); \ + _Tp* __p (__a._M_data); \ + for (_Tp* __q=__b._M_data; __q<__b._M_data+__n; ++__q, ++ok, ++__p) { \ + while (! *ok) { \ + ++ok; \ + ++__p; \ + } \ + *__p _Op##= *__q; \ + } \ +} \ + \ +template \ +void \ +_Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, \ + _Array<_Tp> __b, _Array __m) \ +{ \ + bool* ok (__m._M_data); \ + _Tp* __q (__b._M_data); \ + for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p, ++ok, ++__q) { \ + while (! *ok) { \ + ++ok; \ + ++__q; \ + } \ + *__p _Op##= *__q; \ + } \ +} \ + \ +template \ +void \ +_Array_augmented_##_Name (_Array<_Tp> __a, _Array __m, \ + const _Expr<_Dom, _Tp>& __e, size_t __n) \ +{ \ + bool* ok(__m._M_data); \ + _Tp* __p (__a._M_data); \ + for (size_t __i=0; __i<__n; ++__i, ++ok, ++__p) { \ + while (! *ok) { \ + ++ok; \ + ++__p; \ + } \ + *__p _Op##= __e[__i]; \ + } \ +} + +_DEFINE_ARRAY_FUNCTION(+, plus) +_DEFINE_ARRAY_FUNCTION(-, minus) +_DEFINE_ARRAY_FUNCTION(*, multiplies) +_DEFINE_ARRAY_FUNCTION(/, divides) +_DEFINE_ARRAY_FUNCTION(%, modulus) +_DEFINE_ARRAY_FUNCTION(^, xor) +_DEFINE_ARRAY_FUNCTION(|, or) +_DEFINE_ARRAY_FUNCTION(&, and) +_DEFINE_ARRAY_FUNCTION(<<, shift_left) +_DEFINE_ARRAY_FUNCTION(>>, shift_right) + +#undef _DEFINE_ARRAY_FUNCTION + +} // extern "C++" + +#ifdef _G_NO_VALARRAY_TEMPLATE_EXPORT +# define export +# include +#endif + +#endif // __VALARRAY_ARRAY__ + +// Local Variables: +// mode:c++ +// End: diff --git a/headers/cpp/std/valarray_array.tcc b/headers/cpp/std/valarray_array.tcc new file mode 100644 index 0000000000..bd6692571f --- /dev/null +++ b/headers/cpp/std/valarray_array.tcc @@ -0,0 +1,130 @@ +// The template and inlines for the -*- C++ -*- internal _Array helper class. + +// Copyright (C) 1997-1999 Cygnus Solutions +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis + +#ifndef __VALARRAY_ARRAY_TCC__ +#define __VALARRAY_ARRAY_TCC__ + +extern "C++" { + +export template +void +__valarray_fill (_Array<_Tp> __a, size_t __n, _Array __m, const _Tp& __t) +{ + _Tp* __p = __a._M_data; + bool* __ok (__m._M_data); + for (size_t __i=0; __i<__n; ++__i, ++__ok, ++__p) { + while (! *__ok) { + ++__ok; + ++__p; + } + *__p = __t; + } +} + +export template +void +__valarray_copy (_Array<_Tp> __a, _Array __m, _Array<_Tp> __b, size_t __n) +{ + _Tp* __p (__a._M_data); + bool* __ok (__m._M_data); + for (_Tp* __q=__b._M_data; __q<__b._M_data+__n; ++__q, ++__ok, ++__p) { + while (! *__ok) { + ++__ok; + ++__p; + } + *__q = *__p; + } +} + +export template +void +__valarray_copy (_Array<_Tp> __a, size_t __n, _Array<_Tp> __b, _Array __m) +{ + _Tp* __q (__b._M_data); + bool* __ok (__m._M_data); + for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p, ++__ok, ++__q) { + while (! *__ok) { + ++__ok; + ++__q; + } + *__q = *__p; + } +} + +export template +void +__valarray_copy (const _Expr<_Dom, _Tp>& __e, size_t __n, _Array<_Tp> __a) +{ + _Tp* __p (__a._M_data); + for (size_t __i=0; __i<__n; ++__i, ++__p) *__p = __e[__i]; +} + +export template +void +__valarray_copy (const _Expr<_Dom, _Tp>& __e, size_t __n, + _Array<_Tp> __a, size_t __s) +{ + _Tp* __p (__a._M_data); + for (size_t __i=0; __i<__n; ++__i, __p+=__s) *__p = __e[__i]; +} + +export template +void +__valarray_copy (const _Expr<_Dom, _Tp>& __e, size_t __n, + _Array<_Tp> __a, _Array __i) +{ + size_t* __j (__i._M_data); + for (size_t __k=0; __k<__n; ++__k, ++__j) __a._M_data[*__j] = __e[__k]; +} + +export template +void +__valarray_copy (const _Expr<_Dom, _Tp>& __e, size_t __n, + _Array<_Tp> __a, _Array __m) +{ + bool* __ok (__m._M_data); + _Tp* __p (__a._M_data); + for (size_t __i=0; __i<__n; ++__i, ++__ok, ++__p) { + while (! *__ok) { + ++__ok; + ++__p; + } + *__p = __e[__i]; + } +} + +} // extern "C++" + +#endif // __VALARRAY_ARRAY_TCC__ + +// Local Variables: +// mode:c++ +// End: diff --git a/headers/cpp/std/valarray_meta.h b/headers/cpp/std/valarray_meta.h new file mode 100644 index 0000000000..48fb21371f --- /dev/null +++ b/headers/cpp/std/valarray_meta.h @@ -0,0 +1,1046 @@ +// The template and inlines for the -*- C++ -*- internal _Meta class. + +// Copyright (C) 1997-1999 Cygnus Solutions +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis + +#ifndef _CPP_VALARRAY_META_H +#define _CPP_VALARRAY_META_H 1 + +// +// Implementing a loosened valarray return value is tricky. +// First we need to meet 26.3.1/3: we should not add more than +// two levels of template nesting. Therefore we resort to template +// template to "flatten" loosened return value types. +// At some point we use partial specialization to remove one level +// template nesting due to _Expr<> +// + + +// This class is NOT defined. It doesn't need to. +template class _Constant; + +// +// Unary function application closure. +// +template class _UnFunBase { +public: + typedef typename _Dom::value_type value_type; + typedef value_type _Vt; + + _UnFunBase (const _Dom& __e, _Vt __f(_Vt)) + : _M_expr(__e), _M_func(__f) {} + + _Vt operator[] (size_t __i) const { return _M_func(_M_expr[__i]); } + size_t size () const { return _M_expr.size(); } + +private: + const _Dom& _M_expr; + _Vt (*_M_func)(_Vt); +}; + +template class _Meta, class _Dom> class _UnFunClos; + +template +struct _UnFunClos<_Expr,_Dom> : _UnFunBase<_Dom> { + typedef _UnFunBase<_Dom> _Base; + typedef typename _Base::value_type value_type; + + _UnFunClos (const _Dom& __e, value_type __f(value_type)) + : _Base (__e, __f) {} +}; + +template +struct _UnFunClos<_ValArray,_Tp> : _UnFunBase > { + typedef _UnFunBase > _Base; + typedef typename _Base::value_type value_type; + + _UnFunClos (const valarray<_Tp>& __v, _Tp __f(_Tp)) + : _Base (__v, __f) {} +}; + +// +// Binary function application closure. +// +template class _Meta1, + template class Meta2, + class _Dom1, class _Dom2> class _BinFunClos; + +template class _BinFunBase { +public: + typedef typename _Dom1::value_type value_type; + typedef value_type _Vt; + + _BinFunBase (const _Dom1& __e1, const _Dom2& __e2, + _Vt __f (_Vt, _Vt)) + : _M_expr1 (__e1), _M_expr2 (__e2), _M_func (__f) {} + + value_type operator[] (size_t __i) const + { return _M_func (_M_expr1[__i], _M_expr2[__i]); } + size_t size () const { return _M_expr1.size (); } + +private: + const _Dom1& _M_expr1; + const _Dom2& _M_expr2; + _Vt (*_M_func)(_Vt, _Vt); +}; + +template class _BinFunBase1 { +public: + typedef typename _Dom::value_type value_type ; + typedef value_type _Vt; + + _BinFunBase1 (const _Vt& __c, const _Dom& __e, _Vt __f(_Vt, _Vt)) + : _M_expr1 (__c), _M_expr2 (__e), _M_func (__f) {} + + value_type operator[] (size_t __i) const + { return _M_func (_M_expr1, _M_expr2[__i]); } + size_t size () const { return _M_expr2.size (); } + +private: + const _Vt& _M_expr1; + const _Dom& _M_expr2; + _Vt (*_M_func)(_Vt, _Vt); +}; + +template class _BinFunBase2 { +public: + typedef typename _Dom::value_type value_type; + typedef value_type _Vt; + + _BinFunBase2 (const _Dom& __e, const _Vt& __c, _Vt __f(_Vt, _Vt)) + : _M_expr1 (__e), _M_expr2 (__c), _M_func (__f) {} + + value_type operator[] (size_t __i) const + { return _M_func (_M_expr1[__i], _M_expr2); } + size_t size () const { return _M_expr1.size (); } + +private: + const _Dom& _M_expr1; + const _Vt& _M_expr2; + _Vt (*_M_func)(_Vt, _Vt); +}; + +template +struct _BinFunClos<_Expr,_Expr,_Dom1,_Dom2> : _BinFunBase<_Dom1,_Dom2> { + typedef _BinFunBase<_Dom1,_Dom2> _Base; + typedef typename _Base::value_type value_type; + typedef value_type _Tp; + + _BinFunClos (const _Dom1& __e1, const _Dom2& __e2, + _Tp __f(_Tp, _Tp)) + : _Base (__e1, __e2, __f) {} +}; + +template +struct _BinFunClos<_ValArray,_ValArray,_Tp,_Tp> + : _BinFunBase, valarray<_Tp> > { + typedef _BinFunBase, valarray<_Tp> > _Base; + typedef _Tp value_type; + + _BinFunClos (const valarray<_Tp>& __v, const valarray<_Tp>& __w, + _Tp __f(_Tp, _Tp)) + : _Base (__v, __w, __f) {} +}; + +template +struct _BinFunClos<_Expr,_ValArray,_Dom,typename _Dom::value_type> + : _BinFunBase<_Dom,valarray > { + typedef typename _Dom::value_type _Tp; + typedef _BinFunBase<_Dom,valarray<_Tp> > _Base; + typedef _Tp value_type; + + _BinFunClos (const _Dom& __e, const valarray<_Tp>& __v, + _Tp __f(_Tp, _Tp)) + : _Base (__e, __v, __f) {} +}; + +template +struct _BinFunClos<_ValArray,_Expr,typename _Dom::value_type,_Dom> + : _BinFunBase,_Dom> { + typedef typename _Dom::value_type _Tp; + typedef _BinFunBase<_Dom,valarray<_Tp> > _Base; + typedef _Tp value_type; + + _BinFunClos (const valarray<_Tp>& __v, const _Dom& __e, + _Tp __f(_Tp, _Tp)) + : _Base (__v, __e, __f) {} +}; + +template +struct _BinFunClos<_Expr,_Constant,_Dom,typename _Dom::value_type> + : _BinFunBase2<_Dom> { + typedef typename _Dom::value_type _Tp; + typedef _Tp value_type; + typedef _BinFunBase2<_Dom> _Base; + + _BinFunClos (const _Dom& __e, const _Tp& __t, _Tp __f (_Tp, _Tp)) + : _Base (__e, __t, __f) {} +}; + +template +struct _BinFunClos<_Constant,_Expr,_Dom,typename _Dom::value_type> + : _BinFunBase1<_Dom> { + typedef typename _Dom::value_type _Tp; + typedef _Tp value_type; + typedef _BinFunBase1<_Dom> _Base; + + _BinFunClos (const _Tp& __t, const _Dom& __e, _Tp __f (_Tp, _Tp)) + : _Base (__t, __e, __f) {} +}; + +template +struct _BinFunClos<_ValArray,_Constant,_Tp,_Tp> + : _BinFunBase2 > { + typedef _BinFunBase2 > _Base; + typedef _Tp value_type; + + _BinFunClos (const valarray<_Tp>& __v, const _Tp& __t, + _Tp __f(_Tp, _Tp)) + : _Base (__v, __t, __f) {} +}; + +template +struct _BinFunClos<_Constant,_ValArray,_Tp,_Tp> + : _BinFunBase1 > { + typedef _BinFunBase1 > _Base; + typedef _Tp value_type; + + _BinFunClos (const _Tp& __t, const valarray<_Tp>& __v, + _Tp __f (_Tp, _Tp)) + : _Base (__t, __v, __f) {} +}; + +// +// Apply function taking a value/const reference closure +// + +template class _FunBase { +public: + typedef typename _Dom::value_type value_type; + + _FunBase (const _Dom& __e, value_type __f(_Arg)) + : _M_expr (__e), _M_func (__f) {} + + value_type operator[] (size_t __i) const + { return _M_func (_M_expr[__i]); } + size_t size() const { return _M_expr.size ();} + +private: + const _Dom& _M_expr; + value_type (*_M_func)(_Arg); +}; + +template +struct _ValFunClos<_Expr,_Dom> + : _FunBase<_Dom, typename _Dom::value_type> { + typedef _FunBase<_Dom, typename _Dom::value_type> _Base; + typedef typename _Base::value_type value_type; + typedef value_type _Tp; + + _ValFunClos (const _Dom& __e, _Tp __f (_Tp)) : _Base (__e, __f) {} +}; + +template +struct _ValFunClos<_ValArray,_Tp> + : _FunBase, _Tp> { + typedef _FunBase, _Tp> _Base; + typedef _Tp value_type; + + _ValFunClos (const valarray<_Tp>& __v, _Tp __f(_Tp)) + : _Base (__v, __f) {} +}; + +template +struct _RefFunClos<_Expr,_Dom> : + _FunBase<_Dom, const typename _Dom::value_type&> { + typedef _FunBase<_Dom, const typename _Dom::value_type&> _Base; + typedef typename _Base::value_type value_type; + typedef value_type _Tp; + + _RefFunClos (const _Dom& __e, _Tp __f (const _Tp&)) + : _Base (__e, __f) {} +}; + +template +struct _RefFunClos<_ValArray,_Tp> + : _FunBase, const _Tp&> { + typedef _FunBase, const _Tp&> _Base; + typedef _Tp value_type; + + _RefFunClos (const valarray<_Tp>& __v, _Tp __f(const _Tp&)) + : _Base (__v, __f) {} +}; + +// +// Unary expression closure. +// + +template class _Oper, typename _Arg> +class _UnBase { +public: + typedef _Oper _Op; + typedef typename _Op::result_type value_type; + + _UnBase (const _Arg& __e) : _M_expr(__e) {} + value_type operator[] (size_t) const; + size_t size () const { return _M_expr.size (); } + +private: + const _Arg& _M_expr; +}; + +template class _Oper, typename _Arg> +inline typename _UnBase<_Oper, _Arg>::value_type +_UnBase<_Oper, _Arg>::operator[] (size_t __i) const +{ return _Op() (_M_expr[__i]); } + +template class _Oper, class _Dom> +struct _UnClos<_Oper, _Expr, _Dom> : _UnBase<_Oper, _Dom> { + typedef _Dom _Arg; + typedef _UnBase<_Oper, _Dom> _Base; + typedef typename _Base::value_type value_type; + + _UnClos (const _Arg& __e) : _Base(__e) {} +}; + +template class _Oper, typename _Tp> +struct _UnClos<_Oper, _ValArray, _Tp> : _UnBase<_Oper, valarray<_Tp> > { + typedef valarray<_Tp> _Arg; + typedef _UnBase<_Oper, valarray<_Tp> > _Base; + typedef typename _Base::value_type value_type; + + _UnClos (const _Arg& __e) : _Base(__e) {} +}; + + +// +// Binary expression closure. +// + +template class _Oper, typename _FirstArg, typename _SecondArg> +class _BinBase { +public: + typedef _Oper _Op; + typedef typename _Op::result_type value_type; + + _BinBase (const _FirstArg& __e1, const _SecondArg& __e2) + : _M_expr1 (__e1), _M_expr2 (__e2) {} + value_type operator[] (size_t) const; + size_t size () const { return _M_expr1.size (); } + +private: + const _FirstArg& _M_expr1; + const _SecondArg& _M_expr2; +}; + +template class _Oper, typename _FirstArg, typename _SecondArg> +inline typename _BinBase<_Oper,_FirstArg,_SecondArg>::value_type +_BinBase<_Oper,_FirstArg,_SecondArg>::operator[] (size_t __i) const +{ return _Op() (_M_expr1[__i], _M_expr2[__i]); } + + +template class _Oper, class _Clos> +class _BinBase2 { +public: + typedef typename _Clos::value_type _Vt; + typedef _Oper<_Vt> _Op; + typedef typename _Op::result_type value_type; + + _BinBase2 (const _Clos& __e, const _Vt& __t) + : _M_expr1 (__e), _M_expr2 (__t) {} + value_type operator[] (size_t) const; + size_t size () const { return _M_expr1.size (); } + +private: + const _Clos& _M_expr1; + const _Vt& _M_expr2; +}; + +template class _Oper, class _Clos> +inline typename _BinBase2<_Oper,_Clos>::value_type +_BinBase2<_Oper,_Clos>::operator[] (size_t __i) const +{ return _Op() (_M_expr1[__i], _M_expr2); } + + +template class _Oper, class _Clos> +class _BinBase1 { +public: + typedef typename _Clos::value_type _Vt; + typedef _Oper<_Vt> _Op; + typedef typename _Op::result_type value_type; + + _BinBase1 (const _Vt& __t, const _Clos& __e) + : _M_expr1 (__t), _M_expr2 (__e) {} + value_type operator[] (size_t) const; + size_t size () const { return _M_expr2.size (); } + +private: + const _Vt& _M_expr1; + const _Clos& _M_expr2; +}; + +template class _Oper, class _Clos> +inline typename +_BinBase1<_Oper,_Clos>::value_type +_BinBase1<_Oper,_Clos>:: operator[] (size_t __i) const +{ return _Op() (_M_expr1, _M_expr2[__i]); } + + +template class _Oper, class _Dom1, class _Dom2> +struct _BinClos<_Oper, _Expr, _Expr, _Dom1, _Dom2> + : _BinBase<_Oper,_Dom1,_Dom2> { + typedef _BinBase<_Oper,_Dom1,_Dom2> _Base; + typedef typename _Base::value_type value_type; + + _BinClos(const _Dom1& __e1, const _Dom2& __e2) : _Base(__e1, __e2) {} +}; + +template class _Oper, typename _Tp> +struct _BinClos<_Oper,_ValArray,_ValArray,_Tp,_Tp> + : _BinBase<_Oper,valarray<_Tp>,valarray<_Tp> > { + typedef _BinBase<_Oper,valarray<_Tp>,valarray<_Tp> > _Base; + typedef _Tp value_type; + + _BinClos (const valarray<_Tp>& __v, const valarray<_Tp>& __w) + : _Base (__v, __w) {} +}; + +template class _Oper, class _Dom> +struct _BinClos<_Oper,_Expr,_ValArray,_Dom,typename _Dom::value_type> + : _BinBase<_Oper,_Dom,valarray > { + typedef typename _Dom::value_type _Tp; + typedef _BinBase<_Oper,_Dom,valarray<_Tp> > _Base; + typedef typename _Base::value_type value_type; + + _BinClos(const _Dom& __e1, const valarray<_Tp>& __e2) + : _Base (__e1, __e2) {} +}; + +template class _Oper, class _Dom> +struct _BinClos<_Oper,_ValArray,_Expr,typename _Dom::value_type,_Dom> + : _BinBase<_Oper,valarray,_Dom> { + typedef typename _Dom::value_type _Tp; + typedef _BinBase<_Oper,valarray<_Tp>,_Dom> _Base; + typedef typename _Base::value_type value_type; + + _BinClos (const valarray<_Tp>& __e1, const _Dom& __e2) + : _Base (__e1, __e2) {} +}; + +template class _Oper, class _Dom> +struct _BinClos<_Oper,_Expr,_Constant,_Dom,typename _Dom::value_type> + : _BinBase2<_Oper,_Dom> { + typedef typename _Dom::value_type _Tp; + typedef _BinBase2<_Oper,_Dom> _Base; + typedef typename _Base::value_type value_type; + + _BinClos (const _Dom& __e1, const _Tp& __e2) : _Base (__e1, __e2) {} +}; + +template class _Oper, class _Dom> +struct _BinClos<_Oper,_Constant,_Expr,typename _Dom::value_type,_Dom> + : _BinBase1<_Oper,_Dom> { + typedef typename _Dom::value_type _Tp; + typedef _BinBase1<_Oper,_Dom> _Base; + typedef typename _Base::value_type value_type; + + _BinClos (const _Tp& __e1, const _Dom& __e2) : _Base (__e1, __e2) {} +}; + +template class _Oper, typename _Tp> +struct _BinClos<_Oper,_ValArray,_Constant,_Tp,_Tp> + : _BinBase2<_Oper,valarray<_Tp> > { + typedef _BinBase2<_Oper,valarray<_Tp> > _Base; + typedef typename _Base::value_type value_type; + + _BinClos (const valarray<_Tp>& __v, const _Tp& __t) + : _Base (__v, __t) {} +}; + +template class _Oper, typename _Tp> +struct _BinClos<_Oper,_Constant,_ValArray,_Tp,_Tp> + : _BinBase1<_Oper,valarray<_Tp> > { + typedef _BinBase1<_Oper,valarray<_Tp> > _Base; + typedef typename _Base::value_type value_type; + + _BinClos (const _Tp& __t, const valarray<_Tp>& __v) + : _Base (__t, __v) {} +}; + + +// +// slice_array closure. +// +template class _SBase { +public: + typedef typename _Dom::value_type value_type; + + _SBase (const _Dom& __e, const slice& __s) + : _M_expr (__e), _M_slice (__s) {} + value_type operator[] (size_t __i) const + { return _M_expr[_M_slice.start () + __i * _M_slice.stride ()]; } + size_t size() const { return _M_slice.size (); } + +private: + const _Dom& _M_expr; + const slice& _M_slice; +}; + +template class _SBase<_Array<_Tp> > { +public: + typedef _Tp value_type; + + _SBase (_Array<_Tp> __a, const slice& __s) + : _M_array (__a._M_data+__s.start()), _M_size (__s.size()), + _M_stride (__s.stride()) {} + value_type operator[] (size_t __i) const + { return _M_array._M_data[__i * _M_stride]; } + size_t size() const { return _M_size; } + +private: + const _Array<_Tp> _M_array; + const size_t _M_size; + const size_t _M_stride; +}; + +template struct _SClos<_Expr,_Dom> : _SBase<_Dom> { + typedef _SBase<_Dom> _Base; + typedef typename _Base::value_type value_type; + + _SClos (const _Dom& __e, const slice& __s) : _Base (__e, __s) {} +}; + +template +struct _SClos<_ValArray,_Tp> : _SBase<_Array<_Tp> > { + typedef _SBase<_Array<_Tp> > _Base; + typedef _Tp value_type; + + _SClos (_Array<_Tp> __a, const slice& __s) : _Base (__a, __s) {} +}; + +// +// gslice_array closure. +// +template class _GBase { +public: + typedef typename _Dom::value_type value_type; + + _GBase (const _Dom& __e, const valarray& __i) + : _M_expr (__e), _M_index(__i) {} + value_type operator[] (size_t __i) const + { return _M_expr[_M_index[__i]]; } + size_t size () const { return _M_index.size(); } + +private: + const _Dom& _M_expr; + const valarray& _M_index; +}; + +template class _GBase<_Array<_Tp> > { +public: + typedef _Tp value_type; + + _GBase (_Array<_Tp> __a, const valarray& __i) + : _M_array (__a), _M_index(__i) {} + value_type operator[] (size_t __i) const + { return _M_array._M_data[_M_index[__i]]; } + size_t size () const { return _M_index.size(); } + +private: + const _Array<_Tp> _M_array; + const valarray& _M_index; +}; + +template struct _GClos<_Expr,_Dom> : _GBase<_Dom> { + typedef _GBase<_Dom> _Base; + typedef typename _Base::value_type value_type; + + _GClos (const _Dom& __e, const valarray& __i) + : _Base (__e, __i) {} +}; + +template +struct _GClos<_ValArray,_Tp> : _GBase<_Array<_Tp> > { + typedef _GBase<_Array<_Tp> > _Base; + typedef typename _Base::value_type value_type; + + _GClos (_Array<_Tp> __a, const valarray& __i) + : _Base (__a, __i) {} +}; + +// +// indirect_array closure +// + +template class _IBase { +public: + typedef typename _Dom::value_type value_type; + + _IBase (const _Dom& __e, const valarray& __i) + : _M_expr (__e), _M_index (__i) {} + value_type operator[] (size_t __i) const + { return _M_expr[_M_index[__i]]; } + size_t size() const { return _M_index.size(); } + +private: + const _Dom& _M_expr; + const valarray& _M_index; +}; + +template struct _IClos<_Expr,_Dom> : _IBase<_Dom> { + typedef _IBase<_Dom> _Base; + typedef typename _Base::value_type value_type; + + _IClos (const _Dom& __e, const valarray& __i) + : _Base (__e, __i) {} +}; + +template +struct _IClos<_ValArray,_Tp> : _IBase > { + typedef _IBase > _Base; + typedef _Tp value_type; + + _IClos (const valarray<_Tp>& __a, const valarray& __i) + : _Base (__a, __i) {} +}; + +// +// class _Expr +// +template class _Expr { +public: + typedef _Tp value_type; + + _Expr (const _Clos&); + + const _Clos& operator() () const; + + value_type operator[] (size_t) const; + valarray operator[] (slice) const; + valarray operator[] (const gslice&) const; + valarray operator[] (const valarray&) const; + valarray operator[] (const valarray&) const; + + _Expr<_UnClos<_Unary_plus,_Expr,_Clos>, value_type> + operator+ () const; + + _Expr<_UnClos, value_type> + operator- () const; + + _Expr<_UnClos<_Bitwise_not,_Expr,_Clos>, value_type> + operator~ () const; + + _Expr<_UnClos, bool> + operator! () const; + + size_t size () const; + value_type sum () const; + + valarray shift (int) const; + valarray cshift (int) const; +// _Meta<_ApplyFunctionWithValue<_Expr>, value_type> +// apply (value_type _M_func (value_type)) const; +// _Meta<_ApplyFunctionWithConstRef<_Expr>, value_type> +// apply (value_type _M_func (const value_type&)) const; + +private: + const _Clos _M_closure; +}; + +template +inline +_Expr<_Clos,_Tp>::_Expr (const _Clos& __c) : _M_closure(__c) {} + +template +inline const _Clos& +_Expr<_Clos,_Tp>::operator() () const +{ return _M_closure; } + +template +inline _Tp +_Expr<_Clos,_Tp>::operator[] (size_t __i) const +{ return _M_closure[__i]; } + +template +inline valarray<_Tp> +_Expr<_Clos,_Tp>::operator[] (slice __s) const +{ return _M_closure[__s]; } + +template +inline valarray<_Tp> +_Expr<_Clos,_Tp>::operator[] (const gslice& __gs) const +{ return _M_closure[__gs]; } + +template +inline valarray<_Tp> +_Expr<_Clos,_Tp>::operator[] (const valarray& __m) const +{ return _M_closure[__m]; } + +template +inline valarray<_Tp> +_Expr<_Clos,_Tp>::operator[] (const valarray& __i) const +{ return _M_closure[__i]; } + +template +inline size_t +_Expr<_Clos,_Tp>::size () const { return _M_closure.size (); } + +// XXX: replace this with a more robust summation algorithm. +template +inline _Tp +_Expr<_Clos,_Tp>::sum () const +{ + _Tp __s(_Tp()); + size_t __n (_M_closure.size ()); + for (size_t __i=0; __i<__n; ++__i) __s += _M_closure[__i]; + return __s; +} + +template +inline _Tp +min (const _Expr<_Dom,_Tp>& __e) +{ + size_t __s (__e.size ()); + _Tp __m (__e[0]); + for (size_t __i=1; __i<__s; ++__i) + if (__m > __e[__i]) __m = __e[__i]; + return __m; +} + +template +inline _Tp +max (const _Expr<_Dom,_Tp>& __e) +{ + size_t __s (__e.size()); + _Tp __m (__e[0]); + for (size_t __i=1; __i<__s; ++__i) + if (__m < __e[__i]) __m = __e[__i]; + return __m; +} + +template +inline _Expr<_UnClos, bool> +_Expr<_Dom,_Tp>::operator! () const +{ + typedef _UnClos _Closure; + return _Expr<_Closure,_Tp> (_Closure(this->_M_closure)); +} + +#define _DEFINE_EXPR_UNARY_OPERATOR(_Op, _Name) \ +template \ +inline _Expr<_UnClos<_Name,_Expr,_Dom>,_Tp> \ +_Expr<_Dom,_Tp>::operator##_Op () const \ +{ \ + typedef _UnClos<_Name,_Expr,_Dom> _Closure; \ + return _Expr<_Closure,_Tp> (_Closure (this->_M_closure)); \ +} + + _DEFINE_EXPR_UNARY_OPERATOR(+, _Unary_plus) + _DEFINE_EXPR_UNARY_OPERATOR(-, negate) + _DEFINE_EXPR_UNARY_OPERATOR(~, _Bitwise_not) + +#undef _DEFINE_EXPR_UNARY_OPERATOR + + +#define _DEFINE_EXPR_BINARY_OPERATOR(_Op, _Name) \ +template \ +inline _Expr<_BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2>, \ + typename _Name::result_type> \ +operator##_Op (const _Expr<_Dom1,typename _Dom1::value_type>& __v, \ + const _Expr<_Dom2,typename _Dom2::value_type>& __w) \ +{ \ + typedef typename _Dom1::value_type _Arg; \ + typedef typename _Name<_Arg>::result_type _Value; \ + typedef _BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2> _Closure; \ + return _Expr<_Closure,_Value> (_Closure (__v (), __w ())); \ +} \ + \ +template \ +inline _Expr<_BinClos<_Name,_Expr,_Constant,_Dom,typename _Dom::value_type>, \ + typename _Name::result_type> \ +operator##_Op (const _Expr<_Dom,typename _Dom::value_type>& __v, \ + const typename _Dom::value_type& __t) \ +{ \ + typedef typename _Dom::value_type _Arg; \ + typedef typename _Name<_Arg>::result_type _Value; \ + typedef _BinClos<_Name,_Expr,_Constant,_Dom,_Arg> _Closure; \ + return _Expr<_Closure,_Value> (_Closure (__v (), __t)); \ +} \ + \ +template \ +inline _Expr<_BinClos<_Name,_Constant,_Expr,typename _Dom::value_type,_Dom>, \ + typename _Name::result_type> \ +operator##_Op (const typename _Dom::value_type& __t, \ + const _Expr<_Dom,typename _Dom::value_type>& __v) \ +{ \ + typedef typename _Dom::value_type _Arg; \ + typedef typename _Name<_Arg>::result_type _Value; \ + typedef _BinClos<_Name,_Constant,_Expr,_Arg,_Dom> _Closure; \ + return _Expr<_Closure,_Value> (_Closure (__t, __v ())); \ +} \ + \ +template \ +inline _Expr<_BinClos<_Name,_Expr,_ValArray,_Dom,typename _Dom::value_type>, \ + typename _Name::result_type> \ +operator##_Op (const _Expr<_Dom,typename _Dom::value_type>& __e, \ + const valarray& __v) \ +{ \ + typedef typename _Dom::value_type _Arg; \ + typedef typename _Name<_Arg>::result_type _Value; \ + typedef _BinClos<_Name,_Expr,_ValArray,_Dom,_Arg> _Closure; \ + return _Expr<_Closure,_Value> (_Closure (__e (), __v)); \ +} \ + \ +template \ +inline _Expr<_BinClos<_Name,_ValArray,_Expr,typename _Dom::value_type,_Dom>, \ + typename _Name::result_type> \ +operator##_Op (const valarray& __v, \ + const _Expr<_Dom,typename _Dom::value_type>& __e) \ +{ \ + typedef typename _Dom::value_type _Tp; \ + typedef typename _Name<_Tp>::result_type _Value; \ + typedef _BinClos<_Name,_ValArray,_Expr,_Tp,_Dom> _Closure; \ + return _Expr<_Closure,_Value> (_Closure (__v, __e ())); \ +} + + _DEFINE_EXPR_BINARY_OPERATOR(+, plus) + _DEFINE_EXPR_BINARY_OPERATOR(-, minus) + _DEFINE_EXPR_BINARY_OPERATOR(*, multiplies) + _DEFINE_EXPR_BINARY_OPERATOR(/, divides) + _DEFINE_EXPR_BINARY_OPERATOR(%, modulus) + _DEFINE_EXPR_BINARY_OPERATOR(^, _Bitwise_xor) + _DEFINE_EXPR_BINARY_OPERATOR(&, _Bitwise_and) + _DEFINE_EXPR_BINARY_OPERATOR(|, _Bitwise_or) + _DEFINE_EXPR_BINARY_OPERATOR(<<, _Shift_left) + _DEFINE_EXPR_BINARY_OPERATOR(>>, _Shift_right) + +#undef _DEFINE_EXPR_BINARY_OPERATOR + +#define _DEFINE_EXPR_RELATIONAL_OPERATOR(_Op, _Name) \ +template \ +inline _Expr<_BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2>, bool> \ +operator##_Op (const _Expr<_Dom1,typename _Dom1::value_type>& __v, \ + const _Expr<_Dom2,typename _Dom2::value_type>& __w) \ +{ \ + typedef typename _Dom1::value_type _Arg; \ + typedef _BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2> _Closure; \ + return _Expr<_Closure,bool> (_Closure (__v (), __w ())); \ +} \ + \ +template \ +inline _Expr<_BinClos<_Name,_Expr,_Constant,_Dom,typename _Dom::value_type>, \ + bool> \ +operator##_Op (const _Expr<_Dom,typename _Dom::value_type>& __v, \ + const typename _Dom::value_type& __t) \ +{ \ + typedef typename _Dom::value_type _Arg; \ + typedef _BinClos<_Name,_Expr,_Constant,_Dom,_Arg> _Closure; \ + return _Expr<_Closure,bool> (_Closure (__v (), __t)); \ +} \ + \ +template \ +inline _Expr<_BinClos<_Name,_Constant,_Expr,typename _Dom::value_type,_Dom>, \ + bool> \ +operator##_Op (const typename _Dom::value_type& __t, \ + const _Expr<_Dom,typename _Dom::value_type>& __v) \ +{ \ + typedef typename _Dom::value_type _Arg; \ + typedef _BinClos<_Name,_Constant,_Expr,_Arg,_Dom> _Closure; \ + return _Expr<_Closure,bool> (_Closure (__t, __v ())); \ +} \ + \ +template \ +inline _Expr<_BinClos<_Name,_Expr,_ValArray,_Dom,typename _Dom::value_type>, \ + bool> \ +operator##_Op (const _Expr<_Dom,typename _Dom::value_type>& __e, \ + const valarray& __v) \ +{ \ + typedef typename _Dom::value_type _Tp; \ + typedef _BinClos<_Name,_Expr,_ValArray,_Dom,_Tp> _Closure; \ + return _Expr<_Closure,bool> (_Closure (__e (), __v)); \ +} \ + \ +template \ +inline _Expr<_BinClos<_Name,_ValArray,_Expr,typename _Dom::value_type,_Dom>, \ + bool> \ +operator##_Op (const valarray& __v, \ + const _Expr<_Dom,typename _Dom::value_type>& __e) \ +{ \ + typedef typename _Dom::value_type _Tp; \ + typedef _BinClos<_Name,_ValArray,_Expr,_Tp,_Dom> _Closure; \ + return _Expr<_Closure,bool> (_Closure (__v, __e ())); \ +} + + _DEFINE_EXPR_RELATIONAL_OPERATOR(&&, logical_and) + _DEFINE_EXPR_RELATIONAL_OPERATOR(||, logical_or) + _DEFINE_EXPR_RELATIONAL_OPERATOR(==, equal_to) + _DEFINE_EXPR_RELATIONAL_OPERATOR(!=, not_equal_to) + _DEFINE_EXPR_RELATIONAL_OPERATOR(<, less) + _DEFINE_EXPR_RELATIONAL_OPERATOR(>, greater) + _DEFINE_EXPR_RELATIONAL_OPERATOR(<=, less_equal) + _DEFINE_EXPR_RELATIONAL_OPERATOR(>=, greater_equal) + +#undef _DEFINE_EXPR_RELATIONAL_OPERATOR + + + +#define _DEFINE_EXPR_UNARY_FUNCTION(_Name) \ +template \ +inline _Expr<_UnFunClos<_Expr,_Dom>,typename _Dom::value_type> \ +_Name(const _Expr<_Dom,typename _Dom::value_type>& __e) \ +{ \ + typedef typename _Dom::value_type _Tp; \ + typedef _UnFunClos<_Expr,_Dom> _Closure; \ + return _Expr<_Closure,_Tp>(_Closure(__e(), (_Tp(*)(_Tp))(&_Name))); \ +} \ + \ +template \ +inline _Expr<_UnFunClos<_ValArray,_Tp>,_Tp> \ +_Name(const valarray<_Tp>& __v) \ +{ \ + typedef _UnFunClos<_ValArray,_Tp> _Closure; \ + return _Expr<_Closure,_Tp> (_Closure (__v, (_Tp(*)(_Tp))(&_Name))); \ +} + + + _DEFINE_EXPR_UNARY_FUNCTION(abs) + _DEFINE_EXPR_UNARY_FUNCTION(cos) + _DEFINE_EXPR_UNARY_FUNCTION(acos) + _DEFINE_EXPR_UNARY_FUNCTION(cosh) + _DEFINE_EXPR_UNARY_FUNCTION(sin) + _DEFINE_EXPR_UNARY_FUNCTION(asin) + _DEFINE_EXPR_UNARY_FUNCTION(sinh) + _DEFINE_EXPR_UNARY_FUNCTION(tan) + _DEFINE_EXPR_UNARY_FUNCTION(tanh) + _DEFINE_EXPR_UNARY_FUNCTION(atan) + _DEFINE_EXPR_UNARY_FUNCTION(exp) + _DEFINE_EXPR_UNARY_FUNCTION(log) + _DEFINE_EXPR_UNARY_FUNCTION(log10) + _DEFINE_EXPR_UNARY_FUNCTION(sqrt) + +#undef _DEFINE_EXPR_UNARY_FUNCTION + + +#define _DEFINE_EXPR_BINARY_FUNCTION(_Name) \ +template \ +inline _Expr<_BinFunClos<_Expr,_Expr,_Dom1,_Dom2>,typename _Dom1::value_type>\ +_Name (const _Expr<_Dom1,typename _Dom1::value_type>& __e1, \ + const _Expr<_Dom2,typename _Dom2::value_type>& __e2) \ +{ \ + typedef typename _Dom1::value_type _Tp; \ + typedef _BinFunClos<_Expr,_Expr,_Dom1,_Dom2> _Closure; \ + return _Expr<_Closure,_Tp> \ + (_Closure (__e1 (), __e2 (), (_Tp(*)(_Tp, _Tp))(&_Name))); \ +} \ + \ +template \ +inline _Expr<_BinFunClos<_Expr,_ValArray,_Dom,typename _Dom::value_type>, \ + typename _Dom::value_type> \ +_Name (const _Expr<_Dom,typename _Dom::value_type>& __e, \ + const valarray& __v) \ +{ \ + typedef typename _Dom::value_type _Tp; \ + typedef _BinFunClos<_Expr,_ValArray,_Dom,_Tp> _Closure; \ + return _Expr<_Closure,_Tp> \ + (_Closure (__e (), __v, (_Tp(*)(_Tp, _Tp))(&_Name))); \ +} \ + \ +template \ +inline _Expr<_BinFunClos<_ValArray,_Expr,typename _Dom::value_type,_Dom>, \ + typename _Dom::value_type> \ +_Name (const valarray& __v, \ + const _Expr<_Dom,typename _Dom::value_type>& __e) \ +{ \ + typedef typename _Dom::value_type _Tp; \ + typedef _BinFunClos<_ValArray,_Expr,_Tp,_Dom> _Closure; \ + return _Expr<_Closure,_Tp> \ + (_Closure (__v, __e (), (_Tp(*)(_Tp, _Tp))(&_Name))); \ +} \ + \ +template \ +inline _Expr<_BinFunClos<_Expr,_Constant,_Dom,typename _Dom::value_type>, \ + typename _Dom::value_type> \ +_Name (const _Expr<_Dom, typename _Dom::value_type>& __e, \ + const typename _Dom::value_type& __t) \ +{ \ + typedef typename _Dom::value_type _Tp; \ + typedef _BinFunClos<_Expr,_Constant,_Dom,_Tp> _Closure; \ + return _Expr<_Closure,_Tp> \ + (_Closure (__e (), __t, (_Tp(*)(_Tp, _Tp))(&_Name))); \ +} \ + \ +template \ +inline _Expr<_BinFunClos<_Constant,_Expr,typename _Dom::value_type,_Dom>, \ + typename _Dom::value_type> \ +_Name (const typename _Dom::value_type& __t, \ + const _Expr<_Dom,typename _Dom::value_type>& __e) \ +{ \ + typedef typename _Dom::value_type _Tp; \ + typedef _BinFunClos<_Constant,_Expr,_Tp,_Dom> _Closure; \ + return _Expr<_Closure,_Tp> \ + (_Closure (__t, __e (), (_Tp(*)(_Tp, _Tp))(&_Name))); \ +} \ + \ +template \ +inline _Expr<_BinFunClos<_ValArray,_ValArray,_Tp,_Tp>, _Tp> \ +_Name (const valarray<_Tp>& __v, const valarray<_Tp>& __w) \ +{ \ + typedef _BinFunClos<_ValArray,_ValArray,_Tp,_Tp> _Closure; \ + return _Expr<_Closure,_Tp> \ + (_Closure (__v, __w, (_Tp(*)(_Tp,_Tp))(&_Name))); \ +} \ + \ +template \ +inline _Expr<_BinFunClos<_ValArray,_Constant,_Tp,_Tp>,_Tp> \ +_Name (const valarray<_Tp>& __v, const _Tp& __t) \ +{ \ + typedef _BinFunClos<_ValArray,_Constant,_Tp,_Tp> _Closure; \ + return _Expr<_Closure,_Tp> \ + (_Closure (__v, __t, (_Tp(*)(_Tp,_Tp))(&_Name))); \ +} \ + \ +template \ +inline _Expr<_BinFunClos<_Constant,_ValArray,_Tp,_Tp>,_Tp> \ +_Name (const _Tp& __t, const valarray<_Tp>& __v) \ +{ \ + typedef _BinFunClos<_Constant,_ValArray,_Tp,_Tp> _Closure; \ + return _Expr<_Closure,_Tp> \ + (_Closure (__t, __v, (_Tp(*)(_Tp,_Tp))(&_Name))); \ +} + +_DEFINE_EXPR_BINARY_FUNCTION(atan2) +_DEFINE_EXPR_BINARY_FUNCTION(pow) + +#undef _DEFINE_EXPR_BINARY_FUNCTION + +#endif // _CPP_VALARRAY_META_H + +// Local Variables: +// mode:c++ +// End: diff --git a/headers/cpp/stdexcept b/headers/cpp/stdexcept new file mode 100644 index 0000000000..69e9627d57 --- /dev/null +++ b/headers/cpp/stdexcept @@ -0,0 +1,97 @@ +// Methods for Exception Support for -*- C++ -*- +// Copyright (C) 1994, 1995, 1997 Free Software Foundation + +// This file is part of the GNU ANSI C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// As a special exception, if you link this library with files +// compiled with a GNU compiler to produce an executable, this does not cause +// the resulting executable to be covered by the GNU General Public License. +// This exception does not however invalidate any other reasons why +// the executable file might be covered by the GNU General Public License. + +// Written by Mike Stump based upon the specification in the 20 September 1994 +// C++ working paper, ANSI document X3J16/94-0158. + +#ifndef __STDEXCEPT__ +#define __STDEXCEPT__ + +#ifdef __GNUG__ +#pragma interface "stdexcept" +#endif + +#include +#include + +extern "C++" { + +namespace std { + +class logic_error : public exception { + string _what; +public: + logic_error(const string& what_arg): _what (what_arg) { } + virtual const char* what () const { return _what.c_str (); } +}; + +class domain_error : public logic_error { +public: + domain_error (const string& what_arg): logic_error (what_arg) { } +}; + +class invalid_argument : public logic_error { +public: + invalid_argument (const string& what_arg): logic_error (what_arg) { } +}; + +class length_error : public logic_error { +public: + length_error (const string& what_arg): logic_error (what_arg) { } +}; + +class out_of_range : public logic_error { +public: + out_of_range (const string& what_arg): logic_error (what_arg) { } +}; + +class runtime_error : public exception { + string _what; +public: + runtime_error(const string& what_arg): _what (what_arg) { } + virtual const char* what () const { return _what.c_str (); } +protected: + runtime_error(): exception () { } +}; + +class range_error : public runtime_error { +public: + range_error (const string& what_arg): runtime_error (what_arg) { } +}; + +class overflow_error : public runtime_error { +public: + overflow_error (const string& what_arg): runtime_error (what_arg) { } +}; + +class underflow_error : public runtime_error { +public: + underflow_error (const string& what_arg): runtime_error (what_arg) { } +}; + +} // namespace std + +} // extern "C++" + +#endif diff --git a/headers/cpp/stdiostream.h b/headers/cpp/stdiostream.h new file mode 100644 index 0000000000..b973d7a39b --- /dev/null +++ b/headers/cpp/stdiostream.h @@ -0,0 +1,79 @@ +/* This is part of libio/iostream, providing -*- C++ -*- input/output. +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + +/* Written by Per Bothner (bothner@cygnus.com). */ + +#ifndef _STDIOSTREAM_H +#define _STDIOSTREAM_H + +#ifdef __GNUG__ +#pragma interface +#endif + +#include +#include + +extern "C++" { +class stdiobuf : public filebuf { + protected: + FILE *_file; + public: + FILE* stdiofile() const { return _file; } + stdiobuf(FILE *); + ~stdiobuf(); + int buffered () const { return _flags & _IO_UNBUFFERED ? 0 : 1; } + void buffered (int); + virtual streamsize sys_read(char*, streamsize); + virtual streampos sys_seek(streamoff, _seek_dir); + virtual streamsize sys_write(const char*, streamsize); + virtual int sys_close(); + virtual int sync(); + virtual int overflow(int c = EOF); + streamsize xsputn(const char* s, streamsize n); +}; + +class istdiostream : public istream +{ +private: + stdiobuf _file; +public: + istdiostream (FILE* __f) : istream(), _file(__f) { init(&_file); } + stdiobuf* rdbuf()/* const */ { return &_file; } + int buffered () const { return _file.buffered (); } + void buffered (int _i) { _file.buffered (_i); } +}; + +class ostdiostream : public ostream +{ +private: + stdiobuf _file; +public: + ostdiostream (FILE* __f) : ostream(), _file(__f) { init(&_file); } + stdiobuf* rdbuf() /* const */ { return &_file; } + int buffered () const { return _file.buffered (); } + void buffered (int _i) { _file.buffered (_i); } +}; +} // extern "C++" + +#endif /* !_STDIOSTREAM_H */ diff --git a/headers/cpp/stl.h b/headers/cpp/stl.h new file mode 100644 index 0000000000..4b270742c9 --- /dev/null +++ b/headers/cpp/stl.h @@ -0,0 +1,15 @@ +// -*- C++ -*- compatibility header. +// This file is part of the GNU ANSI C++ Library. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/headers/cpp/stl_algo.h b/headers/cpp/stl_algo.h new file mode 100644 index 0000000000..e9beaee15f --- /dev/null +++ b/headers/cpp/stl_algo.h @@ -0,0 +1,2894 @@ +/* + * + * 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. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_ALGO_H +#define __SGI_STL_INTERNAL_ALGO_H + +#include + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1209 +#endif + +// __median (an extension, not present in the C++ standard). + +template +inline const _Tp& __median(const _Tp& __a, const _Tp& __b, const _Tp& __c) { + if (__a < __b) + if (__b < __c) + return __b; + else if (__a < __c) + return __c; + else + return __a; + else if (__a < __c) + return __a; + else if (__b < __c) + return __c; + else + return __b; +} + +template +inline const _Tp& +__median(const _Tp& __a, const _Tp& __b, const _Tp& __c, _Compare __comp) { + if (__comp(__a, __b)) + if (__comp(__b, __c)) + return __b; + else if (__comp(__a, __c)) + return __c; + else + return __a; + else if (__comp(__a, __c)) + return __a; + else if (__comp(__b, __c)) + return __c; + else + return __b; +} + +// for_each. Apply a function to every element of a range. +template +_Function for_each(_InputIter __first, _InputIter __last, _Function __f) { + for ( ; __first != __last; ++__first) + __f(*__first); + return __f; +} + +// find and find_if. + +template +inline _InputIter find(_InputIter __first, _InputIter __last, + const _Tp& __val, + input_iterator_tag) +{ + while (__first != __last && *__first != __val) + ++__first; + return __first; +} + +template +inline _InputIter find_if(_InputIter __first, _InputIter __last, + _Predicate __pred, + input_iterator_tag) +{ + while (__first != __last && !__pred(*__first)) + ++__first; + return __first; +} + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +_RandomAccessIter find(_RandomAccessIter __first, _RandomAccessIter __last, + const _Tp& __val, + random_access_iterator_tag) +{ + typename iterator_traits<_RandomAccessIter>::difference_type __trip_count + = (__last - __first) >> 2; + + for ( ; __trip_count > 0 ; --__trip_count) { + if (*__first == __val) return __first; + ++__first; + + if (*__first == __val) return __first; + ++__first; + + if (*__first == __val) return __first; + ++__first; + + if (*__first == __val) return __first; + ++__first; + } + + switch(__last - __first) { + case 3: + if (*__first == __val) return __first; + ++__first; + case 2: + if (*__first == __val) return __first; + ++__first; + case 1: + if (*__first == __val) return __first; + ++__first; + case 0: + default: + return __last; + } +} + +template +_RandomAccessIter find_if(_RandomAccessIter __first, _RandomAccessIter __last, + _Predicate __pred, + random_access_iterator_tag) +{ + typename iterator_traits<_RandomAccessIter>::difference_type __trip_count + = (__last - __first) >> 2; + + for ( ; __trip_count > 0 ; --__trip_count) { + if (__pred(*__first)) return __first; + ++__first; + + if (__pred(*__first)) return __first; + ++__first; + + if (__pred(*__first)) return __first; + ++__first; + + if (__pred(*__first)) return __first; + ++__first; + } + + switch(__last - __first) { + case 3: + if (__pred(*__first)) return __first; + ++__first; + case 2: + if (__pred(*__first)) return __first; + ++__first; + case 1: + if (__pred(*__first)) return __first; + ++__first; + case 0: + default: + return __last; + } +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template +inline _InputIter find(_InputIter __first, _InputIter __last, + const _Tp& __val) +{ + return find(__first, __last, __val, __ITERATOR_CATEGORY(__first)); +} + +template +inline _InputIter find_if(_InputIter __first, _InputIter __last, + _Predicate __pred) { + return find_if(__first, __last, __pred, __ITERATOR_CATEGORY(__first)); +} + +// adjacent_find. + +template +_ForwardIter adjacent_find(_ForwardIter __first, _ForwardIter __last) { + if (__first == __last) + return __last; + _ForwardIter __next = __first; + while(++__next != __last) { + if (*__first == *__next) + return __first; + __first = __next; + } + return __last; +} + +template +_ForwardIter adjacent_find(_ForwardIter __first, _ForwardIter __last, + _BinaryPredicate __binary_pred) { + if (__first == __last) + return __last; + _ForwardIter __next = __first; + while(++__next != __last) { + if (__binary_pred(*__first, *__next)) + return __first; + __first = __next; + } + return __last; +} + +// count and count_if. There are two version of each, one whose return type +// type is void and one (present only if we have partial specialization) +// whose return type is iterator_traits<_InputIter>::difference_type. The +// C++ standard only has the latter version, but the former, which was present +// in the HP STL, is retained for backward compatibility. + +template +void count(_InputIter __first, _InputIter __last, const _Tp& __value, + _Size& __n) { + for ( ; __first != __last; ++__first) + if (*__first == __value) + ++__n; +} + +template +void count_if(_InputIter __first, _InputIter __last, _Predicate __pred, + _Size& __n) { + for ( ; __first != __last; ++__first) + if (__pred(*__first)) + ++__n; +} + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +typename iterator_traits<_InputIter>::difference_type +count(_InputIter __first, _InputIter __last, const _Tp& __value) { + typename iterator_traits<_InputIter>::difference_type __n = 0; + for ( ; __first != __last; ++__first) + if (*__first == __value) + ++__n; + return __n; +} + +template +typename iterator_traits<_InputIter>::difference_type +count_if(_InputIter __first, _InputIter __last, _Predicate __pred) { + typename iterator_traits<_InputIter>::difference_type __n = 0; + for ( ; __first != __last; ++__first) + if (__pred(*__first)) + ++__n; + return __n; +} + + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +// search. + +template +_ForwardIter1 search(_ForwardIter1 __first1, _ForwardIter1 __last1, + _ForwardIter2 __first2, _ForwardIter2 __last2) +{ + // Test for empty ranges + if (__first1 == __last1 || __first2 == __last2) + return __first1; + + // Test for a pattern of length 1. + _ForwardIter2 __tmp(__first2); + ++__tmp; + if (__tmp == __last2) + return find(__first1, __last1, *__first2); + + // General case. + + _ForwardIter2 __p1, __p; + + __p1 = __first2; ++__p1; + + _ForwardIter1 __current = __first1; + + while (__first1 != __last1) { + __first1 = find(__first1, __last1, *__first2); + if (__first1 == __last1) + return __last1; + + __p = __p1; + __current = __first1; + if (++__current == __last1) + return __last1; + + while (*__current == *__p) { + if (++__p == __last2) + return __first1; + if (++__current == __last1) + return __last1; + } + + ++__first1; + } + return __first1; +} + +template +_ForwardIter1 search(_ForwardIter1 __first1, _ForwardIter1 __last1, + _ForwardIter2 __first2, _ForwardIter2 __last2, + _BinaryPred __predicate) +{ + // Test for empty ranges + if (__first1 == __last1 || __first2 == __last2) + return __first1; + + // Test for a pattern of length 1. + _ForwardIter2 __tmp(__first2); + ++__tmp; + if (__tmp == __last2) + return find(__first1, __last1, *__first2); + + // General case. + + _ForwardIter2 __p1, __p; + + __p1 = __first2; ++__p1; + + _ForwardIter1 __current = __first1; + + while (__first1 != __last1) { + while (__first1 != __last1) { + if (__predicate(*__first1, *__first2)) + break; + ++__first1; + } + while (__first1 != __last1 && !__predicate(*__first1, *__first2)) + ++__first1; + if (__first1 == __last1) + return __last1; + + __p = __p1; + __current = __first1; + if (++__current == __last1) return __last1; + + while (__predicate(*__current, *__p)) { + if (++__p == __last2) + return __first1; + if (++__current == __last1) + return __last1; + } + + ++__first1; + } + return __first1; +} + +// search_n. Search for __count consecutive copies of __val. + +template +_ForwardIter search_n(_ForwardIter __first, _ForwardIter __last, + _Integer __count, const _Tp& __val) { + if (__count <= 0) + return __first; + else { + __first = find(__first, __last, __val); + while (__first != __last) { + _Integer __n = __count - 1; + _ForwardIter __i = __first; + ++__i; + while (__i != __last && __n != 0 && *__i == __val) { + ++__i; + --__n; + } + if (__n == 0) + return __first; + else + __first = find(__i, __last, __val); + } + return __last; + } +} + +template +_ForwardIter search_n(_ForwardIter __first, _ForwardIter __last, + _Integer __count, const _Tp& __val, + _BinaryPred __binary_pred) { + if (__count <= 0) + return __first; + else { + while (__first != __last) { + if (__binary_pred(*__first, __val)) + break; + ++__first; + } + while (__first != __last) { + _Integer __n = __count - 1; + _ForwardIter __i = __first; + ++__i; + while (__i != __last && __n != 0 && __binary_pred(*__i, __val)) { + ++__i; + --__n; + } + if (__n == 0) + return __first; + else { + while (__i != __last) { + if (__binary_pred(*__i, __val)) + break; + ++__i; + } + __first = __i; + } + } + return __last; + } +} + +// swap_ranges + +template +_ForwardIter2 swap_ranges(_ForwardIter1 __first1, _ForwardIter1 __last1, + _ForwardIter2 __first2) { + for ( ; __first1 != __last1; ++__first1, ++__first2) + iter_swap(__first1, __first2); + return __first2; +} + +// transform + +template +_OutputIter transform(_InputIter __first, _InputIter __last, + _OutputIter __result, _UnaryOperation __oper) { + for ( ; __first != __last; ++__first, ++__result) + *__result = __oper(*__first); + return __result; +} + +template +_OutputIter transform(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _OutputIter __result, + _BinaryOperation __binary_op) { + for ( ; __first1 != __last1; ++__first1, ++__first2, ++__result) + *__result = __binary_op(*__first1, *__first2); + return __result; +} + +// replace, replace_if, replace_copy, replace_copy_if + +template +void replace(_ForwardIter __first, _ForwardIter __last, + const _Tp& __old_value, const _Tp& __new_value) { + for ( ; __first != __last; ++__first) + if (*__first == __old_value) + *__first = __new_value; +} + +template +void replace_if(_ForwardIter __first, _ForwardIter __last, + _Predicate __pred, const _Tp& __new_value) { + for ( ; __first != __last; ++__first) + if (__pred(*__first)) + *__first = __new_value; +} + +template +_OutputIter replace_copy(_InputIter __first, _InputIter __last, + _OutputIter __result, + const _Tp& __old_value, const _Tp& __new_value) { + for ( ; __first != __last; ++__first, ++__result) + *__result = *__first == __old_value ? __new_value : *__first; + return __result; +} + +template +_OutputIter replace_copy_if(Iterator __first, Iterator __last, + _OutputIter __result, + _Predicate __pred, const _Tp& __new_value) { + for ( ; __first != __last; ++__first, ++__result) + *__result = __pred(*__first) ? __new_value : *__first; + return __result; +} + +// generate and generate_n + +template +void generate(_ForwardIter __first, _ForwardIter __last, _Generator __gen) { + for ( ; __first != __last; ++__first) + *__first = __gen(); +} + +template +_OutputIter generate_n(_OutputIter __first, _Size __n, _Generator __gen) { + for ( ; __n > 0; --__n, ++__first) + *__first = __gen(); + return __first; +} + +// remove, remove_if, remove_copy, remove_copy_if + +template +_OutputIter remove_copy(_InputIter __first, _InputIter __last, + _OutputIter __result, const _Tp& __value) { + for ( ; __first != __last; ++__first) + if (*__first != __value) { + *__result = *__first; + ++__result; + } + return __result; +} + +template +_OutputIter remove_copy_if(_InputIter __first, _InputIter __last, + _OutputIter __result, _Predicate __pred) { + for ( ; __first != __last; ++__first) + if (!__pred(*__first)) { + *__result = *__first; + ++__result; + } + return __result; +} + +template +_ForwardIter remove(_ForwardIter __first, _ForwardIter __last, + const _Tp& __value) { + __first = find(__first, __last, __value); + _ForwardIter __i = __first; + return __first == __last ? __first + : remove_copy(++__i, __last, __first, __value); +} + +template +_ForwardIter remove_if(_ForwardIter __first, _ForwardIter __last, + _Predicate __pred) { + __first = find_if(__first, __last, __pred); + _ForwardIter __i = __first; + return __first == __last ? __first + : remove_copy_if(++__i, __last, __first, __pred); +} + +// unique and unique_copy + +template +_OutputIter __unique_copy(_InputIter __first, _InputIter __last, + _OutputIter __result, _Tp*) { + _Tp __value = *__first; + *__result = __value; + while (++__first != __last) + if (__value != *__first) { + __value = *__first; + *++__result = __value; + } + return ++__result; +} + +template +inline _OutputIter __unique_copy(_InputIter __first, _InputIter __last, + _OutputIter __result, + output_iterator_tag) { + return __unique_copy(__first, __last, __result, __VALUE_TYPE(__first)); +} + +template +_ForwardIter __unique_copy(_InputIter __first, _InputIter __last, + _ForwardIter __result, forward_iterator_tag) { + *__result = *__first; + while (++__first != __last) + if (*__result != *__first) *++__result = *__first; + return ++__result; +} + +template +inline _OutputIter unique_copy(_InputIter __first, _InputIter __last, + _OutputIter __result) { + if (__first == __last) return __result; + return __unique_copy(__first, __last, __result, + __ITERATOR_CATEGORY(__result)); +} + +template +_OutputIter __unique_copy(_InputIter __first, _InputIter __last, + _OutputIter __result, + _BinaryPredicate __binary_pred, _Tp*) { + _Tp __value = *__first; + *__result = __value; + while (++__first != __last) + if (!__binary_pred(__value, *__first)) { + __value = *__first; + *++__result = __value; + } + return ++__result; +} + +template +inline _OutputIter __unique_copy(_InputIter __first, _InputIter __last, + _OutputIter __result, + _BinaryPredicate __binary_pred, + output_iterator_tag) { + return __unique_copy(__first, __last, __result, __binary_pred, + __VALUE_TYPE(__first)); +} + +template +_ForwardIter __unique_copy(_InputIter __first, _InputIter __last, + _ForwardIter __result, + _BinaryPredicate __binary_pred, + forward_iterator_tag) { + *__result = *__first; + while (++__first != __last) + if (!__binary_pred(*__result, *__first)) *++__result = *__first; + return ++__result; +} + +template +inline _OutputIter unique_copy(_InputIter __first, _InputIter __last, + _OutputIter __result, + _BinaryPredicate __binary_pred) { + if (__first == __last) return __result; + return __unique_copy(__first, __last, __result, __binary_pred, + __ITERATOR_CATEGORY(__result)); +} + +template +_ForwardIter unique(_ForwardIter __first, _ForwardIter __last) { + __first = adjacent_find(__first, __last); + return unique_copy(__first, __last, __first); +} + +template +_ForwardIter unique(_ForwardIter __first, _ForwardIter __last, + _BinaryPredicate __binary_pred) { + __first = adjacent_find(__first, __last, __binary_pred); + return unique_copy(__first, __last, __first, __binary_pred); +} + +// reverse and reverse_copy, and their auxiliary functions + +template +void __reverse(_BidirectionalIter __first, _BidirectionalIter __last, + bidirectional_iterator_tag) { + while (true) + if (__first == __last || __first == --__last) + return; + else + iter_swap(__first++, __last); +} + +template +void __reverse(_RandomAccessIter __first, _RandomAccessIter __last, + random_access_iterator_tag) { + while (__first < __last) + iter_swap(__first++, --__last); +} + +template +inline void reverse(_BidirectionalIter __first, _BidirectionalIter __last) { + __reverse(__first, __last, __ITERATOR_CATEGORY(__first)); +} + +template +_OutputIter reverse_copy(_BidirectionalIter __first, + _BidirectionalIter __last, + _OutputIter __result) { + while (__first != __last) { + --__last; + *__result = *__last; + ++__result; + } + return __result; +} + +// rotate and rotate_copy, and their auxiliary functions + +template +_EuclideanRingElement __gcd(_EuclideanRingElement __m, + _EuclideanRingElement __n) +{ + while (__n != 0) { + _EuclideanRingElement __t = __m % __n; + __m = __n; + __n = __t; + } + return __m; +} + +template +_ForwardIter __rotate(_ForwardIter __first, + _ForwardIter __middle, + _ForwardIter __last, + _Distance*, + forward_iterator_tag) { + if (__first == __middle) + return __last; + if (__last == __middle) + return __first; + + _ForwardIter __first2 = __middle; + do { + swap(*__first++, *__first2++); + if (__first == __middle) + __middle = __first2; + } while (__first2 != __last); + + _ForwardIter __new_middle = __first; + + __first2 = __middle; + + while (__first2 != __last) { + swap (*__first++, *__first2++); + if (__first == __middle) + __middle = __first2; + else if (__first2 == __last) + __first2 = __middle; + } + + return __new_middle; +} + + +template +_BidirectionalIter __rotate(_BidirectionalIter __first, + _BidirectionalIter __middle, + _BidirectionalIter __last, + _Distance*, + bidirectional_iterator_tag) { + if (__first == __middle) + return __last; + if (__last == __middle) + return __first; + + __reverse(__first, __middle, bidirectional_iterator_tag()); + __reverse(__middle, __last, bidirectional_iterator_tag()); + + while (__first != __middle && __middle != __last) + swap (*__first++, *--__last); + + if (__first == __middle) { + __reverse(__middle, __last, bidirectional_iterator_tag()); + return __last; + } + else { + __reverse(__first, __middle, bidirectional_iterator_tag()); + return __first; + } +} + +template +_RandomAccessIter __rotate(_RandomAccessIter __first, + _RandomAccessIter __middle, + _RandomAccessIter __last, + _Distance *, _Tp *) { + + _Distance __n = __last - __first; + _Distance __k = __middle - __first; + _Distance __l = __n - __k; + _RandomAccessIter __result = __first + (__last - __middle); + + if (__k == __l) { + swap_ranges(__first, __middle, __middle); + return __result; + } + + _Distance __d = __gcd(__n, __k); + + for (_Distance __i = 0; __i < __d; __i++) { + _Tp __tmp = *__first; + _RandomAccessIter __p = __first; + + if (__k < __l) { + for (_Distance __j = 0; __j < __l/__d; __j++) { + if (__p > __first + __l) { + *__p = *(__p - __l); + __p -= __l; + } + + *__p = *(__p + __k); + __p += __k; + } + } + + else { + for (_Distance __j = 0; __j < __k/__d - 1; __j ++) { + if (__p < __last - __k) { + *__p = *(__p + __k); + __p += __k; + } + + *__p = * (__p - __l); + __p -= __l; + } + } + + *__p = __tmp; + ++__first; + } + + return __result; +} + +template +inline _ForwardIter rotate(_ForwardIter __first, _ForwardIter __middle, + _ForwardIter __last) { + return __rotate(__first, __middle, __last, + __DISTANCE_TYPE(__first), + __ITERATOR_CATEGORY(__first)); +} + +template +_OutputIter rotate_copy(_ForwardIter __first, _ForwardIter __middle, + _ForwardIter __last, _OutputIter __result) { + return copy(__first, __middle, copy(__middle, __last, __result)); +} + +// Return a random number in the range [0, __n). This function encapsulates +// whether we're using rand (part of the standard C library) or lrand48 +// (not standard, but a much better choice whenever it's available). + +template +inline _Distance __random_number(_Distance __n) { +#ifdef __STL_NO_DRAND48 + return rand() % __n; +#else + return lrand48() % __n; +#endif +} + +// random_shuffle + +template +inline void random_shuffle(_RandomAccessIter __first, + _RandomAccessIter __last) { + if (__first == __last) return; + for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i) + iter_swap(__i, __first + __random_number((__i - __first) + 1)); +} + +template +void random_shuffle(_RandomAccessIter __first, _RandomAccessIter __last, + _RandomNumberGenerator& __rand) { + if (__first == __last) return; + for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i) + iter_swap(__i, __first + __rand((__i - __first) + 1)); +} + +// random_sample and random_sample_n (extensions, not part of the standard). + +template +_OutputIter random_sample_n(_ForwardIter __first, _ForwardIter __last, + _OutputIter __out, const _Distance __n) +{ + _Distance __remaining = 0; + distance(__first, __last, __remaining); + _Distance __m = min(__n, __remaining); + + while (__m > 0) { + if (__random_number(__remaining) < __m) { + *__out = *__first; + ++__out; + --__m; + } + + --__remaining; + ++__first; + } + return __out; +} + +template +_OutputIter random_sample_n(_ForwardIter __first, _ForwardIter __last, + _OutputIter __out, const _Distance __n, + _RandomNumberGenerator& __rand) +{ + _Distance __remaining = 0; + distance(__first, __last, __remaining); + _Distance __m = min(__n, __remaining); + + while (__m > 0) { + if (__rand(__remaining) < __m) { + *__out = *__first; + ++__out; + --__m; + } + + --__remaining; + ++__first; + } + return __out; +} + +template +_RandomAccessIter __random_sample(_InputIter __first, _InputIter __last, + _RandomAccessIter __out, + const _Distance __n) +{ + _Distance __m = 0; + _Distance __t = __n; + for ( ; __first != __last && __m < __n; ++__m, ++__first) + __out[__m] = *__first; + + while (__first != __last) { + ++__t; + _Distance __M = __random_number(__t); + if (__M < __n) + __out[__M] = *__first; + ++__first; + } + + return __out + __m; +} + +template +_RandomAccessIter __random_sample(_InputIter __first, _InputIter __last, + _RandomAccessIter __out, + _RandomNumberGenerator& __rand, + const _Distance __n) +{ + _Distance __m = 0; + _Distance __t = __n; + for ( ; __first != __last && __m < __n; ++__m, ++__first) + __out[__m] = *__first; + + while (__first != __last) { + ++__t; + _Distance __M = __rand(__t); + if (__M < __n) + __out[__M] = *__first; + ++__first; + } + + return __out + __m; +} + +template +inline _RandomAccessIter +random_sample(_InputIter __first, _InputIter __last, + _RandomAccessIter __out_first, _RandomAccessIter __out_last) +{ + return __random_sample(__first, __last, + __out_first, __out_last - __out_first); +} + + +template +inline _RandomAccessIter +random_sample(_InputIter __first, _InputIter __last, + _RandomAccessIter __out_first, _RandomAccessIter __out_last, + _RandomNumberGenerator& __rand) +{ + return __random_sample(__first, __last, + __out_first, __rand, + __out_last - __out_first); +} + +// partition, stable_partition, and their auxiliary functions + +template +_ForwardIter __partition(_ForwardIter __first, + _ForwardIter __last, + _Predicate __pred, + forward_iterator_tag) { + if (__first == __last) return __first; + + while (__pred(*__first)) + if (++__first == __last) return __first; + + _ForwardIter __next = __first; + + while (++__next != __last) + if (__pred(*__next)) { + swap(*__first, *__next); + ++__first; + } + + return __first; +} + +template +_BidirectionalIter __partition(_BidirectionalIter __first, + _BidirectionalIter __last, + _Predicate __pred, + bidirectional_iterator_tag) { + while (true) { + while (true) + if (__first == __last) + return __first; + else if (__pred(*__first)) + ++__first; + else + break; + --__last; + while (true) + if (__first == __last) + return __first; + else if (!__pred(*__last)) + --__last; + else + break; + iter_swap(__first, __last); + ++__first; + } +} + +template +inline _ForwardIter partition(_ForwardIter __first, + _ForwardIter __last, + _Predicate __pred) { + return __partition(__first, __last, __pred, __ITERATOR_CATEGORY(__first)); +} + + +template +_ForwardIter __inplace_stable_partition(_ForwardIter __first, + _ForwardIter __last, + _Predicate __pred, _Distance __len) { + if (__len == 1) + return __pred(*__first) ? __last : __first; + _ForwardIter __middle = __first; + advance(__middle, __len / 2); + return rotate(__inplace_stable_partition(__first, __middle, __pred, + __len / 2), + __middle, + __inplace_stable_partition(__middle, __last, __pred, + __len - __len / 2)); +} + +template +_ForwardIter __stable_partition_adaptive(_ForwardIter __first, + _ForwardIter __last, + _Predicate __pred, _Distance __len, + _Pointer __buffer, + _Distance __buffer_size) +{ + if (__len <= __buffer_size) { + _ForwardIter __result1 = __first; + _Pointer __result2 = __buffer; + for ( ; __first != __last ; ++__first) + if (__pred(*__first)) { + *__result1 = *__first; + ++__result1; + } + else { + *__result2 = *__first; + ++__result2; + } + copy(__buffer, __result2, __result1); + return __result1; + } + else { + _ForwardIter __middle = __first; + advance(__middle, __len / 2); + return rotate(__stable_partition_adaptive( + __first, __middle, __pred, + __len / 2, __buffer, __buffer_size), + __middle, + __stable_partition_adaptive( + __middle, __last, __pred, + __len - __len / 2, __buffer, __buffer_size)); + } +} + +template +inline _ForwardIter +__stable_partition_aux(_ForwardIter __first, _ForwardIter __last, + _Predicate __pred, _Tp*, _Distance*) +{ + _Temporary_buffer<_ForwardIter, _Tp> __buf(__first, __last); + if (__buf.size() > 0) + return __stable_partition_adaptive(__first, __last, __pred, + _Distance(__buf.requested_size()), + __buf.begin(), __buf.size()); + else + return __inplace_stable_partition(__first, __last, __pred, + _Distance(__buf.requested_size())); +} + +template +inline _ForwardIter stable_partition(_ForwardIter __first, + _ForwardIter __last, + _Predicate __pred) { + if (__first == __last) + return __first; + else + return __stable_partition_aux(__first, __last, __pred, + __VALUE_TYPE(__first), + __DISTANCE_TYPE(__first)); +} + +template +_RandomAccessIter __unguarded_partition(_RandomAccessIter __first, + _RandomAccessIter __last, + _Tp __pivot) +{ + while (true) { + while (*__first < __pivot) + ++__first; + --__last; + while (__pivot < *__last) + --__last; + if (!(__first < __last)) + return __first; + iter_swap(__first, __last); + ++__first; + } +} + +template +_RandomAccessIter __unguarded_partition(_RandomAccessIter __first, + _RandomAccessIter __last, + _Tp __pivot, _Compare __comp) +{ + while (true) { + while (__comp(*__first, __pivot)) + ++__first; + --__last; + while (__comp(__pivot, *__last)) + --__last; + if (!(__first < __last)) + return __first; + iter_swap(__first, __last); + ++__first; + } +} + +const int __stl_threshold = 16; + +// sort() and its auxiliary functions. + +template +void __unguarded_linear_insert(_RandomAccessIter __last, _Tp __val) { + _RandomAccessIter __next = __last; + --__next; + while (__val < *__next) { + *__last = *__next; + __last = __next; + --__next; + } + *__last = __val; +} + +template +void __unguarded_linear_insert(_RandomAccessIter __last, _Tp __val, + _Compare __comp) { + _RandomAccessIter __next = __last; + --__next; + while (__comp(__val, *__next)) { + *__last = *__next; + __last = __next; + --__next; + } + *__last = __val; +} + +template +inline void __linear_insert(_RandomAccessIter __first, + _RandomAccessIter __last, _Tp*) { + _Tp __val = *__last; + if (__val < *__first) { + copy_backward(__first, __last, __last + 1); + *__first = __val; + } + else + __unguarded_linear_insert(__last, __val); +} + +template +inline void __linear_insert(_RandomAccessIter __first, + _RandomAccessIter __last, _Tp*, _Compare __comp) { + _Tp __val = *__last; + if (__comp(__val, *__first)) { + copy_backward(__first, __last, __last + 1); + *__first = __val; + } + else + __unguarded_linear_insert(__last, __val, __comp); +} + +template +void __insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last) { + if (__first == __last) return; + for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i) + __linear_insert(__first, __i, __VALUE_TYPE(__first)); +} + +template +void __insertion_sort(_RandomAccessIter __first, + _RandomAccessIter __last, _Compare __comp) { + if (__first == __last) return; + for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i) + __linear_insert(__first, __i, __VALUE_TYPE(__first), __comp); +} + +template +void __unguarded_insertion_sort_aux(_RandomAccessIter __first, + _RandomAccessIter __last, _Tp*) { + for (_RandomAccessIter __i = __first; __i != __last; ++__i) + __unguarded_linear_insert(__i, _Tp(*__i)); +} + +template +inline void __unguarded_insertion_sort(_RandomAccessIter __first, + _RandomAccessIter __last) { + __unguarded_insertion_sort_aux(__first, __last, __VALUE_TYPE(__first)); +} + +template +void __unguarded_insertion_sort_aux(_RandomAccessIter __first, + _RandomAccessIter __last, + _Tp*, _Compare __comp) { + for (_RandomAccessIter __i = __first; __i != __last; ++__i) + __unguarded_linear_insert(__i, _Tp(*__i), __comp); +} + +template +inline void __unguarded_insertion_sort(_RandomAccessIter __first, + _RandomAccessIter __last, + _Compare __comp) { + __unguarded_insertion_sort_aux(__first, __last, __VALUE_TYPE(__first), + __comp); +} + +template +void __final_insertion_sort(_RandomAccessIter __first, + _RandomAccessIter __last) { + if (__last - __first > __stl_threshold) { + __insertion_sort(__first, __first + __stl_threshold); + __unguarded_insertion_sort(__first + __stl_threshold, __last); + } + else + __insertion_sort(__first, __last); +} + +template +void __final_insertion_sort(_RandomAccessIter __first, + _RandomAccessIter __last, _Compare __comp) { + if (__last - __first > __stl_threshold) { + __insertion_sort(__first, __first + __stl_threshold, __comp); + __unguarded_insertion_sort(__first + __stl_threshold, __last, __comp); + } + else + __insertion_sort(__first, __last, __comp); +} + +template +inline _Size __lg(_Size __n) { + _Size __k; + for (__k = 0; __n != 1; __n >>= 1) ++__k; + return __k; +} + +template +void __introsort_loop(_RandomAccessIter __first, + _RandomAccessIter __last, _Tp*, + _Size __depth_limit) +{ + while (__last - __first > __stl_threshold) { + if (__depth_limit == 0) { + partial_sort(__first, __last, __last); + return; + } + --__depth_limit; + _RandomAccessIter __cut = + __unguarded_partition(__first, __last, + _Tp(__median(*__first, + *(__first + (__last - __first)/2), + *(__last - 1)))); + __introsort_loop(__cut, __last, (_Tp*) 0, __depth_limit); + __last = __cut; + } +} + +template +void __introsort_loop(_RandomAccessIter __first, + _RandomAccessIter __last, _Tp*, + _Size __depth_limit, _Compare __comp) +{ + while (__last - __first > __stl_threshold) { + if (__depth_limit == 0) { + partial_sort(__first, __last, __last, __comp); + return; + } + --__depth_limit; + _RandomAccessIter __cut = + __unguarded_partition(__first, __last, + _Tp(__median(*__first, + *(__first + (__last - __first)/2), + *(__last - 1), __comp)), + __comp); + __introsort_loop(__cut, __last, (_Tp*) 0, __depth_limit, __comp); + __last = __cut; + } +} + +template +inline void sort(_RandomAccessIter __first, _RandomAccessIter __last) { + if (__first != __last) { + __introsort_loop(__first, __last, + __VALUE_TYPE(__first), + __lg(__last - __first) * 2); + __final_insertion_sort(__first, __last); + } +} + +template +inline void sort(_RandomAccessIter __first, _RandomAccessIter __last, + _Compare __comp) { + if (__first != __last) { + __introsort_loop(__first, __last, + __VALUE_TYPE(__first), + __lg(__last - __first) * 2, + __comp); + __final_insertion_sort(__first, __last, __comp); + } +} + +// stable_sort() and its auxiliary functions. + +template +void __inplace_stable_sort(_RandomAccessIter __first, + _RandomAccessIter __last) { + if (__last - __first < 15) { + __insertion_sort(__first, __last); + return; + } + _RandomAccessIter __middle = __first + (__last - __first) / 2; + __inplace_stable_sort(__first, __middle); + __inplace_stable_sort(__middle, __last); + __merge_without_buffer(__first, __middle, __last, + __middle - __first, + __last - __middle); +} + +template +void __inplace_stable_sort(_RandomAccessIter __first, + _RandomAccessIter __last, _Compare __comp) { + if (__last - __first < 15) { + __insertion_sort(__first, __last, __comp); + return; + } + _RandomAccessIter __middle = __first + (__last - __first) / 2; + __inplace_stable_sort(__first, __middle, __comp); + __inplace_stable_sort(__middle, __last, __comp); + __merge_without_buffer(__first, __middle, __last, + __middle - __first, + __last - __middle, + __comp); +} + +template +void __merge_sort_loop(_RandomAccessIter1 __first, + _RandomAccessIter1 __last, + _RandomAccessIter2 __result, _Distance __step_size) { + _Distance __two_step = 2 * __step_size; + + while (__last - __first >= __two_step) { + __result = merge(__first, __first + __step_size, + __first + __step_size, __first + __two_step, + __result); + __first += __two_step; + } + + __step_size = min(_Distance(__last - __first), __step_size); + merge(__first, __first + __step_size, __first + __step_size, __last, + __result); +} + +template +void __merge_sort_loop(_RandomAccessIter1 __first, + _RandomAccessIter1 __last, + _RandomAccessIter2 __result, _Distance __step_size, + _Compare __comp) { + _Distance __two_step = 2 * __step_size; + + while (__last - __first >= __two_step) { + __result = merge(__first, __first + __step_size, + __first + __step_size, __first + __two_step, + __result, + __comp); + __first += __two_step; + } + __step_size = min(_Distance(__last - __first), __step_size); + + merge(__first, __first + __step_size, + __first + __step_size, __last, + __result, + __comp); +} + +const int __stl_chunk_size = 7; + +template +void __chunk_insertion_sort(_RandomAccessIter __first, + _RandomAccessIter __last, _Distance __chunk_size) +{ + while (__last - __first >= __chunk_size) { + __insertion_sort(__first, __first + __chunk_size); + __first += __chunk_size; + } + __insertion_sort(__first, __last); +} + +template +void __chunk_insertion_sort(_RandomAccessIter __first, + _RandomAccessIter __last, + _Distance __chunk_size, _Compare __comp) +{ + while (__last - __first >= __chunk_size) { + __insertion_sort(__first, __first + __chunk_size, __comp); + __first += __chunk_size; + } + __insertion_sort(__first, __last, __comp); +} + +template +void __merge_sort_with_buffer(_RandomAccessIter __first, + _RandomAccessIter __last, + _Pointer __buffer, _Distance*) { + _Distance __len = __last - __first; + _Pointer __buffer_last = __buffer + __len; + + _Distance __step_size = __stl_chunk_size; + __chunk_insertion_sort(__first, __last, __step_size); + + while (__step_size < __len) { + __merge_sort_loop(__first, __last, __buffer, __step_size); + __step_size *= 2; + __merge_sort_loop(__buffer, __buffer_last, __first, __step_size); + __step_size *= 2; + } +} + +template +void __merge_sort_with_buffer(_RandomAccessIter __first, + _RandomAccessIter __last, _Pointer __buffer, + _Distance*, _Compare __comp) { + _Distance __len = __last - __first; + _Pointer __buffer_last = __buffer + __len; + + _Distance __step_size = __stl_chunk_size; + __chunk_insertion_sort(__first, __last, __step_size, __comp); + + while (__step_size < __len) { + __merge_sort_loop(__first, __last, __buffer, __step_size, __comp); + __step_size *= 2; + __merge_sort_loop(__buffer, __buffer_last, __first, __step_size, __comp); + __step_size *= 2; + } +} + +template +void __stable_sort_adaptive(_RandomAccessIter __first, + _RandomAccessIter __last, _Pointer __buffer, + _Distance __buffer_size) { + _Distance __len = (__last - __first + 1) / 2; + _RandomAccessIter __middle = __first + __len; + if (__len > __buffer_size) { + __stable_sort_adaptive(__first, __middle, __buffer, __buffer_size); + __stable_sort_adaptive(__middle, __last, __buffer, __buffer_size); + } + else { + __merge_sort_with_buffer(__first, __middle, __buffer, (_Distance*)0); + __merge_sort_with_buffer(__middle, __last, __buffer, (_Distance*)0); + } + __merge_adaptive(__first, __middle, __last, _Distance(__middle - __first), + _Distance(__last - __middle), __buffer, __buffer_size); +} + +template +void __stable_sort_adaptive(_RandomAccessIter __first, + _RandomAccessIter __last, _Pointer __buffer, + _Distance __buffer_size, _Compare __comp) { + _Distance __len = (__last - __first + 1) / 2; + _RandomAccessIter __middle = __first + __len; + if (__len > __buffer_size) { + __stable_sort_adaptive(__first, __middle, __buffer, __buffer_size, + __comp); + __stable_sort_adaptive(__middle, __last, __buffer, __buffer_size, + __comp); + } + else { + __merge_sort_with_buffer(__first, __middle, __buffer, (_Distance*)0, + __comp); + __merge_sort_with_buffer(__middle, __last, __buffer, (_Distance*)0, + __comp); + } + __merge_adaptive(__first, __middle, __last, _Distance(__middle - __first), + _Distance(__last - __middle), __buffer, __buffer_size, + __comp); +} + +template +inline void __stable_sort_aux(_RandomAccessIter __first, + _RandomAccessIter __last, _Tp*, _Distance*) { + _Temporary_buffer<_RandomAccessIter, _Tp> buf(__first, __last); + if (buf.begin() == 0) + __inplace_stable_sort(__first, __last); + else + __stable_sort_adaptive(__first, __last, buf.begin(), + _Distance(buf.size())); +} + +template +inline void __stable_sort_aux(_RandomAccessIter __first, + _RandomAccessIter __last, _Tp*, _Distance*, + _Compare __comp) { + _Temporary_buffer<_RandomAccessIter, _Tp> buf(__first, __last); + if (buf.begin() == 0) + __inplace_stable_sort(__first, __last, __comp); + else + __stable_sort_adaptive(__first, __last, buf.begin(), + _Distance(buf.size()), + __comp); +} + +template +inline void stable_sort(_RandomAccessIter __first, + _RandomAccessIter __last) { + __stable_sort_aux(__first, __last, + __VALUE_TYPE(__first), + __DISTANCE_TYPE(__first)); +} + +template +inline void stable_sort(_RandomAccessIter __first, + _RandomAccessIter __last, _Compare __comp) { + __stable_sort_aux(__first, __last, + __VALUE_TYPE(__first), + __DISTANCE_TYPE(__first), + __comp); +} + +// partial_sort, partial_sort_copy, and auxiliary functions. + +template +void __partial_sort(_RandomAccessIter __first, _RandomAccessIter __middle, + _RandomAccessIter __last, _Tp*) { + make_heap(__first, __middle); + for (_RandomAccessIter __i = __middle; __i < __last; ++__i) + if (*__i < *__first) + __pop_heap(__first, __middle, __i, _Tp(*__i), + __DISTANCE_TYPE(__first)); + sort_heap(__first, __middle); +} + +template +inline void partial_sort(_RandomAccessIter __first, + _RandomAccessIter __middle, + _RandomAccessIter __last) { + __partial_sort(__first, __middle, __last, __VALUE_TYPE(__first)); +} + +template +void __partial_sort(_RandomAccessIter __first, _RandomAccessIter __middle, + _RandomAccessIter __last, _Tp*, _Compare __comp) { + make_heap(__first, __middle, __comp); + for (_RandomAccessIter __i = __middle; __i < __last; ++__i) + if (__comp(*__i, *__first)) + __pop_heap(__first, __middle, __i, _Tp(*__i), __comp, + __DISTANCE_TYPE(__first)); + sort_heap(__first, __middle, __comp); +} + +template +inline void partial_sort(_RandomAccessIter __first, + _RandomAccessIter __middle, + _RandomAccessIter __last, _Compare __comp) { + __partial_sort(__first, __middle, __last, __VALUE_TYPE(__first), __comp); +} + +template +_RandomAccessIter __partial_sort_copy(_InputIter __first, + _InputIter __last, + _RandomAccessIter __result_first, + _RandomAccessIter __result_last, + _Distance*, _Tp*) { + if (__result_first == __result_last) return __result_last; + _RandomAccessIter __result_real_last = __result_first; + while(__first != __last && __result_real_last != __result_last) { + *__result_real_last = *__first; + ++__result_real_last; + ++__first; + } + make_heap(__result_first, __result_real_last); + while (__first != __last) { + if (*__first < *__result_first) + __adjust_heap(__result_first, _Distance(0), + _Distance(__result_real_last - __result_first), + _Tp(*__first)); + ++__first; + } + sort_heap(__result_first, __result_real_last); + return __result_real_last; +} + +template +inline _RandomAccessIter +partial_sort_copy(_InputIter __first, _InputIter __last, + _RandomAccessIter __result_first, + _RandomAccessIter __result_last) { + return __partial_sort_copy(__first, __last, __result_first, __result_last, + __DISTANCE_TYPE(__result_first), + __VALUE_TYPE(__first)); +} + +template +_RandomAccessIter __partial_sort_copy(_InputIter __first, + _InputIter __last, + _RandomAccessIter __result_first, + _RandomAccessIter __result_last, + _Compare __comp, _Distance*, _Tp*) { + if (__result_first == __result_last) return __result_last; + _RandomAccessIter __result_real_last = __result_first; + while(__first != __last && __result_real_last != __result_last) { + *__result_real_last = *__first; + ++__result_real_last; + ++__first; + } + make_heap(__result_first, __result_real_last, __comp); + while (__first != __last) { + if (__comp(*__first, *__result_first)) + __adjust_heap(__result_first, _Distance(0), + _Distance(__result_real_last - __result_first), + _Tp(*__first), + __comp); + ++__first; + } + sort_heap(__result_first, __result_real_last, __comp); + return __result_real_last; +} + +template +inline _RandomAccessIter +partial_sort_copy(_InputIter __first, _InputIter __last, + _RandomAccessIter __result_first, + _RandomAccessIter __result_last, _Compare __comp) { + return __partial_sort_copy(__first, __last, __result_first, __result_last, + __comp, + __DISTANCE_TYPE(__result_first), + __VALUE_TYPE(__first)); +} + +// nth_element() and its auxiliary functions. + +template +void __nth_element(_RandomAccessIter __first, _RandomAccessIter __nth, + _RandomAccessIter __last, _Tp*) { + while (__last - __first > 3) { + _RandomAccessIter __cut = + __unguarded_partition(__first, __last, + _Tp(__median(*__first, + *(__first + (__last - __first)/2), + *(__last - 1)))); + if (__cut <= __nth) + __first = __cut; + else + __last = __cut; + } + __insertion_sort(__first, __last); +} + +template +inline void nth_element(_RandomAccessIter __first, _RandomAccessIter __nth, + _RandomAccessIter __last) { + __nth_element(__first, __nth, __last, __VALUE_TYPE(__first)); +} + +template +void __nth_element(_RandomAccessIter __first, _RandomAccessIter __nth, + _RandomAccessIter __last, _Tp*, _Compare __comp) { + while (__last - __first > 3) { + _RandomAccessIter __cut = + __unguarded_partition(__first, __last, + _Tp(__median(*__first, + *(__first + (__last - __first)/2), + *(__last - 1), + __comp)), + __comp); + if (__cut <= __nth) + __first = __cut; + else + __last = __cut; + } + __insertion_sort(__first, __last, __comp); +} + +template +inline void nth_element(_RandomAccessIter __first, _RandomAccessIter __nth, + _RandomAccessIter __last, _Compare __comp) { + __nth_element(__first, __nth, __last, __VALUE_TYPE(__first), __comp); +} + + +// Binary search (lower_bound, upper_bound, equal_range, binary_search). + +template +_ForwardIter __lower_bound(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val, _Distance*) +{ + _Distance __len = 0; + distance(__first, __last, __len); + _Distance __half; + _ForwardIter __middle; + + while (__len > 0) { + __half = __len >> 1; + __middle = __first; + advance(__middle, __half); + if (*__middle < __val) { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + else + __len = __half; + } + return __first; +} + +template +inline _ForwardIter lower_bound(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val) { + return __lower_bound(__first, __last, __val, + __DISTANCE_TYPE(__first)); +} + +template +_ForwardIter __lower_bound(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val, _Compare __comp, _Distance*) +{ + _Distance __len = 0; + distance(__first, __last, __len); + _Distance __half; + _ForwardIter __middle; + + while (__len > 0) { + __half = __len >> 1; + __middle = __first; + advance(__middle, __half); + if (__comp(*__middle, __val)) { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + else + __len = __half; + } + return __first; +} + +template +inline _ForwardIter lower_bound(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val, _Compare __comp) { + return __lower_bound(__first, __last, __val, __comp, + __DISTANCE_TYPE(__first)); +} + +template +_ForwardIter __upper_bound(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val, _Distance*) +{ + _Distance __len = 0; + distance(__first, __last, __len); + _Distance __half; + _ForwardIter __middle; + + while (__len > 0) { + __half = __len >> 1; + __middle = __first; + advance(__middle, __half); + if (__val < *__middle) + __len = __half; + else { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + } + return __first; +} + +template +inline _ForwardIter upper_bound(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val) { + return __upper_bound(__first, __last, __val, + __DISTANCE_TYPE(__first)); +} + +template +_ForwardIter __upper_bound(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val, _Compare __comp, _Distance*) +{ + _Distance __len = 0; + distance(__first, __last, __len); + _Distance __half; + _ForwardIter __middle; + + while (__len > 0) { + __half = __len >> 1; + __middle = __first; + advance(__middle, __half); + if (__comp(__val, *__middle)) + __len = __half; + else { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + } + return __first; +} + +template +inline _ForwardIter upper_bound(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val, _Compare __comp) { + return __upper_bound(__first, __last, __val, __comp, + __DISTANCE_TYPE(__first)); +} + +template +pair<_ForwardIter, _ForwardIter> +__equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, + _Distance*) +{ + _Distance __len = 0; + distance(__first, __last, __len); + _Distance __half; + _ForwardIter __middle, __left, __right; + + while (__len > 0) { + __half = __len >> 1; + __middle = __first; + advance(__middle, __half); + if (*__middle < __val) { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + else if (__val < *__middle) + __len = __half; + else { + __left = lower_bound(__first, __middle, __val); + advance(__first, __len); + __right = upper_bound(++__middle, __first, __val); + return pair<_ForwardIter, _ForwardIter>(__left, __right); + } + } + return pair<_ForwardIter, _ForwardIter>(__first, __first); +} + +template +inline pair<_ForwardIter, _ForwardIter> +equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val) { + return __equal_range(__first, __last, __val, + __DISTANCE_TYPE(__first)); +} + +template +pair<_ForwardIter, _ForwardIter> +__equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, + _Compare __comp, _Distance*) +{ + _Distance __len = 0; + distance(__first, __last, __len); + _Distance __half; + _ForwardIter __middle, __left, __right; + + while (__len > 0) { + __half = __len >> 1; + __middle = __first; + advance(__middle, __half); + if (__comp(*__middle, __val)) { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + else if (__comp(__val, *__middle)) + __len = __half; + else { + __left = lower_bound(__first, __middle, __val, __comp); + advance(__first, __len); + __right = upper_bound(++__middle, __first, __val, __comp); + return pair<_ForwardIter, _ForwardIter>(__left, __right); + } + } + return pair<_ForwardIter, _ForwardIter>(__first, __first); +} + +template +inline pair<_ForwardIter, _ForwardIter> +equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, + _Compare __comp) { + return __equal_range(__first, __last, __val, __comp, + __DISTANCE_TYPE(__first)); +} + +template +bool binary_search(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val) { + _ForwardIter __i = lower_bound(__first, __last, __val); + return __i != __last && !(__val < *__i); +} + +template +bool binary_search(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val, + _Compare __comp) { + _ForwardIter __i = lower_bound(__first, __last, __val, __comp); + return __i != __last && !__comp(__val, *__i); +} + +// merge, with and without an explicitly supplied comparison function. + +template +_OutputIter merge(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result) { + while (__first1 != __last1 && __first2 != __last2) { + if (*__first2 < *__first1) { + *__result = *__first2; + ++__first2; + } + else { + *__result = *__first1; + ++__first1; + } + ++__result; + } + return copy(__first2, __last2, copy(__first1, __last1, __result)); +} + +template +_OutputIter merge(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result, _Compare __comp) { + while (__first1 != __last1 && __first2 != __last2) { + if (__comp(*__first2, *__first1)) { + *__result = *__first2; + ++__first2; + } + else { + *__result = *__first1; + ++__first1; + } + ++__result; + } + return copy(__first2, __last2, copy(__first1, __last1, __result)); +} + +// inplace_merge and its auxiliary functions. + +template +void __merge_without_buffer(_BidirectionalIter __first, + _BidirectionalIter __middle, + _BidirectionalIter __last, + _Distance __len1, _Distance __len2) { + if (__len1 == 0 || __len2 == 0) + return; + if (__len1 + __len2 == 2) { + if (*__middle < *__first) + iter_swap(__first, __middle); + return; + } + _BidirectionalIter __first_cut = __first; + _BidirectionalIter __second_cut = __middle; + _Distance __len11 = 0; + _Distance __len22 = 0; + if (__len1 > __len2) { + __len11 = __len1 / 2; + advance(__first_cut, __len11); + __second_cut = lower_bound(__middle, __last, *__first_cut); + distance(__middle, __second_cut, __len22); + } + else { + __len22 = __len2 / 2; + advance(__second_cut, __len22); + __first_cut = upper_bound(__first, __middle, *__second_cut); + distance(__first, __first_cut, __len11); + } + _BidirectionalIter __new_middle + = rotate(__first_cut, __middle, __second_cut); + __merge_without_buffer(__first, __first_cut, __new_middle, + __len11, __len22); + __merge_without_buffer(__new_middle, __second_cut, __last, __len1 - __len11, + __len2 - __len22); +} + +template +void __merge_without_buffer(_BidirectionalIter __first, + _BidirectionalIter __middle, + _BidirectionalIter __last, + _Distance __len1, _Distance __len2, + _Compare __comp) { + if (__len1 == 0 || __len2 == 0) + return; + if (__len1 + __len2 == 2) { + if (__comp(*__middle, *__first)) + iter_swap(__first, __middle); + return; + } + _BidirectionalIter __first_cut = __first; + _BidirectionalIter __second_cut = __middle; + _Distance __len11 = 0; + _Distance __len22 = 0; + if (__len1 > __len2) { + __len11 = __len1 / 2; + advance(__first_cut, __len11); + __second_cut = lower_bound(__middle, __last, *__first_cut, __comp); + distance(__middle, __second_cut, __len22); + } + else { + __len22 = __len2 / 2; + advance(__second_cut, __len22); + __first_cut = upper_bound(__first, __middle, *__second_cut, __comp); + distance(__first, __first_cut, __len11); + } + _BidirectionalIter __new_middle + = rotate(__first_cut, __middle, __second_cut); + __merge_without_buffer(__first, __first_cut, __new_middle, __len11, __len22, + __comp); + __merge_without_buffer(__new_middle, __second_cut, __last, __len1 - __len11, + __len2 - __len22, __comp); +} + +template +_BidirectionalIter1 __rotate_adaptive(_BidirectionalIter1 __first, + _BidirectionalIter1 __middle, + _BidirectionalIter1 __last, + _Distance __len1, _Distance __len2, + _BidirectionalIter2 __buffer, + _Distance __buffer_size) { + _BidirectionalIter2 __buffer_end; + if (__len1 > __len2 && __len2 <= __buffer_size) { + __buffer_end = copy(__middle, __last, __buffer); + copy_backward(__first, __middle, __last); + return copy(__buffer, __buffer_end, __first); + } + else if (__len1 <= __buffer_size) { + __buffer_end = copy(__first, __middle, __buffer); + copy(__middle, __last, __first); + return copy_backward(__buffer, __buffer_end, __last); + } + else + return rotate(__first, __middle, __last); +} + +template +_BidirectionalIter3 __merge_backward(_BidirectionalIter1 __first1, + _BidirectionalIter1 __last1, + _BidirectionalIter2 __first2, + _BidirectionalIter2 __last2, + _BidirectionalIter3 __result) { + if (__first1 == __last1) + return copy_backward(__first2, __last2, __result); + if (__first2 == __last2) + return copy_backward(__first1, __last1, __result); + --__last1; + --__last2; + while (true) { + if (*__last2 < *__last1) { + *--__result = *__last1; + if (__first1 == __last1) + return copy_backward(__first2, ++__last2, __result); + --__last1; + } + else { + *--__result = *__last2; + if (__first2 == __last2) + return copy_backward(__first1, ++__last1, __result); + --__last2; + } + } +} + +template +_BidirectionalIter3 __merge_backward(_BidirectionalIter1 __first1, + _BidirectionalIter1 __last1, + _BidirectionalIter2 __first2, + _BidirectionalIter2 __last2, + _BidirectionalIter3 __result, + _Compare __comp) { + if (__first1 == __last1) + return copy_backward(__first2, __last2, __result); + if (__first2 == __last2) + return copy_backward(__first1, __last1, __result); + --__last1; + --__last2; + while (true) { + if (__comp(*__last2, *__last1)) { + *--__result = *__last1; + if (__first1 == __last1) + return copy_backward(__first2, ++__last2, __result); + --__last1; + } + else { + *--__result = *__last2; + if (__first2 == __last2) + return copy_backward(__first1, ++__last1, __result); + --__last2; + } + } +} + +template +void __merge_adaptive(_BidirectionalIter __first, + _BidirectionalIter __middle, + _BidirectionalIter __last, + _Distance __len1, _Distance __len2, + _Pointer __buffer, _Distance __buffer_size) { + if (__len1 <= __len2 && __len1 <= __buffer_size) { + _Pointer __buffer_end = copy(__first, __middle, __buffer); + merge(__buffer, __buffer_end, __middle, __last, __first); + } + else if (__len2 <= __buffer_size) { + _Pointer __buffer_end = copy(__middle, __last, __buffer); + __merge_backward(__first, __middle, __buffer, __buffer_end, __last); + } + else { + _BidirectionalIter __first_cut = __first; + _BidirectionalIter __second_cut = __middle; + _Distance __len11 = 0; + _Distance __len22 = 0; + if (__len1 > __len2) { + __len11 = __len1 / 2; + advance(__first_cut, __len11); + __second_cut = lower_bound(__middle, __last, *__first_cut); + distance(__middle, __second_cut, __len22); + } + else { + __len22 = __len2 / 2; + advance(__second_cut, __len22); + __first_cut = upper_bound(__first, __middle, *__second_cut); + distance(__first, __first_cut, __len11); + } + _BidirectionalIter __new_middle = + __rotate_adaptive(__first_cut, __middle, __second_cut, __len1 - __len11, + __len22, __buffer, __buffer_size); + __merge_adaptive(__first, __first_cut, __new_middle, __len11, + __len22, __buffer, __buffer_size); + __merge_adaptive(__new_middle, __second_cut, __last, __len1 - __len11, + __len2 - __len22, __buffer, __buffer_size); + } +} + +template +void __merge_adaptive(_BidirectionalIter __first, + _BidirectionalIter __middle, + _BidirectionalIter __last, + _Distance __len1, _Distance __len2, + _Pointer __buffer, _Distance __buffer_size, + _Compare __comp) { + if (__len1 <= __len2 && __len1 <= __buffer_size) { + _Pointer __buffer_end = copy(__first, __middle, __buffer); + merge(__buffer, __buffer_end, __middle, __last, __first, __comp); + } + else if (__len2 <= __buffer_size) { + _Pointer __buffer_end = copy(__middle, __last, __buffer); + __merge_backward(__first, __middle, __buffer, __buffer_end, __last, + __comp); + } + else { + _BidirectionalIter __first_cut = __first; + _BidirectionalIter __second_cut = __middle; + _Distance __len11 = 0; + _Distance __len22 = 0; + if (__len1 > __len2) { + __len11 = __len1 / 2; + advance(__first_cut, __len11); + __second_cut = lower_bound(__middle, __last, *__first_cut, __comp); + distance(__middle, __second_cut, __len22); + } + else { + __len22 = __len2 / 2; + advance(__second_cut, __len22); + __first_cut = upper_bound(__first, __middle, *__second_cut, __comp); + distance(__first, __first_cut, __len11); + } + _BidirectionalIter __new_middle = + __rotate_adaptive(__first_cut, __middle, __second_cut, __len1 - __len11, + __len22, __buffer, __buffer_size); + __merge_adaptive(__first, __first_cut, __new_middle, __len11, + __len22, __buffer, __buffer_size, __comp); + __merge_adaptive(__new_middle, __second_cut, __last, __len1 - __len11, + __len2 - __len22, __buffer, __buffer_size, __comp); + } +} + +template +inline void __inplace_merge_aux(_BidirectionalIter __first, + _BidirectionalIter __middle, + _BidirectionalIter __last, _Tp*, _Distance*) { + _Distance __len1 = 0; + distance(__first, __middle, __len1); + _Distance __len2 = 0; + distance(__middle, __last, __len2); + + _Temporary_buffer<_BidirectionalIter, _Tp> __buf(__first, __last); + if (__buf.begin() == 0) + __merge_without_buffer(__first, __middle, __last, __len1, __len2); + else + __merge_adaptive(__first, __middle, __last, __len1, __len2, + __buf.begin(), _Distance(__buf.size())); +} + +template +inline void __inplace_merge_aux(_BidirectionalIter __first, + _BidirectionalIter __middle, + _BidirectionalIter __last, _Tp*, _Distance*, + _Compare __comp) { + _Distance __len1 = 0; + distance(__first, __middle, __len1); + _Distance __len2 = 0; + distance(__middle, __last, __len2); + + _Temporary_buffer<_BidirectionalIter, _Tp> __buf(__first, __last); + if (__buf.begin() == 0) + __merge_without_buffer(__first, __middle, __last, __len1, __len2, __comp); + else + __merge_adaptive(__first, __middle, __last, __len1, __len2, + __buf.begin(), _Distance(__buf.size()), + __comp); +} + +template +inline void inplace_merge(_BidirectionalIter __first, + _BidirectionalIter __middle, + _BidirectionalIter __last) { + if (__first == __middle || __middle == __last) + return; + __inplace_merge_aux(__first, __middle, __last, + __VALUE_TYPE(__first), __DISTANCE_TYPE(__first)); +} + +template +inline void inplace_merge(_BidirectionalIter __first, + _BidirectionalIter __middle, + _BidirectionalIter __last, _Compare __comp) { + if (__first == __middle || __middle == __last) + return; + __inplace_merge_aux(__first, __middle, __last, + __VALUE_TYPE(__first), __DISTANCE_TYPE(__first), + __comp); +} + +// Set algorithms: includes, set_union, set_intersection, set_difference, +// set_symmetric_difference. All of these algorithms have the precondition +// that their input ranges are sorted and the postcondition that their output +// ranges are sorted. + +template +bool includes(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2) { + while (__first1 != __last1 && __first2 != __last2) + if (*__first2 < *__first1) + return false; + else if(*__first1 < *__first2) + ++__first1; + else + ++__first1, ++__first2; + + return __first2 == __last2; +} + +template +bool includes(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, _Compare __comp) { + while (__first1 != __last1 && __first2 != __last2) + if (__comp(*__first2, *__first1)) + return false; + else if(__comp(*__first1, *__first2)) + ++__first1; + else + ++__first1, ++__first2; + + return __first2 == __last2; +} + +template +_OutputIter set_union(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result) { + while (__first1 != __last1 && __first2 != __last2) { + if (*__first1 < *__first2) { + *__result = *__first1; + ++__first1; + } + else if (*__first2 < *__first1) { + *__result = *__first2; + ++__first2; + } + else { + *__result = *__first1; + ++__first1; + ++__first2; + } + ++__result; + } + return copy(__first2, __last2, copy(__first1, __last1, __result)); +} + +template +_OutputIter set_union(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result, _Compare __comp) { + while (__first1 != __last1 && __first2 != __last2) { + if (__comp(*__first1, *__first2)) { + *__result = *__first1; + ++__first1; + } + else if (__comp(*__first2, *__first1)) { + *__result = *__first2; + ++__first2; + } + else { + *__result = *__first1; + ++__first1; + ++__first2; + } + ++__result; + } + return copy(__first2, __last2, copy(__first1, __last1, __result)); +} + +template +_OutputIter set_intersection(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result) { + while (__first1 != __last1 && __first2 != __last2) + if (*__first1 < *__first2) + ++__first1; + else if (*__first2 < *__first1) + ++__first2; + else { + *__result = *__first1; + ++__first1; + ++__first2; + ++__result; + } + return __result; +} + +template +_OutputIter set_intersection(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result, _Compare __comp) { + while (__first1 != __last1 && __first2 != __last2) + if (__comp(*__first1, *__first2)) + ++__first1; + else if (__comp(*__first2, *__first1)) + ++__first2; + else { + *__result = *__first1; + ++__first1; + ++__first2; + ++__result; + } + return __result; +} + +template +_OutputIter set_difference(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result) { + while (__first1 != __last1 && __first2 != __last2) + if (*__first1 < *__first2) { + *__result = *__first1; + ++__first1; + ++__result; + } + else if (*__first2 < *__first1) + ++__first2; + else { + ++__first1; + ++__first2; + } + return copy(__first1, __last1, __result); +} + +template +_OutputIter set_difference(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result, _Compare __comp) { + while (__first1 != __last1 && __first2 != __last2) + if (__comp(*__first1, *__first2)) { + *__result = *__first1; + ++__first1; + ++__result; + } + else if (__comp(*__first2, *__first1)) + ++__first2; + else { + ++__first1; + ++__first2; + } + return copy(__first1, __last1, __result); +} + +template +_OutputIter +set_symmetric_difference(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result) { + while (__first1 != __last1 && __first2 != __last2) + if (*__first1 < *__first2) { + *__result = *__first1; + ++__first1; + ++__result; + } + else if (*__first2 < *__first1) { + *__result = *__first2; + ++__first2; + ++__result; + } + else { + ++__first1; + ++__first2; + } + return copy(__first2, __last2, copy(__first1, __last1, __result)); +} + +template +_OutputIter +set_symmetric_difference(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result, + _Compare __comp) { + while (__first1 != __last1 && __first2 != __last2) + if (__comp(*__first1, *__first2)) { + *__result = *__first1; + ++__first1; + ++__result; + } + else if (__comp(*__first2, *__first1)) { + *__result = *__first2; + ++__first2; + ++__result; + } + else { + ++__first1; + ++__first2; + } + return copy(__first2, __last2, copy(__first1, __last1, __result)); +} + +// min_element and max_element, with and without an explicitly supplied +// comparison function. + +template +_ForwardIter max_element(_ForwardIter __first, _ForwardIter __last) { + if (__first == __last) return __first; + _ForwardIter __result = __first; + while (++__first != __last) + if (*__result < *__first) + __result = __first; + return __result; +} + +template +_ForwardIter max_element(_ForwardIter __first, _ForwardIter __last, + _Compare __comp) { + if (__first == __last) return __first; + _ForwardIter __result = __first; + while (++__first != __last) + if (__comp(*__result, *__first)) __result = __first; + return __result; +} + +template +_ForwardIter min_element(_ForwardIter __first, _ForwardIter __last) { + if (__first == __last) return __first; + _ForwardIter __result = __first; + while (++__first != __last) + if (*__first < *__result) + __result = __first; + return __result; +} + +template +_ForwardIter min_element(_ForwardIter __first, _ForwardIter __last, + _Compare __comp) { + if (__first == __last) return __first; + _ForwardIter __result = __first; + while (++__first != __last) + if (__comp(*__first, *__result)) + __result = __first; + return __result; +} + +// next_permutation and prev_permutation, with and without an explicitly +// supplied comparison function. + +template +bool next_permutation(_BidirectionalIter __first, _BidirectionalIter __last) { + if (__first == __last) + return false; + _BidirectionalIter __i = __first; + ++__i; + if (__i == __last) + return false; + __i = __last; + --__i; + + for(;;) { + _BidirectionalIter __ii = __i; + --__i; + if (*__i < *__ii) { + _BidirectionalIter __j = __last; + while (!(*__i < *--__j)) + {} + iter_swap(__i, __j); + reverse(__ii, __last); + return true; + } + if (__i == __first) { + reverse(__first, __last); + return false; + } + } +} + +template +bool next_permutation(_BidirectionalIter __first, _BidirectionalIter __last, + _Compare __comp) { + if (__first == __last) + return false; + _BidirectionalIter __i = __first; + ++__i; + if (__i == __last) + return false; + __i = __last; + --__i; + + for(;;) { + _BidirectionalIter __ii = __i; + --__i; + if (__comp(*__i, *__ii)) { + _BidirectionalIter __j = __last; + while (!__comp(*__i, *--__j)) + {} + iter_swap(__i, __j); + reverse(__ii, __last); + return true; + } + if (__i == __first) { + reverse(__first, __last); + return false; + } + } +} + +template +bool prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last) { + if (__first == __last) + return false; + _BidirectionalIter __i = __first; + ++__i; + if (__i == __last) + return false; + __i = __last; + --__i; + + for(;;) { + _BidirectionalIter __ii = __i; + --__i; + if (*__ii < *__i) { + _BidirectionalIter __j = __last; + while (!(*--__j < *__i)) + {} + iter_swap(__i, __j); + reverse(__ii, __last); + return true; + } + if (__i == __first) { + reverse(__first, __last); + return false; + } + } +} + +template +bool prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last, + _Compare __comp) { + if (__first == __last) + return false; + _BidirectionalIter __i = __first; + ++__i; + if (__i == __last) + return false; + __i = __last; + --__i; + + for(;;) { + _BidirectionalIter __ii = __i; + --__i; + if (__comp(*__ii, *__i)) { + _BidirectionalIter __j = __last; + while (!__comp(*--__j, *__i)) + {} + iter_swap(__i, __j); + reverse(__ii, __last); + return true; + } + if (__i == __first) { + reverse(__first, __last); + return false; + } + } +} + +// find_first_of, with and without an explicitly supplied comparison function. + +template +_InputIter find_first_of(_InputIter __first1, _InputIter __last1, + _ForwardIter __first2, _ForwardIter __last2) +{ + for ( ; __first1 != __last1; ++__first1) + for (_ForwardIter __iter = __first2; __iter != __last2; ++__iter) + if (*__first1 == *__iter) + return __first1; + return __last1; +} + +template +_InputIter find_first_of(_InputIter __first1, _InputIter __last1, + _ForwardIter __first2, _ForwardIter __last2, + _BinaryPredicate __comp) +{ + for ( ; __first1 != __last1; ++__first1) + for (_ForwardIter __iter = __first2; __iter != __last2; ++__iter) + if (__comp(*__first1, *__iter)) + return __first1; + return __last1; +} + + +// find_end, with and without an explicitly supplied comparison function. +// Search [first2, last2) as a subsequence in [first1, last1), and return +// the *last* possible match. Note that find_end for bidirectional iterators +// is much faster than for forward iterators. + +// find_end for forward iterators. +template +_ForwardIter1 __find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, + _ForwardIter2 __first2, _ForwardIter2 __last2, + forward_iterator_tag, forward_iterator_tag) +{ + if (__first2 == __last2) + return __last1; + else { + _ForwardIter1 __result = __last1; + while (1) { + _ForwardIter1 __new_result + = search(__first1, __last1, __first2, __last2); + if (__new_result == __last1) + return __result; + else { + __result = __new_result; + __first1 = __new_result; + ++__first1; + } + } + } +} + +template +_ForwardIter1 __find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, + _ForwardIter2 __first2, _ForwardIter2 __last2, + forward_iterator_tag, forward_iterator_tag, + _BinaryPredicate __comp) +{ + if (__first2 == __last2) + return __last1; + else { + _ForwardIter1 __result = __last1; + while (1) { + _ForwardIter1 __new_result + = search(__first1, __last1, __first2, __last2, __comp); + if (__new_result == __last1) + return __result; + else { + __result = __new_result; + __first1 = __new_result; + ++__first1; + } + } + } +} + +// find_end for bidirectional iterators. Requires partial specialization. +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +_BidirectionalIter1 +__find_end(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1, + _BidirectionalIter2 __first2, _BidirectionalIter2 __last2, + bidirectional_iterator_tag, bidirectional_iterator_tag) +{ + typedef reverse_iterator<_BidirectionalIter1> _RevIter1; + typedef reverse_iterator<_BidirectionalIter2> _RevIter2; + + _RevIter1 __rlast1(__first1); + _RevIter2 __rlast2(__first2); + _RevIter1 __rresult = search(_RevIter1(__last1), __rlast1, + _RevIter2(__last2), __rlast2); + + if (__rresult == __rlast1) + return __last1; + else { + _BidirectionalIter1 __result = __rresult.base(); + advance(__result, -distance(__first2, __last2)); + return __result; + } +} + +template +_BidirectionalIter1 +__find_end(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1, + _BidirectionalIter2 __first2, _BidirectionalIter2 __last2, + bidirectional_iterator_tag, bidirectional_iterator_tag, + _BinaryPredicate __comp) +{ + typedef reverse_iterator<_BidirectionalIter1> _RevIter1; + typedef reverse_iterator<_BidirectionalIter2> _RevIter2; + + _RevIter1 __rlast1(__first1); + _RevIter2 __rlast2(__first2); + _RevIter1 __rresult = search(_RevIter1(__last1), __rlast1, + _RevIter2(__last2), __rlast2, + __comp); + + if (__rresult == __rlast1) + return __last1; + else { + _BidirectionalIter1 __result = __rresult.base(); + advance(__result, -distance(__first2, __last2)); + return __result; + } +} +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +// Dispatching functions for find_end. + +template +inline _ForwardIter1 +find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, + _ForwardIter2 __first2, _ForwardIter2 __last2) +{ + return __find_end(__first1, __last1, __first2, __last2, + __ITERATOR_CATEGORY(__first1), + __ITERATOR_CATEGORY(__first2)); +} + +template +inline _ForwardIter1 +find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, + _ForwardIter2 __first2, _ForwardIter2 __last2, + _BinaryPredicate __comp) +{ + return __find_end(__first1, __last1, __first2, __last2, + __ITERATOR_CATEGORY(__first1), + __ITERATOR_CATEGORY(__first2), + __comp); +} + +// 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 +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 +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; +} + +template +inline bool is_heap(_RandomAccessIter __first, _RandomAccessIter __last) +{ + return __is_heap(__first, __last - __first); +} + + +template +inline bool is_heap(_RandomAccessIter __first, _RandomAccessIter __last, + _StrictWeakOrdering __comp) +{ + return __is_heap(__first, __comp, __last - __first); +} + +// is_sorted, a predicated testing whether a range is sorted in +// nondescending order. This is an extension, not part of the C++ +// standard. + +template +bool is_sorted(_ForwardIter __first, _ForwardIter __last) +{ + if (__first == __last) + return true; + + _ForwardIter __next = __first; + for (++__next; __next != __last; __first = __next, ++__next) { + if (*__next < *__first) + return false; + } + + return true; +} + +template +bool is_sorted(_ForwardIter __first, _ForwardIter __last, + _StrictWeakOrdering __comp) +{ + if (__first == __last) + return true; + + _ForwardIter __next = __first; + for (++__next; __next != __last; __first = __next, ++__next) { + if (__comp(*__next, *__first)) + return false; + } + + return true; +} + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1209 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_ALGO_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/stl_algobase.h b/headers/cpp/stl_algobase.h new file mode 100644 index 0000000000..15e535f483 --- /dev/null +++ b/headers/cpp/stl_algobase.h @@ -0,0 +1,526 @@ +/* + * + * 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. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + + +#ifndef __SGI_STL_INTERNAL_ALGOBASE_H +#define __SGI_STL_INTERNAL_ALGOBASE_H + +#ifndef __STL_CONFIG_H +#include +#endif +#ifndef __SGI_STL_INTERNAL_RELOPS +#include +#endif +#ifndef __SGI_STL_INTERNAL_PAIR_H +#include +#endif +#ifndef __TYPE_TRAITS_H_ +#include +#endif + +#include +#include +#include +#include +#include +#include + +#ifndef __SGI_STL_INTERNAL_ITERATOR_H +#include +#endif + +__STL_BEGIN_NAMESPACE + +// swap and iter_swap + +template +inline void __iter_swap(_ForwardIter1 __a, _ForwardIter2 __b, _Tp*) { + _Tp __tmp = *__a; + *__a = *__b; + *__b = __tmp; +} + +template +inline void iter_swap(_ForwardIter1 __a, _ForwardIter2 __b) { + __iter_swap(__a, __b, __VALUE_TYPE(__a)); +} + +template +inline void swap(_Tp& __a, _Tp& __b) { + _Tp __tmp = __a; + __a = __b; + __b = __tmp; +} + +//-------------------------------------------------- +// min and max + +#ifndef __BORLANDC__ + +#undef min +#undef max + +template +inline const _Tp& min(const _Tp& __a, const _Tp& __b) { + return __b < __a ? __b : __a; +} + +template +inline const _Tp& max(const _Tp& __a, const _Tp& __b) { + return __a < __b ? __b : __a; +} + +#endif /* __BORLANDC__ */ + +template +inline const _Tp& min(const _Tp& __a, const _Tp& __b, _Compare __comp) { + return __comp(__b, __a) ? __b : __a; +} + +template +inline const _Tp& max(const _Tp& __a, const _Tp& __b, _Compare __comp) { + return __comp(__a, __b) ? __b : __a; +} + +//-------------------------------------------------- +// copy + +// All of these auxiliary functions serve two purposes. (1) Replace +// calls to copy with memmove whenever possible. (Memmove, not memcpy, +// because the input and output ranges are permitted to overlap.) +// (2) If we're using random access iterators, then write the loop as +// a for loop with an explicit count. The auxiliary class __copy_dispatch +// is a workaround for compilers that don't support partial ordering of +// function templates. + +template +inline _OutputIter __copy(_InputIter __first, _InputIter __last, + _OutputIter __result, + input_iterator_tag, _Distance*) +{ + for ( ; __first != __last; ++__result, ++__first) + *__result = *__first; + return __result; +} + +template +inline _OutputIter +__copy(_RandomAccessIter __first, _RandomAccessIter __last, + _OutputIter __result, random_access_iterator_tag, _Distance*) +{ + for (_Distance __n = __last - __first; __n > 0; --__n) { + *__result = *__first; + ++__first; + ++__result; + } + return __result; +} + +template +inline _Tp* +__copy_trivial(const _Tp* __first, const _Tp* __last, _Tp* __result) { + memmove(__result, __first, sizeof(_Tp) * (__last - __first)); + return __result + (__last - __first); +} + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +struct __copy_dispatch { + static _OutputIter copy(_InputIter __first, _InputIter __last, + _OutputIter __result) { + typedef typename iterator_traits<_InputIter>::iterator_category _Category; + typedef typename iterator_traits<_InputIter>::difference_type _Distance; + return __copy(__first, __last, __result, _Category(), (_Distance*) 0); + } +}; + +template +struct __copy_dispatch<_Tp*, _Tp*, __true_type> +{ + static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) { + return __copy_trivial(__first, __last, __result); + } +}; + +template +struct __copy_dispatch +{ + static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) { + return __copy_trivial(__first, __last, __result); + } +}; + +template +inline _OutputIter copy(_InputIter __first, _InputIter __last, + _OutputIter __result) { + typedef typename iterator_traits<_InputIter>::value_type _Tp; + typedef typename __type_traits<_Tp>::has_trivial_assignment_operator + _Trivial; + return __copy_dispatch<_InputIter, _OutputIter, _Trivial> + ::copy(__first, __last, __result); +} + +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template +inline _OutputIter copy(_InputIter __first, _InputIter __last, + _OutputIter __result) +{ + return __copy(__first, __last, __result, + __ITERATOR_CATEGORY(__first), + __DISTANCE_TYPE(__first)); +} + +inline char* copy(const char* __first, const char* __last, char* __result) { + memmove(__result, __first, __last - __first); + return __result + (__last - __first); +} + +inline wchar_t* copy(const wchar_t* __first, const wchar_t* __last, + wchar_t* __result) { + memmove(__result, __first, sizeof(wchar_t) * (__last - __first)); + return __result + (__last - __first); +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +//-------------------------------------------------- +// copy_backward + +template +inline _BidirectionalIter2 __copy_backward(_BidirectionalIter1 __first, + _BidirectionalIter1 __last, + _BidirectionalIter2 __result, + bidirectional_iterator_tag, + _Distance*) +{ + while (__first != __last) + *--__result = *--__last; + return __result; +} + +template +inline _BidirectionalIter __copy_backward(_RandomAccessIter __first, + _RandomAccessIter __last, + _BidirectionalIter __result, + random_access_iterator_tag, + _Distance*) +{ + for (_Distance __n = __last - __first; __n > 0; --__n) + *--__result = *--__last; + return __result; +} + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + +// This dispatch class is a workaround for compilers that do not +// have partial ordering of function templates. All we're doing is +// creating a specialization so that we can turn a call to copy_backward +// into a memmove whenever possible. + +template +struct __copy_backward_dispatch +{ + typedef typename iterator_traits<_BidirectionalIter1>::iterator_category + _Cat; + typedef typename iterator_traits<_BidirectionalIter1>::difference_type + _Distance; + + static _BidirectionalIter2 copy(_BidirectionalIter1 __first, + _BidirectionalIter1 __last, + _BidirectionalIter2 __result) { + return __copy_backward(__first, __last, __result, _Cat(), (_Distance*) 0); + } +}; + +template +struct __copy_backward_dispatch<_Tp*, _Tp*, __true_type> +{ + static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) { + const ptrdiff_t _Num = __last - __first; + memmove(__result - _Num, __first, sizeof(_Tp) * _Num); + return __result - _Num; + } +}; + +template +struct __copy_backward_dispatch +{ + static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) { + return __copy_backward_dispatch<_Tp*, _Tp*, __true_type> + ::copy(__first, __last, __result); + } +}; + +template +inline _BI2 copy_backward(_BI1 __first, _BI1 __last, _BI2 __result) { + typedef typename __type_traits::value_type> + ::has_trivial_assignment_operator + _Trivial; + return __copy_backward_dispatch<_BI1, _BI2, _Trivial> + ::copy(__first, __last, __result); +} + +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template +inline _BI2 copy_backward(_BI1 __first, _BI1 __last, _BI2 __result) { + return __copy_backward(__first, __last, __result, + __ITERATOR_CATEGORY(__first), + __DISTANCE_TYPE(__first)); +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +//-------------------------------------------------- +// copy_n (not part of the C++ standard) + +template +pair<_InputIter, _OutputIter> __copy_n(_InputIter __first, _Size __count, + _OutputIter __result, + input_iterator_tag) { + for ( ; __count > 0; --__count) { + *__result = *__first; + ++__first; + ++__result; + } + return pair<_InputIter, _OutputIter>(__first, __result); +} + +template +inline pair<_RAIter, _OutputIter> +__copy_n(_RAIter __first, _Size __count, + _OutputIter __result, + random_access_iterator_tag) { + _RAIter __last = __first + __count; + return pair<_RAIter, _OutputIter>(__last, copy(__first, __last, __result)); +} + +template +inline pair<_InputIter, _OutputIter> +__copy_n(_InputIter __first, _Size __count, _OutputIter __result) { + return __copy_n(__first, __count, __result, + __ITERATOR_CATEGORY(__first)); +} + +template +inline pair<_InputIter, _OutputIter> +copy_n(_InputIter __first, _Size __count, _OutputIter __result) { + return __copy_n(__first, __count, __result); +} + +//-------------------------------------------------- +// fill and fill_n + + +template +void fill(_ForwardIter __first, _ForwardIter __last, const _Tp& __value) { + for ( ; __first != __last; ++__first) + *__first = __value; +} + +template +_OutputIter fill_n(_OutputIter __first, _Size __n, const _Tp& __value) { + for ( ; __n > 0; --__n, ++__first) + *__first = __value; + return __first; +} + +//-------------------------------------------------- +// equal and mismatch + +template +pair<_InputIter1, _InputIter2> mismatch(_InputIter1 __first1, + _InputIter1 __last1, + _InputIter2 __first2) { + while (__first1 != __last1 && *__first1 == *__first2) { + ++__first1; + ++__first2; + } + return pair<_InputIter1, _InputIter2>(__first1, __first2); +} + +template +pair<_InputIter1, _InputIter2> mismatch(_InputIter1 __first1, + _InputIter1 __last1, + _InputIter2 __first2, + _BinaryPredicate __binary_pred) { + while (__first1 != __last1 && __binary_pred(*__first1, *__first2)) { + ++__first1; + ++__first2; + } + return pair<_InputIter1, _InputIter2>(__first1, __first2); +} + +template +inline bool equal(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2) { + for ( ; __first1 != __last1; ++__first1, ++__first2) + if (*__first1 != *__first2) + return false; + return true; +} + +template +inline bool equal(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _BinaryPredicate __binary_pred) { + for ( ; __first1 != __last1; ++__first1, ++__first2) + if (!__binary_pred(*__first1, *__first2)) + return false; + return true; +} + +//-------------------------------------------------- +// lexicographical_compare and lexicographical_compare_3way. +// (the latter is not part of the C++ standard.) + +template +bool lexicographical_compare(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2) { + for ( ; __first1 != __last1 && __first2 != __last2 + ; ++__first1, ++__first2) { + if (*__first1 < *__first2) + return true; + if (*__first2 < *__first1) + return false; + } + return __first1 == __last1 && __first2 != __last2; +} + +template +bool lexicographical_compare(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _Compare __comp) { + for ( ; __first1 != __last1 && __first2 != __last2 + ; ++__first1, ++__first2) { + if (__comp(*__first1, *__first2)) + return true; + if (__comp(*__first2, *__first1)) + return false; + } + return __first1 == __last1 && __first2 != __last2; +} + +inline bool +lexicographical_compare(const unsigned char* __first1, + const unsigned char* __last1, + const unsigned char* __first2, + const unsigned char* __last2) +{ + const size_t __len1 = __last1 - __first1; + const size_t __len2 = __last2 - __first2; + const int __result = memcmp(__first1, __first2, min(__len1, __len2)); + return __result != 0 ? __result < 0 : __len1 < __len2; +} + +inline bool lexicographical_compare(const char* __first1, const char* __last1, + const char* __first2, const char* __last2) +{ +#if CHAR_MAX == SCHAR_MAX + return lexicographical_compare((const signed char*) __first1, + (const signed char*) __last1, + (const signed char*) __first2, + (const signed char*) __last2); +#else /* CHAR_MAX == SCHAR_MAX */ + return lexicographical_compare((const unsigned char*) __first1, + (const unsigned char*) __last1, + (const unsigned char*) __first2, + (const unsigned char*) __last2); +#endif /* CHAR_MAX == SCHAR_MAX */ +} + +template +int __lexicographical_compare_3way(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2) +{ + while (__first1 != __last1 && __first2 != __last2) { + if (*__first1 < *__first2) + return -1; + if (*__first2 < *__first1) + return 1; + ++__first1; + ++__first2; + } + 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 = 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 +} + +template +int lexicographical_compare_3way(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2) +{ + return __lexicographical_compare_3way(__first1, __last1, __first2, __last2); +} + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_ALGOBASE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/stl_alloc.h b/headers/cpp/stl_alloc.h new file mode 100644 index 0000000000..f5d7e3f085 --- /dev/null +++ b/headers/cpp/stl_alloc.h @@ -0,0 +1,1070 @@ +/* + * 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. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_ALLOC_H +#define __SGI_STL_INTERNAL_ALLOC_H + +#ifdef __SUNPRO_CC +# define __PRIVATE public + // Extra access restrictions prevent us from really making some things + // private. +#else +# define __PRIVATE private +#endif + +#ifdef __STL_STATIC_TEMPLATE_MEMBER_BUG +# define __USE_MALLOC +#endif + + +// This implements some standard node allocators. These are +// NOT the same as the allocators in the C++ draft standard or in +// in the original STL. They do not encapsulate different pointer +// types; indeed we assume that there is only one pointer type. +// The allocation primitives are intended to allocate individual objects, +// not larger arenas as with the original STL allocators. + +#if 0 +# include +# define __THROW_BAD_ALLOC throw bad_alloc() +#elif !defined(__THROW_BAD_ALLOC) +#if __BEOS__ +# include +# define __THROW_BAD_ALLOC fprintf(stderr, "out of memory\n"); exit(1) +#else +# include +# define __THROW_BAD_ALLOC cerr << "out of memory" << endl; exit(1) +#endif +#endif + +#ifdef __STL_WIN32THREADS +# include +#endif + +#include +#include +#include +#include +#ifndef __RESTRICT +# define __RESTRICT +#endif + +#if !defined(__STL_PTHREADS) && !defined(__STL_SOLTHREADS) \ + && !defined(_NOTHREADS) \ + && !defined(__STL_SGI_THREADS) && !defined(__STL_WIN32THREADS) +# define _NOTHREADS +#endif + +# ifdef __STL_PTHREADS + // POSIX Threads + // This is dubious, since this is likely to be a high contention + // lock. Performance may not be adequate. +# include +# define __NODE_ALLOCATOR_LOCK \ + if (threads) pthread_mutex_lock(&_S_node_allocator_lock) +# define __NODE_ALLOCATOR_UNLOCK \ + if (threads) pthread_mutex_unlock(&_S_node_allocator_lock) +# define __NODE_ALLOCATOR_THREADS true +# define __VOLATILE volatile // Needed at -O3 on SGI +# endif +# ifdef __STL_SOLTHREADS +# include +# define __NODE_ALLOCATOR_LOCK \ + if (threads) mutex_lock(&_S_node_allocator_lock) +# define __NODE_ALLOCATOR_UNLOCK \ + if (threads) mutex_unlock(&_S_node_allocator_lock) +# define __NODE_ALLOCATOR_THREADS true +# define __VOLATILE +# endif +# ifdef __STL_WIN32THREADS + // The lock needs to be initialized by constructing an allocator + // objects of the right type. We do that here explicitly for alloc. +# define __NODE_ALLOCATOR_LOCK \ + EnterCriticalSection(&_S_node_allocator_lock) +# define __NODE_ALLOCATOR_UNLOCK \ + LeaveCriticalSection(&_S_node_allocator_lock) +# define __NODE_ALLOCATOR_THREADS true +# define __VOLATILE volatile // may not be needed +# endif /* WIN32THREADS */ +# ifdef __STL_SGI_THREADS + // This should work without threads, with sproc threads, or with + // pthreads. It is suboptimal in all cases. + // It is unlikely to even compile on nonSGI machines. + + extern "C" { + extern int __us_rsthread_malloc; + } + // The above is copied from malloc.h. Including + // would be cleaner but fails with certain levels of standard + // conformance. +# define __NODE_ALLOCATOR_LOCK if (threads && __us_rsthread_malloc) \ + { _S_lock(&_S_node_allocator_lock); } +# define __NODE_ALLOCATOR_UNLOCK if (threads && __us_rsthread_malloc) \ + { _S_unlock(&_S_node_allocator_lock); } +# define __NODE_ALLOCATOR_THREADS true +# define __VOLATILE volatile // Needed at -O3 on SGI +# endif +# ifdef _NOTHREADS +// Thread-unsafe +# define __NODE_ALLOCATOR_LOCK +# define __NODE_ALLOCATOR_UNLOCK +# define __NODE_ALLOCATOR_THREADS false +# define __VOLATILE +# endif + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1174 +#endif + +// Malloc-based allocator. Typically slower than default alloc below. +// Typically thread-safe and more storage efficient. +#ifdef __STL_STATIC_TEMPLATE_MEMBER_BUG +# ifdef __DECLARE_GLOBALS_HERE + void (* __malloc_alloc_oom_handler)() = 0; + // g++ 2.7.2 does not handle static template data members. +# else + extern void (* __malloc_alloc_oom_handler)(); +# endif +#endif + +template +class __malloc_alloc_template { + +private: + + static void* _S_oom_malloc(size_t); + static void* _S_oom_realloc(void*, size_t); + +#ifndef __STL_STATIC_TEMPLATE_MEMBER_BUG + static void (* __malloc_alloc_oom_handler)(); +#endif + +public: + + static void* allocate(size_t __n) + { + void* __result = malloc(__n); + if (0 == __result) __result = _S_oom_malloc(__n); + return __result; + } + + static void deallocate(void* __p, size_t /* __n */) + { + free(__p); + } + + static void* reallocate(void* __p, size_t /* old_sz */, size_t __new_sz) + { + void* __result = realloc(__p, __new_sz); + if (0 == __result) __result = _S_oom_realloc(__p, __new_sz); + return __result; + } + + static void (* __set_malloc_handler(void (*__f)()))() + { + void (* __old)() = __malloc_alloc_oom_handler; + __malloc_alloc_oom_handler = __f; + return(__old); + } + +}; + +// malloc_alloc out-of-memory handling + +#ifndef __STL_STATIC_TEMPLATE_MEMBER_BUG +template +void (* __malloc_alloc_template<__inst>::__malloc_alloc_oom_handler)() = 0; +#endif + +template +void* +__malloc_alloc_template<__inst>::_S_oom_malloc(size_t __n) +{ + void (* __my_malloc_handler)(); + void* __result; + + for (;;) { + __my_malloc_handler = __malloc_alloc_oom_handler; + if (0 == __my_malloc_handler) { __THROW_BAD_ALLOC; } + (*__my_malloc_handler)(); + __result = malloc(__n); + if (__result) return(__result); + } +} + +template +void* __malloc_alloc_template<__inst>::_S_oom_realloc(void* __p, size_t __n) +{ + void (* __my_malloc_handler)(); + void* __result; + + for (;;) { + __my_malloc_handler = __malloc_alloc_oom_handler; + if (0 == __my_malloc_handler) { __THROW_BAD_ALLOC; } + (*__my_malloc_handler)(); + __result = realloc(__p, __n); + if (__result) return(__result); + } +} + +typedef __malloc_alloc_template<0> malloc_alloc; + +template +class simple_alloc { + +public: + static _Tp* allocate(size_t __n) + { return 0 == __n ? 0 : (_Tp*) _Alloc::allocate(__n * sizeof (_Tp)); } + static _Tp* allocate(void) + { return (_Tp*) _Alloc::allocate(sizeof (_Tp)); } + static void deallocate(_Tp* __p, size_t __n) + { if (0 != __n) _Alloc::deallocate(__p, __n * sizeof (_Tp)); } + static void deallocate(_Tp* __p) + { _Alloc::deallocate(__p, sizeof (_Tp)); } +}; + +// Allocator adaptor to check size arguments for debugging. +// Reports errors using assert. Checking can be disabled with +// NDEBUG, but it's far better to just use the underlying allocator +// instead when no checking is desired. +// There is some evidence that this can confuse Purify. +template +class debug_alloc { + +private: + + enum {_S_extra = 8}; // Size of space used to store size. Note + // that this must be large enough to preserve + // alignment. + +public: + + static void* allocate(size_t __n) + { + char* __result = (char*)_Alloc::allocate(__n + _S_extra); + *(size_t*)__result = __n; + return __result + _S_extra; + } + + static void deallocate(void* __p, size_t __n) + { + char* __real_p = (char*)__p - _S_extra; + assert(*(size_t*)__real_p == __n); + _Alloc::deallocate(__real_p, __n + _S_extra); + } + + static void* reallocate(void* __p, size_t __old_sz, size_t __new_sz) + { + char* __real_p = (char*)__p - _S_extra; + assert(*(size_t*)__real_p == __old_sz); + char* __result = (char*) + _Alloc::reallocate(__real_p, __old_sz + _S_extra, __new_sz + _S_extra); + *(size_t*)__result = __new_sz; + return __result + _S_extra; + } + +}; + + +# ifdef __USE_MALLOC + +typedef malloc_alloc alloc; +typedef malloc_alloc single_client_alloc; + +# else + + +// Default node allocator. +// With a reasonable compiler, this should be roughly as fast as the +// original STL class-specific allocators, but with less fragmentation. +// Default_alloc_template parameters are experimental and MAY +// DISAPPEAR in the future. Clients should just use alloc for now. +// +// Important implementation properties: +// 1. If the client request an object of size > _MAX_BYTES, the resulting +// object will be obtained directly from malloc. +// 2. In all other cases, we allocate an object of size exactly +// _S_round_up(requested_size). Thus the client has enough size +// information that we can return the object to the proper free list +// without permanently losing part of the object. +// + +// The first template parameter specifies whether more than one thread +// may use this allocator. It is safe to allocate an object from +// one instance of a default_alloc and deallocate it with another +// one. This effectively transfers its ownership to the second one. +// This may have undesirable effects on reference locality. +// The second parameter is unreferenced and serves only to allow the +// creation of multiple default_alloc instances. +// Node that containers built on different allocator instances have +// different types, limiting the utility of this approach. +#ifdef __SUNPRO_CC +// breaks if we make these template class members: + enum {_ALIGN = 8}; + enum {_MAX_BYTES = 128}; + enum {_NFREELISTS = _MAX_BYTES/_ALIGN}; +#endif + +template +class __default_alloc_template { + +private: + // Really we should use static const int x = N + // instead of enum { x = N }, but few compilers accept the former. +# ifndef __SUNPRO_CC + enum {_ALIGN = 8}; +# if defined __BEOS__ + enum {_MAX_BYTES = 0}; +# else + enum {_MAX_BYTES = 128}; +# endif + enum {_NFREELISTS = _MAX_BYTES/_ALIGN}; +# endif + static size_t + _S_round_up(size_t __bytes) + { return (((__bytes) + _ALIGN-1) & ~(_ALIGN - 1)); } + +__PRIVATE: + union _Obj { + union _Obj* _M_free_list_link; + char _M_client_data[1]; /* The client sees this. */ + }; +private: +# ifdef __SUNPRO_CC + static _Obj* __VOLATILE _S_free_list[]; + // Specifying a size results in duplicate def for 4.1 +# else + static _Obj* __VOLATILE _S_free_list[_NFREELISTS]; +# endif + static size_t _S_freelist_index(size_t __bytes) { + return (((__bytes) + _ALIGN-1)/_ALIGN - 1); + } + + // Returns an object of size __n, and optionally adds to size __n free list. + static void* _S_refill(size_t __n); + // Allocates a chunk for nobjs of size "size". nobjs may be reduced + // if it is inconvenient to allocate the requested number. + static char* _S_chunk_alloc(size_t __size, int& __nobjs); + + // Chunk allocation state. + static char* _S_start_free; + static char* _S_end_free; + static size_t _S_heap_size; + +# ifdef __STL_SGI_THREADS + static volatile unsigned long _S_node_allocator_lock; + static void _S_lock(volatile unsigned long*); + static inline void _S_unlock(volatile unsigned long*); +# endif + +# ifdef __STL_PTHREADS + static pthread_mutex_t _S_node_allocator_lock; +# endif + +# ifdef __STL_SOLTHREADS + static mutex_t _S_node_allocator_lock; +# endif + +# ifdef __STL_WIN32THREADS + static CRITICAL_SECTION _S_node_allocator_lock; + static bool _S_node_allocator_lock_initialized; + + public: + __default_alloc_template() { + // This assumes the first constructor is called before threads + // are started. + if (!_S_node_allocator_lock_initialized) { + InitializeCriticalSection(&_S_node_allocator_lock); + _S_node_allocator_lock_initialized = true; + } + } + private: +# endif + + class _Lock { + public: + _Lock() { __NODE_ALLOCATOR_LOCK; } + ~_Lock() { __NODE_ALLOCATOR_UNLOCK; } + }; + friend class _Lock; + +public: + + /* __n must be > 0 */ + static void* allocate(size_t __n) + { + _Obj* __VOLATILE* __my_free_list; + _Obj* __RESTRICT __result; + + if (__n > (size_t) _MAX_BYTES) { + return(malloc_alloc::allocate(__n)); + } + __my_free_list = _S_free_list + _S_freelist_index(__n); + // Acquire the lock here with a constructor call. + // This ensures that it is released in exit or during stack + // unwinding. +# ifndef _NOTHREADS + /*REFERENCED*/ + _Lock __lock_instance; +# endif + __result = *__my_free_list; + if (__result == 0) { + void* __r = _S_refill(_S_round_up(__n)); + return __r; + } + *__my_free_list = __result -> _M_free_list_link; + return (__result); + }; + + /* __p may not be 0 */ + static void deallocate(void* __p, size_t __n) + { + _Obj* __q = (_Obj*)__p; + _Obj* __VOLATILE* __my_free_list; + + if (__n > (size_t) _MAX_BYTES) { + malloc_alloc::deallocate(__p, __n); + return; + } + __my_free_list = _S_free_list + _S_freelist_index(__n); + // acquire lock +# ifndef _NOTHREADS + /*REFERENCED*/ + _Lock __lock_instance; +# endif /* _NOTHREADS */ + __q -> _M_free_list_link = *__my_free_list; + *__my_free_list = __q; + // lock is released here + } + + static void* reallocate(void* __p, size_t __old_sz, size_t __new_sz); + +} ; + +typedef __default_alloc_template<__NODE_ALLOCATOR_THREADS, 0> alloc; +typedef __default_alloc_template single_client_alloc; + + + +/* We allocate memory in large chunks in order to avoid fragmenting */ +/* the malloc heap too much. */ +/* We assume that size is properly aligned. */ +/* We hold the allocation lock. */ +template +char* +__default_alloc_template<__threads, __inst>::_S_chunk_alloc(size_t __size, + int& __nobjs) +{ + char* __result; + size_t __total_bytes = __size * __nobjs; + size_t __bytes_left = _S_end_free - _S_start_free; + + if (__bytes_left >= __total_bytes) { + __result = _S_start_free; + _S_start_free += __total_bytes; + return(__result); + } else if (__bytes_left >= __size) { + __nobjs = (int)(__bytes_left/__size); + __total_bytes = __size * __nobjs; + __result = _S_start_free; + _S_start_free += __total_bytes; + return(__result); + } else { + size_t __bytes_to_get = + 2 * __total_bytes + _S_round_up(_S_heap_size >> 4); + // Try to make use of the left-over piece. + if (__bytes_left > 0) { + _Obj* __VOLATILE* __my_free_list = + _S_free_list + _S_freelist_index(__bytes_left); + + ((_Obj*)_S_start_free) -> _M_free_list_link = *__my_free_list; + *__my_free_list = (_Obj*)_S_start_free; + } + _S_start_free = (char*)malloc(__bytes_to_get); + if (0 == _S_start_free) { + size_t __i; + _Obj* __VOLATILE* __my_free_list; + _Obj* __p; + // Try to make do with what we have. That can't + // hurt. We do not try smaller requests, since that tends + // to result in disaster on multi-process machines. + for (__i = __size; __i <= _MAX_BYTES; __i += _ALIGN) { + __my_free_list = _S_free_list + _S_freelist_index(__i); + __p = *__my_free_list; + if (0 != __p) { + *__my_free_list = __p -> _M_free_list_link; + _S_start_free = (char*)__p; + _S_end_free = _S_start_free + __i; + return(_S_chunk_alloc(__size, __nobjs)); + // Any leftover piece will eventually make it to the + // right free list. + } + } + _S_end_free = 0; // In case of exception. + _S_start_free = (char*)malloc_alloc::allocate(__bytes_to_get); + // This should either throw an + // exception or remedy the situation. Thus we assume it + // succeeded. + } + _S_heap_size += __bytes_to_get; + _S_end_free = _S_start_free + __bytes_to_get; + return(_S_chunk_alloc(__size, __nobjs)); + } +} + + +/* Returns an object of size __n, and optionally adds to size __n free list.*/ +/* We assume that __n is properly aligned. */ +/* We hold the allocation lock. */ +template +void* +__default_alloc_template<__threads, __inst>::_S_refill(size_t __n) +{ + int __nobjs = 20; + char* __chunk = _S_chunk_alloc(__n, __nobjs); + _Obj* __VOLATILE* __my_free_list; + _Obj* __result; + _Obj* __current_obj; + _Obj* __next_obj; + int __i; + + if (1 == __nobjs) return(__chunk); + __my_free_list = _S_free_list + _S_freelist_index(__n); + + /* Build free list in chunk */ + __result = (_Obj*)__chunk; + *__my_free_list = __next_obj = (_Obj*)(__chunk + __n); + for (__i = 1; ; __i++) { + __current_obj = __next_obj; + __next_obj = (_Obj*)((char*)__next_obj + __n); + if (__nobjs - 1 == __i) { + __current_obj -> _M_free_list_link = 0; + break; + } else { + __current_obj -> _M_free_list_link = __next_obj; + } + } + return(__result); +} + +template +void* +__default_alloc_template::reallocate(void* __p, + size_t __old_sz, + size_t __new_sz) +{ + void* __result; + size_t __copy_sz; + + if (__old_sz > (size_t) _MAX_BYTES && __new_sz > (size_t) _MAX_BYTES) { + return(realloc(__p, __new_sz)); + } + if (_S_round_up(__old_sz) == _S_round_up(__new_sz)) return(__p); + __result = allocate(__new_sz); + __copy_sz = __new_sz > __old_sz? __old_sz : __new_sz; + memcpy(__result, __p, __copy_sz); + deallocate(__p, __old_sz); + return(__result); +} + +#ifdef __STL_PTHREADS + template + pthread_mutex_t + __default_alloc_template<__threads, __inst>::_S_node_allocator_lock + = PTHREAD_MUTEX_INITIALIZER; +#endif + +#ifdef __STL_SOLTHREADS + template + mutex_t + __default_alloc_template<__threads, __inst>::_S_node_allocator_lock + = DEFAULTMUTEX; +#endif + +#ifdef __STL_WIN32THREADS + template + CRITICAL_SECTION + __default_alloc_template<__threads, __inst>:: + _S_node_allocator_lock; + + template + bool + __default_alloc_template<__threads, __inst>:: + _S_node_allocator_lock_initialized + = false; +#endif + +#ifdef __STL_SGI_THREADS +__STL_END_NAMESPACE +#include +#include /* XXX should use */ +__STL_BEGIN_NAMESPACE +// Somewhat generic lock implementations. We need only test-and-set +// and some way to sleep. These should work with both SGI pthreads +// and sproc threads. They may be useful on other systems. +template +volatile unsigned long +__default_alloc_template<__threads, __inst>::_S_node_allocator_lock = 0; + +#if __mips < 3 || !(defined (_ABIN32) || defined(_ABI64)) || defined(__GNUC__) +# define __test_and_set(l,v) test_and_set(l,v) +#endif + +template +void +__default_alloc_template<__threads, __inst>:: + _S_lock(volatile unsigned long* __lock) +{ + const unsigned __low_spin_max = 30; // spins if we suspect uniprocessor + const unsigned __high_spin_max = 1000; // spins for multiprocessor + static unsigned __spin_max = __low_spin_max; + unsigned __my_spin_max; + static unsigned __last_spins = 0; + unsigned __my_last_spins; + unsigned __junk; +# define __ALLOC_PAUSE \ + __junk *= __junk; __junk *= __junk; __junk *= __junk; __junk *= __junk + int __i; + + if (!__test_and_set((unsigned long*)__lock, 1)) { + return; + } + __my_spin_max = __spin_max; + __my_last_spins = __last_spins; + for (__i = 0; __i < __my_spin_max; __i++) { + if (__i < __my_last_spins/2 || *__lock) { + __ALLOC_PAUSE; + continue; + } + if (!__test_and_set((unsigned long*)__lock, 1)) { + // got it! + // Spinning worked. Thus we're probably not being scheduled + // against the other process with which we were contending. + // Thus it makes sense to spin longer the next time. + __last_spins = __i; + __spin_max = __high_spin_max; + return; + } + } + // We are probably being scheduled against the other process. Sleep. + __spin_max = __low_spin_max; + for (__i = 0 ;; ++__i) { + struct timespec __ts; + int __log_nsec = __i + 6; + + if (!__test_and_set((unsigned long *)__lock, 1)) { + return; + } + if (__log_nsec > 27) __log_nsec = 27; + /* Max sleep is 2**27nsec ~ 60msec */ + __ts.tv_sec = 0; + __ts.tv_nsec = 1 << __log_nsec; + nanosleep(&__ts, 0); + } +} + +template +inline void +__default_alloc_template<__threads, __inst>::_S_unlock( + volatile unsigned long* __lock) +{ +# if defined(__GNUC__) && __mips >= 3 + asm("sync"); + *__lock = 0; +# elif __mips >= 3 && (defined (_ABIN32) || defined(_ABI64)) + __lock_release(__lock); +# else + *__lock = 0; + // This is not sufficient on many multiprocessors, since + // writes to protected variables and the lock may be reordered. +# endif +} +#endif + +template +char* __default_alloc_template<__threads, __inst>::_S_start_free = 0; + +template +char* __default_alloc_template<__threads, __inst>::_S_end_free = 0; + +template +size_t __default_alloc_template<__threads, __inst>::_S_heap_size = 0; + +template +__default_alloc_template<__threads, __inst>::_Obj* __VOLATILE +__default_alloc_template<__threads, __inst> ::_S_free_list[ + _NFREELISTS +#if defined __BEOS__ +] = { }; +#else +] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; +#endif +// The 16 zeros are necessary to make version 4.1 of the SunPro +// compiler happy. Otherwise it appears to allocate too little +// space for the array. + +# ifdef __STL_WIN32THREADS + // Create one to get critical section initialized. + // We do this onece per file, but only the first constructor + // does anything. + static alloc __node_allocator_dummy_instance; +# endif + +#endif /* ! __USE_MALLOC */ + +// This implements allocators as specified in the C++ standard. +// +// Note that standard-conforming allocators use many language features +// that are not yet widely implemented. In particular, they rely on +// member templates, partial specialization, partial ordering of function +// templates, the typename keyword, and the use of the template keyword +// to refer to a template member of a dependent type. + +#ifdef __STL_USE_STD_ALLOCATORS + +template +class allocator { + typedef alloc _Alloc; // The underlying allocator. +public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef _Tp value_type; + + template struct rebind { + typedef allocator<_Tp1> other; + }; + + allocator() __STL_NOTHROW {} + allocator(const allocator&) __STL_NOTHROW {} + template allocator(const allocator<_Tp1>&) __STL_NOTHROW {} + ~allocator() __STL_NOTHROW {} + + pointer address(reference __x) const { return &__x; } + const_pointer address(const_reference __x) const { return &__x; } + + // __n is permitted to be 0. The C++ standard says nothing about what + // the return value is when __n == 0. + _Tp* allocate(size_type __n, const void* = 0) { + return __n != 0 ? static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp))) + : 0; + } + + // __p is not permitted to be a null pointer. + void deallocate(pointer __p, size_type __n) + { _Alloc::deallocate(__p, __n * sizeof(_Tp)); } + + size_type max_size() const __STL_NOTHROW + { return size_t(-1) / sizeof(_Tp); } + + void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); } + void destroy(pointer __p) { __p->~_Tp(); } +}; + +template<> +class allocator { + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef void* pointer; + typedef const void* const_pointer; + typedef void value_type; + + template struct rebind { + typedef allocator<_Tp1> other; + }; +}; + + +template +inline bool operator==(const allocator<_T1>&, const allocator<_T2>&) +{ + return true; +} + +template +inline bool operator!=(const allocator<_T1>&, const allocator<_T2>&) +{ + return false; +} + +// Allocator adaptor to turn an SGI-style allocator (e.g. alloc, malloc_alloc) +// into a standard-conforming allocator. Note that this adaptor does +// *not* assume that all objects of the underlying alloc class are +// identical, nor does it assume that all of the underlying alloc's +// member functions are static member functions. Note, also, that +// __allocator<_Tp, alloc> is essentially the same thing as allocator<_Tp>. + +template +struct __allocator { + _Alloc __underlying_alloc; + + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef _Tp value_type; + + template struct rebind { + typedef __allocator<_Tp1, _Alloc> other; + }; + + __allocator() __STL_NOTHROW {} + __allocator(const __allocator& __a) __STL_NOTHROW + : __underlying_alloc(__a.__underlying_alloc) {} + template + __allocator(const __allocator<_Tp1, _Alloc>& __a) __STL_NOTHROW + : __underlying_alloc(__a.__underlying_alloc) {} + ~__allocator() __STL_NOTHROW {} + + pointer address(reference __x) const { return &__x; } + const_pointer address(const_reference __x) const { return &__x; } + + // __n is permitted to be 0. + _Tp* allocate(size_type __n, const void* = 0) { + return __n != 0 + ? static_cast<_Tp*>(__underlying_alloc.allocate(__n * sizeof(_Tp))) + : 0; + } + + // __p is not permitted to be a null pointer. + void deallocate(pointer __p, size_type __n) + { __underlying_alloc.deallocate(__p, __n * sizeof(_Tp)); } + + size_type max_size() const __STL_NOTHROW + { return size_t(-1) / sizeof(_Tp); } + + void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); } + void destroy(pointer __p) { __p->~_Tp(); } +}; + +template +class __allocator { + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef void* pointer; + typedef const void* const_pointer; + typedef void value_type; + + template struct rebind { + typedef __allocator<_Tp1, _Alloc> other; + }; +}; + +template +inline bool operator==(const __allocator<_Tp, _Alloc>& __a1, + const __allocator<_Tp, _Alloc>& __a2) +{ + return __a1.__underlying_alloc == __a2.__underlying_alloc; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER +template +inline bool operator!=(const __allocator<_Tp, _Alloc>& __a1, + const __allocator<_Tp, _Alloc>& __a2) +{ + return __a1.__underlying_alloc != __a2.__underlying_alloc; +} +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +// Comparison operators for all of the predifined SGI-style allocators. +// This ensures that __allocator (for example) will +// work correctly. + +template +inline bool operator==(const __malloc_alloc_template&, + const __malloc_alloc_template&) +{ + return true; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER +template +inline bool operator!=(const __malloc_alloc_template<__inst>&, + const __malloc_alloc_template<__inst>&) +{ + return false; +} +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +#ifndef __USE_MALLOC +template +inline bool operator==(const __default_alloc_template<__threads, __inst>&, + const __default_alloc_template<__threads, __inst>&) +{ + return true; +} + +# ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER +template +inline bool operator!=(const __default_alloc_template<__threads, __inst>&, + const __default_alloc_template<__threads, __inst>&) +{ + return false; +} +# endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ +#endif + +template +inline bool operator==(const debug_alloc<_Alloc>&, + const debug_alloc<_Alloc>&) { + return true; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER +template +inline bool operator!=(const debug_alloc<_Alloc>&, + const debug_alloc<_Alloc>&) { + return false; +} +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +// Another allocator adaptor: _Alloc_traits. This serves two +// purposes. First, make it possible to write containers that can use +// either SGI-style allocators or standard-conforming allocator. +// Second, provide a mechanism so that containers can query whether or +// not the allocator has distinct instances. If not, the container +// can avoid wasting a word of memory to store an empty object. + +// This adaptor uses partial specialization. The general case of +// _Alloc_traits<_Tp, _Alloc> assumes that _Alloc is a +// standard-conforming allocator, possibly with non-equal instances +// and non-static members. (It still behaves correctly even if _Alloc +// has static member and if all instances are equal. Refinements +// affect performance, not correctness.) + +// There are always two members: allocator_type, which is a standard- +// conforming allocator type for allocating objects of type _Tp, and +// _S_instanceless, a static const member of type bool. If +// _S_instanceless is true, this means that there is no difference +// between any two instances of type allocator_type. Furthermore, if +// _S_instanceless is true, then _Alloc_traits has one additional +// member: _Alloc_type. This type encapsulates allocation and +// deallocation of objects of type _Tp through a static interface; it +// has two member functions, whose signatures are +// static _Tp* allocate(size_t) +// static void deallocate(_Tp*, size_t) + +// The fully general version. + +template +struct _Alloc_traits +{ + static const bool _S_instanceless = false; + typedef typename _Allocator::__STL_TEMPLATE rebind<_Tp>::other + allocator_type; +}; + +template +const bool _Alloc_traits<_Tp, _Allocator>::_S_instanceless; + +// The version for the default allocator. + +template +struct _Alloc_traits<_Tp, allocator<_Tp1> > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, alloc> _Alloc_type; + typedef allocator<_Tp> allocator_type; +}; + +// Versions for the predefined SGI-style allocators. + +template +struct _Alloc_traits<_Tp, __malloc_alloc_template<__inst> > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, __malloc_alloc_template<__inst> > _Alloc_type; + typedef __allocator<_Tp, __malloc_alloc_template<__inst> > allocator_type; +}; + +#ifndef __USE_MALLOC +template +struct _Alloc_traits<_Tp, __default_alloc_template<__threads, __inst> > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, __default_alloc_template<__threads, __inst> > + _Alloc_type; + typedef __allocator<_Tp, __default_alloc_template<__threads, __inst> > + allocator_type; +}; +#endif + +template +struct _Alloc_traits<_Tp, debug_alloc<_Alloc> > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, debug_alloc<_Alloc> > _Alloc_type; + typedef __allocator<_Tp, debug_alloc<_Alloc> > allocator_type; +}; + +// Versions for the __allocator adaptor used with the predefined +// SGI-style allocators. + +template +struct _Alloc_traits<_Tp, + __allocator<_Tp1, __malloc_alloc_template<__inst> > > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, __malloc_alloc_template<__inst> > _Alloc_type; + typedef __allocator<_Tp, __malloc_alloc_template<__inst> > allocator_type; +}; + +#ifndef __USE_MALLOC +template +struct _Alloc_traits<_Tp, + __allocator<_Tp1, + __default_alloc_template<__thr, __inst> > > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, __default_alloc_template<__thr,__inst> > + _Alloc_type; + typedef __allocator<_Tp, __default_alloc_template<__thr,__inst> > + allocator_type; +}; +#endif + +template +struct _Alloc_traits<_Tp, __allocator<_Tp1, debug_alloc<_Alloc> > > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, debug_alloc<_Alloc> > _Alloc_type; + typedef __allocator<_Tp, debug_alloc<_Alloc> > allocator_type; +}; + + +#endif /* __STL_USE_STD_ALLOCATORS */ + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#endif + +__STL_END_NAMESPACE + +#undef __PRIVATE + +#endif /* __SGI_STL_INTERNAL_ALLOC_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/stl_bvector.h b/headers/cpp/stl_bvector.h new file mode 100644 index 0000000000..0d0cdb6c82 --- /dev/null +++ b/headers/cpp/stl_bvector.h @@ -0,0 +1,838 @@ +/* + * + * 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,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. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_BVECTOR_H +#define __SGI_STL_INTERNAL_BVECTOR_H + +__STL_BEGIN_NAMESPACE + +static const int __WORD_BIT = int(CHAR_BIT*sizeof(unsigned int)); + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1174 +#pragma set woff 1375 +#endif + +struct _Bit_reference { + unsigned int* _M_p; + unsigned int _M_mask; + _Bit_reference(unsigned int* __x, unsigned int __y) + : _M_p(__x), _M_mask(__y) {} + +public: + _Bit_reference() : _M_p(0), _M_mask(0) {} + operator bool() const { return !(!(*_M_p & _M_mask)); } + _Bit_reference& operator=(bool __x) + { + if (__x) *_M_p |= _M_mask; + else *_M_p &= ~_M_mask; + return *this; + } + _Bit_reference& operator=(const _Bit_reference& __x) + { return *this = bool(__x); } + bool operator==(const _Bit_reference& __x) const + { return bool(*this) == bool(__x); } + bool operator<(const _Bit_reference& __x) const { + return !bool(*this) && bool(__x); + } + void flip() { *_M_p ^= _M_mask; } +}; + +inline void swap(_Bit_reference __x, _Bit_reference __y) +{ + bool __tmp = __x; + __x = __y; + __y = __tmp; +} + +struct _Bit_iterator : public random_access_iterator { + typedef _Bit_reference reference; + typedef _Bit_reference* pointer; + typedef _Bit_iterator iterator; + + unsigned int* _M_p; + unsigned int _M_offset; + void bump_up() { + if (_M_offset++ == __WORD_BIT - 1) { + _M_offset = 0; + ++_M_p; + } + } + void bump_down() { + if (_M_offset-- == 0) { + _M_offset = __WORD_BIT - 1; + --_M_p; + } + } + + _Bit_iterator() : _M_p(0), _M_offset(0) {} + _Bit_iterator(unsigned int* __x, unsigned int __y) + : _M_p(__x), _M_offset(__y) {} + reference operator*() const { return reference(_M_p, 1U << _M_offset); } + iterator& operator++() { + bump_up(); + return *this; + } + iterator operator++(int) { + iterator __tmp = *this; + bump_up(); + return __tmp; + } + iterator& operator--() { + bump_down(); + return *this; + } + iterator operator--(int) { + iterator __tmp = *this; + bump_down(); + return __tmp; + } + iterator& operator+=(difference_type __i) { + difference_type __n = __i + _M_offset; + _M_p += __n / __WORD_BIT; + __n = __n % __WORD_BIT; + if (__n < 0) { + _M_offset = (unsigned int) __n + __WORD_BIT; + --_M_p; + } else + _M_offset = (unsigned int) __n; + return *this; + } + iterator& operator-=(difference_type __i) { + *this += -__i; + return *this; + } + iterator operator+(difference_type __i) const { + iterator __tmp = *this; + return __tmp += __i; + } + iterator operator-(difference_type __i) const { + iterator __tmp = *this; + return __tmp -= __i; + } + difference_type operator-(iterator __x) const { + return __WORD_BIT * (_M_p - __x._M_p) + _M_offset - __x._M_offset; + } + reference operator[](difference_type __i) { return *(*this + __i); } + bool operator==(const iterator& __x) const { + return _M_p == __x._M_p && _M_offset == __x._M_offset; + } + bool operator!=(const iterator& __x) const { + return _M_p != __x._M_p || _M_offset != __x._M_offset; + } + bool operator<(iterator __x) const { + return _M_p < __x._M_p || (_M_p == __x._M_p && _M_offset < __x._M_offset); + } +}; + +struct _Bit_const_iterator + : public random_access_iterator +{ + typedef bool reference; + typedef bool const_reference; + typedef const bool* pointer; + typedef _Bit_const_iterator const_iterator; + + unsigned int* _M_p; + unsigned int _M_offset; + void bump_up() { + if (_M_offset++ == __WORD_BIT - 1) { + _M_offset = 0; + ++_M_p; + } + } + void bump_down() { + if (_M_offset-- == 0) { + _M_offset = __WORD_BIT - 1; + --_M_p; + } + } + + _Bit_const_iterator() : _M_p(0), _M_offset(0) {} + _Bit_const_iterator(unsigned int* __x, unsigned int __y) + : _M_p(__x), _M_offset(__y) {} + _Bit_const_iterator(const _Bit_iterator& __x) + : _M_p(__x._M_p), _M_offset(__x._M_offset) {} + const_reference operator*() const { + return _Bit_reference(_M_p, 1U << _M_offset); + } + const_iterator& operator++() { + bump_up(); + return *this; + } + const_iterator operator++(int) { + const_iterator __tmp = *this; + bump_up(); + return __tmp; + } + const_iterator& operator--() { + bump_down(); + return *this; + } + const_iterator operator--(int) { + const_iterator __tmp = *this; + bump_down(); + return __tmp; + } + const_iterator& operator+=(difference_type __i) { + difference_type __n = __i + _M_offset; + _M_p += __n / __WORD_BIT; + __n = __n % __WORD_BIT; + if (__n < 0) { + _M_offset = (unsigned int) __n + __WORD_BIT; + --_M_p; + } else + _M_offset = (unsigned int) __n; + return *this; + } + const_iterator& operator-=(difference_type __i) { + *this += -__i; + return *this; + } + const_iterator operator+(difference_type __i) const { + const_iterator __tmp = *this; + return __tmp += __i; + } + const_iterator operator-(difference_type __i) const { + const_iterator __tmp = *this; + return __tmp -= __i; + } + difference_type operator-(const_iterator __x) const { + return __WORD_BIT * (_M_p - __x._M_p) + _M_offset - __x._M_offset; + } + const_reference operator[](difference_type __i) { + return *(*this + __i); + } + bool operator==(const const_iterator& __x) const { + return _M_p == __x._M_p && _M_offset == __x._M_offset; + } + bool operator!=(const const_iterator& __x) const { + return _M_p != __x._M_p || _M_offset != __x._M_offset; + } + bool operator<(const_iterator __x) const { + return _M_p < __x._M_p || (_M_p == __x._M_p && _M_offset < __x._M_offset); + } +}; + +// Bit-vector base class, which encapsulates the difference between +// old SGI-style allocators and standard-conforming allocators. + +#ifdef __STL_USE_STD_ALLOCATORS + +// Base class for ordinary allocators. +template +class _Bvector_alloc_base { +public: + typedef typename _Alloc_traits::allocator_type + allocator_type; + allocator_type get_allocator() const { return _M_data_allocator; } + + _Bvector_alloc_base(const allocator_type& __a) + : _M_data_allocator(__a), _M_start(), _M_finish(), _M_end_of_storage(0) {} + +protected: + unsigned int* _M_bit_alloc(size_t __n) + { return _M_data_allocator.allocate((__n + __WORD_BIT - 1)/__WORD_BIT); } + void _M_deallocate() { + if (_M_start._M_p) + _M_data_allocator.deallocate(_M_start._M_p, + _M_end_of_storage - _M_start._M_p); + } + + typename _Alloc_traits::allocator_type + _M_data_allocator; + _Bit_iterator _M_start; + _Bit_iterator _M_finish; + unsigned int* _M_end_of_storage; +}; + +// Specialization for instanceless allocators. +template +class _Bvector_alloc_base<_Allocator, true> { +public: + typedef typename _Alloc_traits::allocator_type + allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Bvector_alloc_base(const allocator_type&) + : _M_start(), _M_finish(), _M_end_of_storage(0) {} + +protected: + typedef typename _Alloc_traits::_Alloc_type + _Alloc_type; + + unsigned int* _M_bit_alloc(size_t __n) + { return _Alloc_type::allocate((__n + __WORD_BIT - 1)/__WORD_BIT); } + void _M_deallocate() { + if (_M_start._M_p) + _Alloc_type::deallocate(_M_start._M_p, + _M_end_of_storage - _M_start._M_p); + } + + _Bit_iterator _M_start; + _Bit_iterator _M_finish; + unsigned int* _M_end_of_storage; +}; + +template +class _Bvector_base + : public _Bvector_alloc_base<_Alloc, + _Alloc_traits::_S_instanceless> +{ + typedef _Bvector_alloc_base<_Alloc, + _Alloc_traits::_S_instanceless> + _Base; +public: + typedef typename _Base::allocator_type allocator_type; + + _Bvector_base(const allocator_type& __a) : _Base(__a) {} + ~_Bvector_base() { _Base::_M_deallocate(); } +}; + +#else /* __STL_USE_STD_ALLOCATORS */ + +template +class _Bvector_base +{ +public: + typedef _Alloc allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Bvector_base(const allocator_type&) + : _M_start(), _M_finish(), _M_end_of_storage(0) {} + ~_Bvector_base() { _M_deallocate(); } + +protected: + typedef simple_alloc _Alloc_type; + + unsigned int* _M_bit_alloc(size_t __n) + { return _Alloc_type::allocate((__n + __WORD_BIT - 1)/__WORD_BIT); } + void _M_deallocate() { + if (_M_start._M_p) + _Alloc_type::deallocate(_M_start._M_p, + _M_end_of_storage - _M_start._M_p); + } + + _Bit_iterator _M_start; + _Bit_iterator _M_finish; + unsigned int* _M_end_of_storage; +}; + +#endif /* __STL_USE_STD_ALLOCATORS */ + +// The next few lines are confusing. What we're doing is declaring a +// partial specialization of vector if we have the necessary +// compiler support. Otherwise, we define a class bit_vector which uses +// the default allocator. + +#if defined(__STL_CLASS_PARTIAL_SPECIALIZATION) && !defined(__STL_NO_BOOL) +#define __SGI_STL_VECBOOL_TEMPLATE +#define __BVECTOR vector +#else +#undef __SGI_STL_VECBOOL_TEMPLATE +#define __BVECTOR bit_vector +#endif + +# ifdef __SGI_STL_VECBOOL_TEMPLATE + __STL_END_NAMESPACE +# include + __STL_BEGIN_NAMESPACE +template class vector + : public _Bvector_base<_Alloc> +# else /* __SGI_STL_VECBOOL_TEMPLATE */ +class bit_vector + : public _Bvector_base<__STL_DEFAULT_ALLOCATOR(bool) > +# endif /* __SGI_STL_VECBOOL_TEMPLATE */ +{ +# ifdef __SGI_STL_VECBOOL_TEMPLATE + typedef _Bvector_base<_Alloc> _Base; +# else /* __SGI_STL_VECBOOL_TEMPLATE */ + typedef _Bvector_base<__STL_DEFAULT_ALLOCATOR(bool) > _Base; +# endif /* __SGI_STL_VECBOOL_TEMPLATE */ +public: + typedef bool value_type; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Bit_reference reference; + typedef bool const_reference; + typedef _Bit_reference* pointer; + typedef const bool* const_pointer; + + typedef _Bit_iterator iterator; + typedef _Bit_const_iterator const_iterator; + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + typedef reverse_iterator const_reverse_iterator; + typedef reverse_iterator reverse_iterator; +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + typedef reverse_iterator const_reverse_iterator; + typedef reverse_iterator + reverse_iterator; +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + + typedef typename _Base::allocator_type allocator_type; + allocator_type get_allocator() const { return _Base::get_allocator(); } + +protected: +#ifdef __STL_USE_NAMESPACES + using _Base::_M_bit_alloc; + using _Base::_M_deallocate; + using _Base::_M_start; + using _Base::_M_finish; + using _Base::_M_end_of_storage; +#endif /* __STL_USE_NAMESPACES */ + +protected: + void _M_initialize(size_type __n) { + unsigned int* __q = _M_bit_alloc(__n); + _M_end_of_storage = __q + (__n + __WORD_BIT - 1)/__WORD_BIT; + _M_start = iterator(__q, 0); + _M_finish = _M_start + difference_type(__n); + } + void _M_insert_aux(iterator __position, bool __x) { + if (_M_finish._M_p != _M_end_of_storage) { + copy_backward(__position, _M_finish, _M_finish + 1); + *__position = __x; + ++_M_finish; + } + else { + size_type __len = size() ? 2 * size() : __WORD_BIT; + unsigned int* __q = _M_bit_alloc(__len); + iterator __i = copy(begin(), __position, iterator(__q, 0)); + *__i++ = __x; + _M_finish = copy(__position, end(), __i); + _M_deallocate(); + _M_end_of_storage = __q + (__len + __WORD_BIT - 1)/__WORD_BIT; + _M_start = iterator(__q, 0); + } + } + +#ifdef __STL_MEMBER_TEMPLATES + template + void _M_initialize_range(_InputIterator __first, _InputIterator __last, + input_iterator_tag) { + _M_start = iterator(); + _M_finish = iterator(); + _M_end_of_storage = 0; + for ( ; __first != __last; ++__first) + push_back(*__first); + } + + template + void _M_initialize_range(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag) { + size_type __n = 0; + distance(__first, __last, __n); + _M_initialize(__n); + copy(__first, __last, _M_start); + } + + template + void _M_insert_range(iterator __pos, + _InputIterator __first, _InputIterator __last, + input_iterator_tag) { + for ( ; __first != __last; ++__first) { + __pos = insert(__pos, *__first); + ++__pos; + } + } + + template + void _M_insert_range(iterator __position, + _ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag) { + if (__first != __last) { + size_type __n = 0; + distance(__first, __last, __n); + if (capacity() - size() >= __n) { + copy_backward(__position, end(), _M_finish + difference_type(__n)); + copy(__first, __last, __position); + _M_finish += difference_type(__n); + } + else { + size_type __len = size() + max(size(), __n); + unsigned int* __q = _M_bit_alloc(__len); + iterator __i = copy(begin(), __position, iterator(__q, 0)); + __i = copy(__first, __last, __i); + _M_finish = copy(__position, end(), __i); + _M_deallocate(); + _M_end_of_storage = __q + (__len + __WORD_BIT - 1)/__WORD_BIT; + _M_start = iterator(__q, 0); + } + } + } + +#endif /* __STL_MEMBER_TEMPLATES */ + +public: + iterator begin() { return _M_start; } + const_iterator begin() const { return _M_start; } + iterator end() { return _M_finish; } + const_iterator end() const { return _M_finish; } + + reverse_iterator rbegin() { return reverse_iterator(end()); } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } + reverse_iterator rend() { return reverse_iterator(begin()); } + const_reverse_iterator rend() const { + return const_reverse_iterator(begin()); + } + + size_type size() const { return size_type(end() - begin()); } + size_type max_size() const { return size_type(-1); } + size_type capacity() const { + return size_type(const_iterator(_M_end_of_storage, 0) - begin()); + } + bool empty() const { return begin() == end(); } + reference operator[](size_type __n) { + return *(begin() + difference_type(__n)); + } + const_reference operator[](size_type __n) const { + return *(begin() + difference_type(__n)); + } + + explicit __BVECTOR(const allocator_type& __a = allocator_type()) + : _Base(__a) {} + + __BVECTOR(size_type __n, bool __value, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { + _M_initialize(__n); + fill(_M_start._M_p, _M_end_of_storage, __value ? ~0 : 0); + } + + explicit __BVECTOR(size_type __n) + : _Base(allocator_type()) + { + _M_initialize(__n); + fill(_M_start._M_p, _M_end_of_storage, 0); + } + + __BVECTOR(const __BVECTOR& __x) : _Base(__x.get_allocator()) { + _M_initialize(__x.size()); + copy(__x.begin(), __x.end(), _M_start); + } + +#ifdef __STL_MEMBER_TEMPLATES + // Check whether it's an integral type. If so, it's not an iterator. + template + __BVECTOR(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_initialize_dispatch(__first, __last, _Integral()); + } + + template + void _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) { + _M_initialize(__n); + fill(_M_start._M_p, _M_end_of_storage, __x ? ~0 : 0); + } + + template + void _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) { + _M_initialize_range(__first, __last, __ITERATOR_CATEGORY(__first)); + } +#else /* __STL_MEMBER_TEMPLATES */ + __BVECTOR(const_iterator __first, const_iterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { + size_type __n = 0; + distance(__first, __last, __n); + _M_initialize(__n); + copy(__first, __last, _M_start); + } + __BVECTOR(const bool* __first, const bool* __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { + size_type __n = 0; + distance(__first, __last, __n); + _M_initialize(__n); + copy(__first, __last, _M_start); + } +#endif /* __STL_MEMBER_TEMPLATES */ + + ~__BVECTOR() { } + + __BVECTOR& operator=(const __BVECTOR& __x) { + if (&__x == this) return *this; + if (__x.size() > capacity()) { + _M_deallocate(); + _M_initialize(__x.size()); + } + copy(__x.begin(), __x.end(), begin()); + _M_finish = begin() + difference_type(__x.size()); + return *this; + } + + // assign(), a generalized assignment member function. Two + // versions: one that takes a count, and one that takes a range. + // The range version is a member template, so we dispatch on whether + // or not the type is an integer. + + void assign(size_t __n, bool __x) { + if (__n > size()) { + fill(_M_start._M_p, _M_end_of_storage, __x ? ~0 : 0); + insert(end(), __n - size(), __x); + } + else { + erase(begin() + __n, end()); + fill(_M_start._M_p, _M_end_of_storage, __x ? ~0 : 0); + } + } + +#ifdef __STL_MEMBER_TEMPLATES + + template + void assign(_InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } + + template + void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { assign((size_t) __n, (bool) __val); } + + template + void _M_assign_dispatch(_InputIter __first, _InputIter __last, __false_type) + { _M_assign_aux(__first, __last, __ITERATOR_CATEGORY(__first)); } + + template + void _M_assign_aux(_InputIterator __first, _InputIterator __last, + input_iterator_tag) { + iterator __cur = begin(); + for ( ; __first != __last && __cur != end(); ++__cur, ++__first) + *__cur = *__first; + if (__first == __last) + erase(__cur, end()); + else + insert(end(), __first, __last); + } + + template + void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag) { + size_type __len = 0; + distance(__first, __last, __len); + if (__len < size()) + erase(copy(__first, __last, begin()), end()); + else { + _ForwardIterator __mid = __first; + advance(__mid, size()); + copy(__first, __mid, begin()); + insert(end(), __mid, __last); + } + } + +#endif /* __STL_MEMBER_TEMPLATES */ + + void reserve(size_type __n) { + if (capacity() < __n) { + unsigned int* __q = _M_bit_alloc(__n); + _M_finish = copy(begin(), end(), iterator(__q, 0)); + _M_deallocate(); + _M_start = iterator(__q, 0); + _M_end_of_storage = __q + (__n + __WORD_BIT - 1)/__WORD_BIT; + } + } + + reference front() { return *begin(); } + const_reference front() const { return *begin(); } + reference back() { return *(end() - 1); } + const_reference back() const { return *(end() - 1); } + void push_back(bool __x) { + if (_M_finish._M_p != _M_end_of_storage) + *_M_finish++ = __x; + else + _M_insert_aux(end(), __x); + } + void swap(__BVECTOR& __x) { + __STD::swap(_M_start, __x._M_start); + __STD::swap(_M_finish, __x._M_finish); + __STD::swap(_M_end_of_storage, __x._M_end_of_storage); + } + iterator insert(iterator __position, bool __x = bool()) { + difference_type __n = __position - begin(); + if (_M_finish._M_p != _M_end_of_storage && __position == end()) + *_M_finish++ = __x; + else + _M_insert_aux(__position, __x); + return begin() + __n; + } + +#ifdef __STL_MEMBER_TEMPLATES + // Check whether it's an integral type. If so, it's not an iterator. + template + void insert(iterator __position, + _InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_insert_dispatch(__position, __first, __last, _Integral()); + } + + template + void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, + __true_type) { + insert(__pos, (size_type) __n, (bool) __x); + } + + template + void _M_insert_dispatch(iterator __pos, + _InputIterator __first, _InputIterator __last, + __false_type) { + _M_insert_range(__pos, __first, __last, __ITERATOR_CATEGORY(__first)); + } +#else /* __STL_MEMBER_TEMPLATES */ + void insert(iterator __position, + const_iterator __first, const_iterator __last) { + if (__first == __last) return; + size_type __n = 0; + distance(__first, __last, __n); + if (capacity() - size() >= __n) { + copy_backward(__position, end(), _M_finish + __n); + copy(__first, __last, __position); + _M_finish += __n; + } + else { + size_type __len = size() + max(size(), __n); + unsigned int* __q = _M_bit_alloc(__len); + iterator __i = copy(begin(), __position, iterator(__q, 0)); + __i = copy(__first, __last, __i); + _M_finish = copy(__position, end(), __i); + _M_deallocate(); + _M_end_of_storage = __q + (__len + __WORD_BIT - 1)/__WORD_BIT; + _M_start = iterator(__q, 0); + } + } + + void insert(iterator __position, const bool* __first, const bool* __last) { + if (__first == __last) return; + size_type __n = 0; + distance(__first, __last, __n); + if (capacity() - size() >= __n) { + copy_backward(__position, end(), _M_finish + __n); + copy(__first, __last, __position); + _M_finish += __n; + } + else { + size_type __len = size() + max(size(), __n); + unsigned int* __q = _M_bit_alloc(__len); + iterator __i = copy(begin(), __position, iterator(__q, 0)); + __i = copy(__first, __last, __i); + _M_finish = copy(__position, end(), __i); + _M_deallocate(); + _M_end_of_storage = __q + (__len + __WORD_BIT - 1)/__WORD_BIT; + _M_start = iterator(__q, 0); + } + } +#endif /* __STL_MEMBER_TEMPLATES */ + + void insert(iterator __position, size_type __n, bool __x) { + if (__n == 0) return; + if (capacity() - size() >= __n) { + copy_backward(__position, end(), _M_finish + difference_type(__n)); + fill(__position, __position + difference_type(__n), __x); + _M_finish += difference_type(__n); + } + else { + size_type __len = size() + max(size(), __n); + unsigned int* __q = _M_bit_alloc(__len); + iterator __i = copy(begin(), __position, iterator(__q, 0)); + fill_n(__i, __n, __x); + _M_finish = copy(__position, end(), __i + difference_type(__n)); + _M_deallocate(); + _M_end_of_storage = __q + (__len + __WORD_BIT - 1)/__WORD_BIT; + _M_start = iterator(__q, 0); + } + } + + void pop_back() { --_M_finish; } + iterator erase(iterator __position) { + if (__position + 1 != end()) + copy(__position + 1, end(), __position); + --_M_finish; + return __position; + } + iterator erase(iterator __first, iterator __last) { + _M_finish = copy(__last, end(), __first); + return __first; + } + void resize(size_type __new_size, bool __x = bool()) { + if (__new_size < size()) + erase(begin() + difference_type(__new_size), end()); + else + insert(end(), __new_size - size(), __x); + } + void clear() { erase(begin(), end()); } +}; + +#ifdef __SGI_STL_VECBOOL_TEMPLATE + +typedef vector bit_vector; + +#else /* __SGI_STL_VECBOOL_TEMPLATE */ + +inline bool +operator==(const bit_vector& __x, const bit_vector& __y) +{ + return (__x.size() == __y.size() && + equal(__x.begin(), __x.end(), __y.begin())); +} + +inline bool +operator<(const bit_vector& __x, const bit_vector& __y) +{ + return lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); +} + +#endif /* __SGI_STL_VECBOOL_TEMPLATE */ + +#undef __SGI_STL_VECBOOL_TEMPLATE +#undef __BVECTOR + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#pragma reset woff 1375 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_BVECTOR_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/stl_config.h b/headers/cpp/stl_config.h new file mode 100644 index 0000000000..872813f495 --- /dev/null +++ b/headers/cpp/stl_config.h @@ -0,0 +1,357 @@ +/* + * + * 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) 1997 + * Silicon Graphics + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef __STL_CONFIG_H +# define __STL_CONFIG_H + +// Flags: +// * __STL_NO_BOOL: defined if the compiler doesn't have bool as a builtin +// type. +// * __STL_HAS_WCHAR_T: defined if the compier has wchar_t as a builtin type. +// * __STL_NO_DRAND48: defined if the compiler doesn't have the drand48 +// function. +// * __STL_STATIC_TEMPLATE_MEMBER_BUG: defined if the compiler can't handle +// static members of template classes. +// * __STL_CLASS_PARTIAL_SPECIALIZATION: defined if the compiler supports +// partial specialization of template classes. +// * __STL_PARTIAL_SPECIALIZATION_SYNTAX: defined if the compiler +// supports partial specialization syntax for full specialization of +// class templates. (Even if it doesn't actually support partial +// specialization itself.) +// * __STL_FUNCTION_TMPL_PARTIAL_ORDER: defined if the compiler supports +// partial ordering of function templates. (a.k.a partial specialization +// of function templates.) +// * __STL_MEMBER_TEMPLATES: defined if the compiler supports template +// member functions of classes. +// * __STL_MEMBER_TEMPLATE_CLASSES: defined if the compiler supports +// nested classes that are member templates of other classes. +// * __STL_EXPLICIT_FUNCTION_TMPL_ARGS: defined if the compiler +// supports calling a function template by providing its template +// arguments explicitly. +// * __STL_LIMITED_DEFAULT_TEMPLATES: defined if the compiler is unable +// to handle default template parameters that depend on previous template +// parameters. +// * __STL_NON_TYPE_TMPL_PARAM_BUG: defined if the compiler has trouble with +// function template argument deduction for non-type template parameters. +// * __SGI_STL_NO_ARROW_OPERATOR: defined if the compiler is unable +// to support the -> operator for iterators. +// * __STL_USE_EXCEPTIONS: defined if the compiler (in the current compilation +// mode) supports exceptions. +// * __STL_USE_NAMESPACES: defined if the compiler has the necessary +// support for namespaces. +// * __STL_NO_EXCEPTION_HEADER: defined if the compiler does not have a +// standard-conforming header . +// * __STL_SGI_THREADS: defined if this is being compiled for an SGI IRIX +// system in multithreaded mode, using native SGI threads instead of +// pthreads. +// * __STL_WIN32THREADS: defined if this is being compiled on a WIN32 +// compiler in multithreaded mode. +// * __STL_LONG_LONG if the compiler has long long and unsigned long long +// types. (They're not in the C++ standard, but they are expected to be +// included in the forthcoming C9X standard.) + + +// User-settable macros that control compilation: +// * __STL_USE_SGI_ALLOCATORS: if defined, then the STL will use older +// SGI-style allocators, instead of standard-conforming allocators, +// even if the compiler supports all of the language features needed +// for standard-conforming allocators. +// * __STL_NO_NAMESPACES: if defined, don't put the library in namespace +// std, even if the compiler supports namespaces. +// * __STL_ASSERTIONS: if defined, then enable runtime checking through the +// __stl_assert macro. +// * _PTHREADS: if defined, use Posix threads for multithreading support. +// * _NOTHREADS: if defined, don't use any multithreading support. + + +// Other macros defined by this file: + +// * bool, true, and false, if __STL_NO_BOOL is defined. +// * typename, as a null macro if it's not already a keyword. +// * explicit, as a null macro if it's not already a keyword. +// * namespace-related macros (__STD, __STL_BEGIN_NAMESPACE, etc.) +// * exception-related macros (__STL_TRY, __STL_UNWIND, etc.) +// * __stl_assert, either as a test or as a null macro, depending on +// whether or not __STL_ASSERTIONS is defined. + +#ifdef _PTHREADS +# define __STL_PTHREADS +#endif +#ifdef _SOLTHREADS +# define __STL_SOLTHREADS +#endif + +# if defined(__sgi) && !defined(__GNUC__) +# if !defined(_BOOL) +# define __STL_NO_BOOL +# endif +# if defined(_WCHAR_T_IS_KEYWORD) +# define __STL_HAS_WCHAR_T +# endif +# if !defined(_TYPENAME_IS_KEYWORD) +# define __STL_NEED_TYPENAME +# endif +# ifdef _PARTIAL_SPECIALIZATION_OF_CLASS_TEMPLATES +# define __STL_CLASS_PARTIAL_SPECIALIZATION +# endif +# ifdef _MEMBER_TEMPLATES +# define __STL_MEMBER_TEMPLATES +# define __STL_MEMBER_TEMPLATE_CLASSES +# endif +# if defined(_MEMBER_TEMPLATE_KEYWORD) +# define __STL_MEMBER_TEMPLATE_KEYWORD +# endif +# if (_COMPILER_VERSION >= 730) && defined(_MIPS_SIM) && _MIPS_SIM != _ABIO32 +# define __STL_MEMBER_TEMPLATE_KEYWORD +# endif +# if !defined(_EXPLICIT_IS_KEYWORD) +# define __STL_NEED_EXPLICIT +# endif +# ifdef __EXCEPTIONS +# define __STL_USE_EXCEPTIONS +# endif +# if (_COMPILER_VERSION >= 721) && defined(_NAMESPACES) +# define __STL_HAS_NAMESPACES +# endif +# if (_COMPILER_VERSION < 721) +# define __STL_NO_EXCEPTION_HEADER +# endif +# if !defined(_NOTHREADS) && !defined(__STL_PTHREADS) +# define __STL_SGI_THREADS +# endif +# if defined(_LONGLONG) && defined(_SGIAPI) && _SGIAPI +# define __STL_LONG_LONG +# endif +# endif + +# ifdef __GNUC__ +# include <_G_config.h> +# define __STL_HAS_WCHAR_T +# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) +# define __STL_STATIC_TEMPLATE_MEMBER_BUG +# define __STL_NEED_TYPENAME +# define __STL_NEED_EXPLICIT +# else +# define __STL_CLASS_PARTIAL_SPECIALIZATION +# define __STL_FUNCTION_TMPL_PARTIAL_ORDER +# define __STL_MEMBER_TEMPLATES +# define __STL_MEMBER_TEMPLATE_CLASSES +# define __STL_EXPLICIT_FUNCTION_TMPL_ARGS +# define __STL_HAS_NAMESPACES +# define __STL_NO_NAMESPACES +# define __SGI_STL_USE_AUTO_PTR_CONVERSIONS +# define __STL_USE_NAMESPACES +# endif +# if defined(__linux__) + /* glibc pre 2.0 is very buggy. We have to disable thread for it. + It should be upgraded to glibc 2.0 or later. */ +# if !defined(_NOTHREADS) && __GLIBC__ >= 2 && defined(_G_USING_THUNKS) +# define __STL_PTHREADS +# ifdef __STRICT_ANSI__ + /* Work around a bug in the glibc 2.0.x pthread.h. */ +# define sigset_t __sigset_t +# endif +# endif +# endif +# ifdef __EXCEPTIONS +# define __STL_USE_EXCEPTIONS +# endif +# ifndef __STRICT_ANSI__ +# define __STL_LONG_LONG +# endif +# endif + +# if defined(__SUNPRO_CC) +# define __STL_NO_BOOL +# define __STL_NEED_TYPENAME +# define __STL_NEED_EXPLICIT +# define __STL_USE_EXCEPTIONS +# endif + +# if defined(__COMO__) +# define __STL_MEMBER_TEMPLATES +# define __STL_MEMBER_TEMPLATE_CLASSES +# define __STL_CLASS_PARTIAL_SPECIALIZATION +# define __STL_USE_EXCEPTIONS +# define __STL_HAS_NAMESPACES +# endif + +# if defined(__MINGW32__) +# define __STL_NO_DRAND48 +# endif + +# if defined(__CYGWIN__) +# define __STL_NO_DRAND48 +# endif + +# if defined(_MSC_VER) +# define __STL_NO_DRAND48 +# define __STL_NEED_TYPENAME +# if _MSC_VER < 1100 /* 1000 is version 4.0, 1100 is 5.0, 1200 is 6.0. */ +# define __STL_NEED_EXPLICIT +# define __STL_NO_BOOL +# if _MSC_VER > 1000 +# include +# define __STL_DONT_USE_BOOL_TYPEDEF +# endif +# endif +# define __STL_NON_TYPE_TMPL_PARAM_BUG +# define __SGI_STL_NO_ARROW_OPERATOR +# ifdef _CPPUNWIND +# define __STL_USE_EXCEPTIONS +# endif +# ifdef _MT +# define __STL_WIN32THREADS +# endif +# if _MSC_VER >= 1200 +# define __STL_PARTIAL_SPECIALIZATION_SYNTAX +# define __STL_HAS_NAMESPACES +# define __STL_NO_NAMESPACES +# endif +# endif + +# if defined(__BORLANDC__) +# define __STL_NO_DRAND48 +# define __STL_NEED_TYPENAME +# define __STL_LIMITED_DEFAULT_TEMPLATES +# define __SGI_STL_NO_ARROW_OPERATOR +# define __STL_NON_TYPE_TMPL_PARAM_BUG +# ifdef _CPPUNWIND +# define __STL_USE_EXCEPTIONS +# endif +# ifdef __MT__ +# define __STL_WIN32THREADS +# endif +# endif + +# if defined(__STL_NO_BOOL) && !defined(__STL_DONT_USE_BOOL_TYPEDEF) + typedef int bool; +# define true 1 +# define false 0 +# endif + +# ifdef __STL_NEED_TYPENAME +# define typename +# endif + +# ifdef __STL_MEMBER_TEMPLATE_KEYWORD +# define __STL_TEMPLATE template +# else +# define __STL_TEMPLATE +# endif + +# ifdef __STL_NEED_EXPLICIT +# define explicit +# endif + +# ifdef __STL_EXPLICIT_FUNCTION_TMPL_ARGS +# define __STL_NULL_TMPL_ARGS <> +# else +# define __STL_NULL_TMPL_ARGS +# endif + +# if defined(__STL_CLASS_PARTIAL_SPECIALIZATION) \ + || defined (__STL_PARTIAL_SPECIALIZATION_SYNTAX) +# define __STL_TEMPLATE_NULL template<> +# else +# define __STL_TEMPLATE_NULL +# endif + +// Use standard-conforming allocators if we have the necessary language +// features. __STL_USE_SGI_ALLOCATORS is a hook so that users can +// disable new-style allocators, and continue to use the same kind of +// allocators as before, without having to edit library headers. +# if defined(__STL_CLASS_PARTIAL_SPECIALIZATION) && \ + defined(__STL_MEMBER_TEMPLATES) && \ + defined(__STL_MEMBER_TEMPLATE_CLASSES) && \ + !defined(__STL_NO_BOOL) && \ + !defined(__STL_NON_TYPE_TMPL_PARAM_BUG) && \ + !defined(__STL_LIMITED_DEFAULT_TEMPLATES) && \ + !defined(__STL_USE_SGI_ALLOCATORS) || \ + defined(__BEOS__) +# define __STL_USE_STD_ALLOCATORS +# endif + +# ifndef __STL_DEFAULT_ALLOCATOR +# ifdef __STL_USE_STD_ALLOCATORS +# define __STL_DEFAULT_ALLOCATOR(T) allocator +# else +# define __STL_DEFAULT_ALLOCATOR(T) alloc +# endif +# endif + +// __STL_NO_NAMESPACES is a hook so that users can disable namespaces +// without having to edit library headers. +# if defined(__STL_HAS_NAMESPACES) && !defined(__STL_NO_NAMESPACES) +# define __STD std +# define __STL_BEGIN_NAMESPACE namespace std { +# define __STL_END_NAMESPACE } +# define __STL_USE_NAMESPACE_FOR_RELOPS +# define __STL_BEGIN_RELOPS_NAMESPACE namespace std { +# define __STL_END_RELOPS_NAMESPACE } +# define __STD_RELOPS std +# define __STL_USE_NAMESPACES +# else +# define __STD +# define __STL_BEGIN_NAMESPACE +# define __STL_END_NAMESPACE +# undef __STL_USE_NAMESPACE_FOR_RELOPS +# define __STL_BEGIN_RELOPS_NAMESPACE +# define __STL_END_RELOPS_NAMESPACE +# define __STD_RELOPS +# undef __STL_USE_NAMESPACES +# endif + +# ifdef __STL_USE_EXCEPTIONS +# define __STL_TRY try +# define __STL_CATCH_ALL catch(...) +# define __STL_THROW(x) throw x +# define __STL_RETHROW throw +# define __STL_NOTHROW throw() +# define __STL_UNWIND(action) catch(...) { action; throw; } +# else +# define __STL_TRY +# define __STL_CATCH_ALL if (false) +# define __STL_THROW(x) +# define __STL_RETHROW +# define __STL_NOTHROW +# define __STL_UNWIND(action) +# endif + +#ifdef __STL_ASSERTIONS +# include +# define __stl_assert(expr) \ + if (!(expr)) { fprintf(stderr, "%s:%d STL assertion failure: %s\n", \ + __FILE__, __LINE__, # expr); abort(); } +#else +# define __stl_assert(expr) +#endif + +#endif /* __STL_CONFIG_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/stl_construct.h b/headers/cpp/stl_construct.h new file mode 100644 index 0000000000..761784d57d --- /dev/null +++ b/headers/cpp/stl_construct.h @@ -0,0 +1,90 @@ +/* + * + * 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,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. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_CONSTRUCT_H +#define __SGI_STL_INTERNAL_CONSTRUCT_H + +#include + +__STL_BEGIN_NAMESPACE + +// construct and destroy. These functions are not part of the C++ standard, +// and are provided for backward compatibility with the HP STL. + +template +inline void destroy(_Tp* __pointer) { + __pointer->~_Tp(); +} + +template +inline void construct(_T1* __p, const _T2& __value) { + new (__p) _T1(__value); +} + +template +inline void construct(_T1* __p) { + new (__p) _T1(); +} + +template +inline void +__destroy_aux(_ForwardIterator __first, _ForwardIterator __last, __false_type) +{ + for ( ; __first != __last; ++__first) + destroy(&*__first); +} + +template +inline void __destroy_aux(_ForwardIterator, _ForwardIterator, __true_type) {} + +template +inline void +__destroy(_ForwardIterator __first, _ForwardIterator __last, _Tp*) +{ + typedef typename __type_traits<_Tp>::has_trivial_destructor + _Trivial_destructor; + __destroy_aux(__first, __last, _Trivial_destructor()); +} + +template +inline void destroy(_ForwardIterator __first, _ForwardIterator __last) { + __destroy(__first, __last, __VALUE_TYPE(__first)); +} + +inline void destroy(char*, char*) {} +inline void destroy(wchar_t*, wchar_t*) {} + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_CONSTRUCT_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/stl_deque.h b/headers/cpp/stl_deque.h new file mode 100644 index 0000000000..24a8bfb1bc --- /dev/null +++ b/headers/cpp/stl_deque.h @@ -0,0 +1,1698 @@ +/* + * + * 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) 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. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_DEQUE_H +#define __SGI_STL_INTERNAL_DEQUE_H + +/* Class invariants: + * For any nonsingular iterator i: + * i.node is the address of an element in the map array. The + * contents of i.node is a pointer to the beginning of a node. + * i.first == *(i.node) + * i.last == i.first + node_size + * i.cur is a pointer in the range [i.first, i.last). NOTE: + * the implication of this is that i.cur is always a dereferenceable + * pointer, even if i is a past-the-end iterator. + * Start and Finish are always nonsingular iterators. NOTE: this means + * that an empty deque must have one node, and that a deque + * with N elements, where N is the buffer size, must have two nodes. + * For every node other than start.node and finish.node, every element + * in the node is an initialized object. If start.node == finish.node, + * then [start.cur, finish.cur) are initialized objects, and + * the elements outside that range are uninitialized storage. Otherwise, + * [start.cur, start.last) and [finish.first, finish.cur) are initialized + * objects, and [start.first, start.cur) and [finish.cur, finish.last) + * are uninitialized storage. + * [map, map + map_size) is a valid, non-empty range. + * [start.node, finish.node] is a valid range contained within + * [map, map + map_size). + * A pointer in the range [map, map + map_size) points to an allocated node + * if and only if the pointer is in the range [start.node, finish.node]. + */ + + +/* + * In previous versions of deque, node_size was fixed by the + * implementation. In this version, however, users can select + * the node size. Deque has three template parameters; the third, + * a number of type size_t, is the number of elements per node. + * If the third template parameter is 0 (which is the default), + * then deque will use a default node size. + * + * The only reason for using an alternate node size is if your application + * requires a different performance tradeoff than the default. If, + * for example, your program contains many deques each of which contains + * only a few elements, then you might want to save memory (possibly + * by sacrificing some speed) by using smaller nodes. + * + * Unfortunately, some compilers have trouble with non-type template + * parameters; stl_config.h defines __STL_NON_TYPE_TMPL_PARAM_BUG if + * that is the case. If your compiler is one of them, then you will + * not be able to use alternate node sizes; you will have to use the + * default value. + */ + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1174 +#pragma set woff 1375 +#endif + +// Note: this function is simply a kludge to work around several compilers' +// bugs in handling constant expressions. +inline size_t +__deque_buf_size(size_t __n, size_t __size) +{ + return __n != 0 ? __n : (__size < 512 ? size_t(512 / __size) : size_t(1)); +} + +#ifndef __STL_NON_TYPE_TMPL_PARAM_BUG +template +struct _Deque_iterator { + typedef _Deque_iterator<_Tp,_Tp&,_Tp*,__bufsiz> iterator; + typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*,__bufsiz> const_iterator; + static size_t + _S_buffer_size() { return __deque_buf_size(__bufsiz, sizeof(_Tp)); } +#else /* __STL_NON_TYPE_TMPL_PARAM_BUG */ +template +struct _Deque_iterator { + typedef _Deque_iterator<_Tp, _Tp&, _Tp*> iterator; + typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator; + static size_t + _S_buffer_size() { return __deque_buf_size(0, sizeof(_Tp)); } +#endif + + typedef random_access_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Ptr pointer; + typedef _Ref reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp** _Map_pointer; + + typedef _Deque_iterator _Self; + + _Tp* _M_cur; + _Tp* _M_first; + _Tp* _M_last; + _Map_pointer _M_node; + + _Deque_iterator(_Tp* __x, _Map_pointer __y) + : _M_cur(__x), _M_first(*__y), + _M_last(*__y + _S_buffer_size()), _M_node(__y) {} + _Deque_iterator() : _M_cur(0), _M_first(0), _M_last(0), _M_node(0) {} + _Deque_iterator(const iterator& __x) + : _M_cur(__x._M_cur), _M_first(__x._M_first), + _M_last(__x._M_last), _M_node(__x._M_node) {} + + reference operator*() const { return *_M_cur; } +#ifndef __SGI_STL_NO_ARROW_OPERATOR + pointer operator->() const { return _M_cur; } +#endif /* __SGI_STL_NO_ARROW_OPERATOR */ + + difference_type operator-(const _Self& __x) const { + return difference_type(_S_buffer_size()) * (_M_node - __x._M_node - 1) + + (_M_cur - _M_first) + (__x._M_last - __x._M_cur); + } + + _Self& operator++() { + ++_M_cur; + if (_M_cur == _M_last) { + _M_set_node(_M_node + 1); + _M_cur = _M_first; + } + return *this; + } + _Self operator++(int) { + _Self __tmp = *this; + ++*this; + return __tmp; + } + + _Self& operator--() { + if (_M_cur == _M_first) { + _M_set_node(_M_node - 1); + _M_cur = _M_last; + } + --_M_cur; + return *this; + } + _Self operator--(int) { + _Self __tmp = *this; + --*this; + return __tmp; + } + + _Self& operator+=(difference_type __n) + { + difference_type __offset = __n + (_M_cur - _M_first); + if (__offset >= 0 && __offset < difference_type(_S_buffer_size())) + _M_cur += __n; + else { + difference_type __node_offset = + __offset > 0 ? __offset / difference_type(_S_buffer_size()) + : -difference_type((-__offset - 1) / _S_buffer_size()) - 1; + _M_set_node(_M_node + __node_offset); + _M_cur = _M_first + + (__offset - __node_offset * difference_type(_S_buffer_size())); + } + return *this; + } + + _Self operator+(difference_type __n) const + { + _Self __tmp = *this; + return __tmp += __n; + } + + _Self& operator-=(difference_type __n) { return *this += -__n; } + + _Self operator-(difference_type __n) const { + _Self __tmp = *this; + return __tmp -= __n; + } + + reference operator[](difference_type __n) const { return *(*this + __n); } + + bool operator==(const _Self& __x) const { return _M_cur == __x._M_cur; } + bool operator!=(const _Self& __x) const { return !(*this == __x); } + bool operator<(const _Self& __x) const { + return (_M_node == __x._M_node) ? + (_M_cur < __x._M_cur) : (_M_node < __x._M_node); + } + + void _M_set_node(_Map_pointer __new_node) { + _M_node = __new_node; + _M_first = *__new_node; + _M_last = _M_first + difference_type(_S_buffer_size()); + } +}; + +#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION + +#ifndef __STL_NON_TYPE_TMPL_PARAM_BUG + +template +inline random_access_iterator_tag +iterator_category(const _Deque_iterator<_Tp,_Ref,_Ptr,__bufsiz>&) { + return random_access_iterator_tag(); +} + +template +inline _Tp* +value_type(const _Deque_iterator<_Tp,_Ref,_Ptr,__bufsiz>&) { + return 0; +} + +template +inline ptrdiff_t* +distance_type(const _Deque_iterator<_Tp,_Ref,_Ptr,__bufsiz>&) { + return 0; +} + +#else /* __STL_NON_TYPE_TMPL_PARAM_BUG */ + +template +inline random_access_iterator_tag +iterator_category(const _Deque_iterator<_Tp,_Ref,_Ptr>&) +{ + return random_access_iterator_tag(); +} + +template +inline _Tp* +value_type(const _Deque_iterator<_Tp,_Ref,_Ptr>&) { return 0; } + +template +inline ptrdiff_t* +distance_type(const _Deque_iterator<_Tp,_Ref,_Ptr>&) { + return 0; +} + +#endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */ + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +// Deque base class. It has two purposes. First, its constructor +// and destructor allocate (but don't initialize) storage. This makes +// exception safety easier. Second, the base class encapsulates all of +// the differences between SGI-style allocators and standard-conforming +// allocators. + +#ifdef __STL_USE_STD_ALLOCATORS + +// Base class for ordinary allocators. +template +class _Deque_alloc_base { +public: + typedef typename _Alloc_traits<_Tp,_Alloc>::allocator_type allocator_type; + allocator_type get_allocator() const { return node_allocator; } + + _Deque_alloc_base(const allocator_type& __a) + : node_allocator(__a), map_allocator(__a), _M_map(0), _M_map_size(0) + {} + +protected: + typedef typename _Alloc_traits<_Tp*, _Alloc>::allocator_type + map_allocator_type; + + allocator_type node_allocator; + map_allocator_type map_allocator; + + _Tp* _M_allocate_node() { + return node_allocator.allocate(__deque_buf_size(__bufsiz,sizeof(_Tp))); + } + void _M_deallocate_node(_Tp* __p) { + node_allocator.deallocate(__p, __deque_buf_size(__bufsiz,sizeof(_Tp))); + } + _Tp** _M_allocate_map(size_t __n) + { return map_allocator.allocate(__n); } + void _M_deallocate_map(_Tp** __p, size_t __n) + { map_allocator.deallocate(__p, __n); } + + _Tp** _M_map; + size_t _M_map_size; +}; + +// Specialization for instanceless allocators. +template +class _Deque_alloc_base<_Tp, _Alloc, __bufsiz, true> +{ +public: + typedef typename _Alloc_traits<_Tp,_Alloc>::allocator_type allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Deque_alloc_base(const allocator_type&) : _M_map(0), _M_map_size(0) {} + +protected: + typedef typename _Alloc_traits<_Tp, _Alloc>::_Alloc_type _Node_alloc_type; + typedef typename _Alloc_traits<_Tp*, _Alloc>::_Alloc_type _Map_alloc_type; + + _Tp* _M_allocate_node() + { return _Node_alloc_type::allocate(__deque_buf_size(__bufsiz, + sizeof(_Tp))); } + void _M_deallocate_node(_Tp* __p) + { _Node_alloc_type::deallocate(__p, __deque_buf_size(__bufsiz, + sizeof(_Tp))); } + _Tp** _M_allocate_map(size_t __n) + { return _Map_alloc_type::allocate(__n); } + void _M_deallocate_map(_Tp** __p, size_t __n) + { _Map_alloc_type::deallocate(__p, __n); } + + _Tp** _M_map; + size_t _M_map_size; +}; + +template +class _Deque_base + : public _Deque_alloc_base<_Tp,_Alloc,__bufsiz, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> +{ +public: + typedef _Deque_alloc_base<_Tp,_Alloc,__bufsiz, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> + _Base; + typedef typename _Base::allocator_type allocator_type; + typedef _Deque_iterator<_Tp,_Tp&,_Tp*,__bufsiz> iterator; + typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*, __bufsiz> const_iterator; + + _Deque_base(const allocator_type& __a, size_t __num_elements) + : _Base(__a), _M_start(), _M_finish() + { _M_initialize_map(__num_elements); } + _Deque_base(const allocator_type& __a) + : _Base(__a), _M_start(), _M_finish() {} + ~_Deque_base(); + +protected: + void _M_initialize_map(size_t); + void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish); + void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish); + enum { _S_initial_map_size = 8 }; + +protected: + iterator _M_start; + iterator _M_finish; +}; + +#else /* __STL_USE_STD_ALLOCATORS */ + +template +class _Deque_base { +public: +#ifndef __STL_NON_TYPE_TMPL_PARAM_BUG + typedef _Deque_iterator<_Tp,_Tp&,_Tp*,__bufsiz> iterator; + typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*, __bufsiz> const_iterator; +#else /* __STL_NON_TYPE_TMPL_PARAM_BUG */ + typedef _Deque_iterator<_Tp,_Tp&,_Tp*> iterator; + typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*> const_iterator; +#endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */ + + typedef _Alloc allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Deque_base(const allocator_type&, size_t __num_elements) + : _M_map(0), _M_map_size(0), _M_start(), _M_finish() { + _M_initialize_map(__num_elements); + } + _Deque_base(const allocator_type&) + : _M_map(0), _M_map_size(0), _M_start(), _M_finish() {} + ~_Deque_base(); + +protected: + void _M_initialize_map(size_t); + void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish); + void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish); + enum { _S_initial_map_size = 8 }; + +protected: + _Tp** _M_map; + size_t _M_map_size; + iterator _M_start; + iterator _M_finish; + + typedef simple_alloc<_Tp, _Alloc> _Node_alloc_type; + typedef simple_alloc<_Tp*, _Alloc> _Map_alloc_type; + + _Tp* _M_allocate_node() + { return _Node_alloc_type::allocate(__deque_buf_size(__bufsiz, + sizeof(_Tp))); } + void _M_deallocate_node(_Tp* __p) + { _Node_alloc_type::deallocate(__p, __deque_buf_size(__bufsiz, + sizeof(_Tp))); } + _Tp** _M_allocate_map(size_t __n) + { return _Map_alloc_type::allocate(__n); } + void _M_deallocate_map(_Tp** __p, size_t __n) + { _Map_alloc_type::deallocate(__p, __n); } +}; + +#endif /* __STL_USE_STD_ALLOCATORS */ + +// Non-inline member functions from _Deque_base. + +template +_Deque_base<_Tp,_Alloc,__bufsiz>::~_Deque_base() { + if (_M_map) { + _M_destroy_nodes(_M_start._M_node, _M_finish._M_node + 1); + _M_deallocate_map(_M_map, _M_map_size); + } +} + +template +void +_Deque_base<_Tp,_Alloc,__bufsiz>::_M_initialize_map(size_t __num_elements) +{ + size_t __num_nodes = + __num_elements / __deque_buf_size(__bufsiz, sizeof(_Tp)) + 1; + + _M_map_size = max((size_t) _S_initial_map_size, __num_nodes + 2); + _M_map = _M_allocate_map(_M_map_size); + + _Tp** __nstart = _M_map + (_M_map_size - __num_nodes) / 2; + _Tp** __nfinish = __nstart + __num_nodes; + + __STL_TRY { + _M_create_nodes(__nstart, __nfinish); + } + __STL_UNWIND((_M_deallocate_map(_M_map, _M_map_size), + _M_map = 0, _M_map_size = 0)); + _M_start._M_set_node(__nstart); + _M_finish._M_set_node(__nfinish - 1); + _M_start._M_cur = _M_start._M_first; + _M_finish._M_cur = _M_finish._M_first + + __num_elements % __deque_buf_size(__bufsiz, sizeof(_Tp)); +} + +template +void +_Deque_base<_Tp,_Alloc,__bufsiz>::_M_create_nodes(_Tp** __nstart, + _Tp** __nfinish) +{ + _Tp** __cur; + __STL_TRY { + for (__cur = __nstart; __cur < __nfinish; ++__cur) + *__cur = _M_allocate_node(); + } + __STL_UNWIND(_M_destroy_nodes(__nstart, __cur)); +} + +template +void +_Deque_base<_Tp,_Alloc,__bufsiz>::_M_destroy_nodes(_Tp** __nstart, + _Tp** __nfinish) +{ + for (_Tp** __n = __nstart; __n < __nfinish; ++__n) + _M_deallocate_node(*__n); +} + +// See __deque_buf_size(). The only reason that the default value is 0 +// is as a workaround for bugs in the way that some compilers handle +// constant expressions. +template +class deque : protected _Deque_base<_Tp, _Alloc, __bufsiz> { + typedef _Deque_base<_Tp, _Alloc, __bufsiz> _Base; +public: // Basic types + 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 typename _Base::allocator_type allocator_type; + allocator_type get_allocator() const { return _Base::get_allocator(); } + +public: // Iterators + typedef typename _Base::iterator iterator; + typedef typename _Base::const_iterator const_iterator; + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + typedef reverse_iterator const_reverse_iterator; + typedef reverse_iterator reverse_iterator; +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + typedef reverse_iterator + const_reverse_iterator; + typedef reverse_iterator + reverse_iterator; +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +protected: // Internal typedefs + typedef pointer* _Map_pointer; + static size_t _S_buffer_size() + { return __deque_buf_size(__bufsiz, sizeof(_Tp)); } + +protected: +#ifdef __STL_USE_NAMESPACES + using _Base::_M_initialize_map; + using _Base::_M_create_nodes; + using _Base::_M_destroy_nodes; + using _Base::_M_allocate_node; + using _Base::_M_deallocate_node; + using _Base::_M_allocate_map; + using _Base::_M_deallocate_map; + + using _Base::_M_map; + using _Base::_M_map_size; + using _Base::_M_start; + using _Base::_M_finish; +#endif /* __STL_USE_NAMESPACES */ + +public: // Basic accessors + iterator begin() { return _M_start; } + iterator end() { return _M_finish; } + const_iterator begin() const { return _M_start; } + const_iterator end() const { return _M_finish; } + + reverse_iterator rbegin() { return reverse_iterator(_M_finish); } + reverse_iterator rend() { return reverse_iterator(_M_start); } + const_reverse_iterator rbegin() const + { return const_reverse_iterator(_M_finish); } + const_reverse_iterator rend() const + { return const_reverse_iterator(_M_start); } + + reference operator[](size_type __n) + { return _M_start[difference_type(__n)]; } + const_reference operator[](size_type __n) const + { return _M_start[difference_type(__n)]; } + + reference front() { return *_M_start; } + reference back() { + iterator __tmp = _M_finish; + --__tmp; + return *__tmp; + } + const_reference front() const { return *_M_start; } + const_reference back() const { + const_iterator __tmp = _M_finish; + --__tmp; + return *__tmp; + } + + size_type size() const { return _M_finish - _M_start;; } + size_type max_size() const { return size_type(-1); } + bool empty() const { return _M_finish == _M_start; } + +public: // Constructor, destructor. + explicit deque(const allocator_type& __a = allocator_type()) + : _Base(__a, 0) {} + deque(const deque& __x) : _Base(__x.get_allocator(), __x.size()) + { uninitialized_copy(__x.begin(), __x.end(), _M_start); } + deque(size_type __n, const value_type& __value, + const allocator_type& __a = allocator_type()) : _Base(__a, __n) + { _M_fill_initialize(__value); } + explicit deque(size_type __n) : _Base(allocator_type(), __n) + { _M_fill_initialize(value_type()); } + +#ifdef __STL_MEMBER_TEMPLATES + + // Check whether it's an integral type. If so, it's not an iterator. + template + deque(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) : _Base(__a) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_initialize_dispatch(__first, __last, _Integral()); + } + + template + void _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) { + _M_initialize_map(__n); + _M_fill_initialize(__x); + } + + template + void _M_initialize_dispatch(_InputIter __first, _InputIter __last, + __false_type) { + _M_range_initialize(__first, __last, __ITERATOR_CATEGORY(__first)); + } + +#else /* __STL_MEMBER_TEMPLATES */ + + deque(const value_type* __first, const value_type* __last, + const allocator_type& __a = allocator_type()) + : _Base(__a, __last - __first) + { uninitialized_copy(__first, __last, _M_start); } + deque(const_iterator __first, const_iterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a, __last - __first) + { uninitialized_copy(__first, __last, _M_start); } + +#endif /* __STL_MEMBER_TEMPLATES */ + + ~deque() { destroy(_M_start, _M_finish); } + + deque& operator= (const deque& __x) { + const size_type __len = size(); + if (&__x != this) { + if (__len >= __x.size()) + erase(copy(__x.begin(), __x.end(), _M_start), _M_finish); + else { + const_iterator __mid = __x.begin() + difference_type(__len); + copy(__x.begin(), __mid, _M_start); + insert(_M_finish, __mid, __x.end()); + } + } + return *this; + } + + void swap(deque& __x) { + __STD::swap(_M_start, __x._M_start); + __STD::swap(_M_finish, __x._M_finish); + __STD::swap(_M_map, __x._M_map); + __STD::swap(_M_map_size, __x._M_map_size); + } + +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) { + if (__n > size()) { + fill(begin(), end(), __val); + insert(end(), __n - size(), __val); + } + else { + erase(begin() + __n, end()); + fill(begin(), end(), __val); + } + } + +#ifdef __STL_MEMBER_TEMPLATES + + template + void assign(_InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } + +private: // helper functions for assign() + + template + void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { assign((size_type) __n, (_Tp) __val); } + + template + void _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) { + _M_assign_aux(__first, __last, __ITERATOR_CATEGORY(__first)); + } + + template + void _M_assign_aux(_InputIterator __first, _InputIterator __last, + input_iterator_tag); + + template + void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag) { + size_type __len = 0; + distance(__first, __last, __len); + if (__len > size()) { + _ForwardIterator __mid = __first; + advance(__mid, size()); + copy(__first, __mid, begin()); + insert(end(), __mid, __last); + } + else + erase(copy(__first, __last, begin()), end()); + } + +#endif /* __STL_MEMBER_TEMPLATES */ + +public: // push_* and pop_* + + void push_back(const value_type& __t) { + if (_M_finish._M_cur != _M_finish._M_last - 1) { + construct(_M_finish._M_cur, __t); + ++_M_finish._M_cur; + } + else + _M_push_back_aux(__t); + } + + void push_back() { + if (_M_finish._M_cur != _M_finish._M_last - 1) { + construct(_M_finish._M_cur); + ++_M_finish._M_cur; + } + else + _M_push_back_aux(); + } + + void push_front(const value_type& __t) { + if (_M_start._M_cur != _M_start._M_first) { + construct(_M_start._M_cur - 1, __t); + --_M_start._M_cur; + } + else + _M_push_front_aux(__t); + } + + void push_front() { + if (_M_start._M_cur != _M_start._M_first) { + construct(_M_start._M_cur - 1); + --_M_start._M_cur; + } + else + _M_push_front_aux(); + } + + + void pop_back() { + if (_M_finish._M_cur != _M_finish._M_first) { + --_M_finish._M_cur; + destroy(_M_finish._M_cur); + } + else + _M_pop_back_aux(); + } + + void pop_front() { + if (_M_start._M_cur != _M_start._M_last - 1) { + destroy(_M_start._M_cur); + ++_M_start._M_cur; + } + else + _M_pop_front_aux(); + } + +public: // Insert + + iterator insert(iterator position, const value_type& __x) { + if (position._M_cur == _M_start._M_cur) { + push_front(__x); + return _M_start; + } + else if (position._M_cur == _M_finish._M_cur) { + push_back(__x); + iterator __tmp = _M_finish; + --__tmp; + return __tmp; + } + else { + return _M_insert_aux(position, __x); + } + } + + iterator insert(iterator __position) + { return insert(__position, value_type()); } + + void insert(iterator __pos, size_type __n, const value_type& __x); + +#ifdef __STL_MEMBER_TEMPLATES + + // Check whether it's an integral type. If so, it's not an iterator. + template + void insert(iterator __pos, _InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_insert_dispatch(__pos, __first, __last, _Integral()); + } + + template + void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, + __true_type) { + insert(__pos, (size_type) __n, (value_type) __x); + } + + template + void _M_insert_dispatch(iterator __pos, + _InputIterator __first, _InputIterator __last, + __false_type) { + insert(__pos, __first, __last, __ITERATOR_CATEGORY(__first)); + } + +#else /* __STL_MEMBER_TEMPLATES */ + + void insert(iterator __pos, + const value_type* __first, const value_type* __last); + void insert(iterator __pos, + const_iterator __first, const_iterator __last); + +#endif /* __STL_MEMBER_TEMPLATES */ + + void resize(size_type __new_size, const value_type& __x) { + const size_type __len = size(); + if (__new_size < __len) + erase(_M_start + __new_size, _M_finish); + else + insert(_M_finish, __new_size - __len, __x); + } + + void resize(size_type new_size) { resize(new_size, value_type()); } + +public: // Erase + iterator erase(iterator __pos) { + iterator __next = __pos; + ++__next; + difference_type __index = __pos - _M_start; + if (static_cast(__index) < (size() >> 1)) { + copy_backward(_M_start, __pos, __next); + pop_front(); + } + else { + copy(__next, _M_finish, __pos); + pop_back(); + } + return _M_start + __index; + } + + iterator erase(iterator __first, iterator __last); + void clear(); + +protected: // Internal construction/destruction + + void _M_fill_initialize(const value_type& __value); + +#ifdef __STL_MEMBER_TEMPLATES + + template + void _M_range_initialize(_InputIterator __first, _InputIterator __last, + input_iterator_tag); + + template + void _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag); + +#endif /* __STL_MEMBER_TEMPLATES */ + +protected: // Internal push_* and pop_* + + void _M_push_back_aux(const value_type&); + void _M_push_back_aux(); + void _M_push_front_aux(const value_type&); + void _M_push_front_aux(); + void _M_pop_back_aux(); + void _M_pop_front_aux(); + +protected: // Internal insert functions + +#ifdef __STL_MEMBER_TEMPLATES + + template + void insert(iterator __pos, _InputIterator __first, _InputIterator __last, + input_iterator_tag); + + template + void insert(iterator __pos, + _ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag); + +#endif /* __STL_MEMBER_TEMPLATES */ + + iterator _M_insert_aux(iterator __pos, const value_type& __x); + iterator _M_insert_aux(iterator __pos); + void _M_insert_aux(iterator __pos, size_type __n, const value_type& __x); + +#ifdef __STL_MEMBER_TEMPLATES + + template + void _M_insert_aux(iterator __pos, + _ForwardIterator __first, _ForwardIterator __last, + size_type __n); + +#else /* __STL_MEMBER_TEMPLATES */ + + void _M_insert_aux(iterator __pos, + const value_type* __first, const value_type* __last, + size_type __n); + + void _M_insert_aux(iterator __pos, + const_iterator __first, const_iterator __last, + size_type __n); + +#endif /* __STL_MEMBER_TEMPLATES */ + + iterator _M_reserve_elements_at_front(size_type __n) { + size_type __vacancies = _M_start._M_cur - _M_start._M_first; + if (__n > __vacancies) + _M_new_elements_at_front(__n - __vacancies); + return _M_start - difference_type(__n); + } + + iterator _M_reserve_elements_at_back(size_type __n) { + size_type __vacancies = (_M_finish._M_last - _M_finish._M_cur) - 1; + if (__n > __vacancies) + _M_new_elements_at_back(__n - __vacancies); + return _M_finish + difference_type(__n); + } + + void _M_new_elements_at_front(size_type __new_elements); + void _M_new_elements_at_back(size_type __new_elements); + +protected: // Allocation of _M_map and nodes + + // Makes sure the _M_map has space for new nodes. Does not actually + // add the nodes. Can invalidate _M_map pointers. (And consequently, + // deque iterators.) + + void _M_reserve_map_at_back (size_type __nodes_to_add = 1) { + if (__nodes_to_add + 1 > _M_map_size - (_M_finish._M_node - _M_map)) + _M_reallocate_map(__nodes_to_add, false); + } + + void _M_reserve_map_at_front (size_type __nodes_to_add = 1) { + if (__nodes_to_add > size_type(_M_start._M_node - _M_map)) + _M_reallocate_map(__nodes_to_add, true); + } + + void _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front); + +#ifdef __STL_NON_TYPE_TMPL_PARAM_BUG +public: + bool operator==(const deque<_Tp,_Alloc,0>& __x) const { + return size() == __x.size() && equal(begin(), end(), __x.begin()); + } + bool operator!=(const deque<_Tp,_Alloc,0>& __x) const { + return size() != __x.size() || !equal(begin(), end(), __x.begin()); + } + bool operator<(const deque<_Tp,_Alloc,0>& __x) const { + return lexicographical_compare(begin(), end(), __x.begin(), __x.end()); + } +#endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */ +}; + +// Non-inline member functions + +#ifdef __STL_MEMBER_TEMPLATES + +template +template +void deque<_Tp, _Alloc, __bufsize> + ::_M_assign_aux(_InputIter __first, _InputIter __last, input_iterator_tag) +{ + iterator __cur = begin(); + for ( ; __first != __last && __cur != end(); ++__cur, ++__first) + *__cur = *__first; + if (__first == __last) + erase(__cur, end()); + else + insert(end(), __first, __last); +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +template +void +deque<_Tp, _Alloc, __bufsize>::insert(iterator __pos, + size_type __n, const value_type& __x) +{ + if (__pos._M_cur == _M_start._M_cur) { + iterator __new_start = _M_reserve_elements_at_front(__n); + uninitialized_fill(__new_start, _M_start, __x); + _M_start = __new_start; + } + else if (__pos._M_cur == _M_finish._M_cur) { + iterator __new_finish = _M_reserve_elements_at_back(__n); + uninitialized_fill(_M_finish, __new_finish, __x); + _M_finish = __new_finish; + } + else + _M_insert_aux(__pos, __n, __x); +} + +#ifndef __STL_MEMBER_TEMPLATES + +template +void deque<_Tp, _Alloc, __bufsize>::insert(iterator __pos, + const value_type* __first, + const value_type* __last) { + size_type __n = __last - __first; + if (__pos._M_cur == _M_start._M_cur) { + iterator __new_start = _M_reserve_elements_at_front(__n); + __STL_TRY { + uninitialized_copy(__first, __last, __new_start); + _M_start = __new_start; + } + __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node)); + } + else if (__pos._M_cur == _M_finish._M_cur) { + iterator __new_finish = _M_reserve_elements_at_back(__n); + __STL_TRY { + uninitialized_copy(__first, __last, _M_finish); + _M_finish = __new_finish; + } + __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, + __new_finish._M_node + 1)); + } + else + _M_insert_aux(__pos, __first, __last, __n); +} + +template +void deque<_Tp,_Alloc,__bufsize>::insert(iterator __pos, + const_iterator __first, + const_iterator __last) +{ + size_type __n = __last - __first; + if (__pos._M_cur == _M_start._M_cur) { + iterator __new_start = _M_reserve_elements_at_front(__n); + __STL_TRY { + uninitialized_copy(__first, __last, __new_start); + _M_start = __new_start; + } + __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node)); + } + else if (__pos._M_cur == _M_finish._M_cur) { + iterator __new_finish = _M_reserve_elements_at_back(__n); + __STL_TRY { + uninitialized_copy(__first, __last, _M_finish); + _M_finish = __new_finish; + } + __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, + __new_finish._M_node + 1)); + } + else + _M_insert_aux(__pos, __first, __last, __n); +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +template +deque<_Tp,_Alloc,__bufsize>::iterator +deque<_Tp,_Alloc,__bufsize>::erase(iterator __first, iterator __last) +{ + if (__first == _M_start && __last == _M_finish) { + clear(); + return _M_finish; + } + else { + difference_type __n = __last - __first; + difference_type __elems_before = __first - _M_start; + if (static_cast(__elems_before) < (size() - __n) / 2) { + copy_backward(_M_start, __first, __last); + iterator __new_start = _M_start + __n; + destroy(_M_start, __new_start); + _M_destroy_nodes(__new_start._M_node, _M_start._M_node); + _M_start = __new_start; + } + else { + copy(__last, _M_finish, __first); + iterator __new_finish = _M_finish - __n; + destroy(__new_finish, _M_finish); + _M_destroy_nodes(__new_finish._M_node + 1, _M_finish._M_node + 1); + _M_finish = __new_finish; + } + return _M_start + __elems_before; + } +} + +template +void deque<_Tp,_Alloc,__bufsize>::clear() +{ + for (_Map_pointer __node = _M_start._M_node + 1; + __node < _M_finish._M_node; + ++__node) { + destroy(*__node, *__node + _S_buffer_size()); + _M_deallocate_node(*__node); + } + + if (_M_start._M_node != _M_finish._M_node) { + destroy(_M_start._M_cur, _M_start._M_last); + destroy(_M_finish._M_first, _M_finish._M_cur); + _M_deallocate_node(_M_finish._M_first); + } + else + destroy(_M_start._M_cur, _M_finish._M_cur); + + _M_finish = _M_start; +} + +// Precondition: _M_start and _M_finish have already been initialized, +// but none of the deque's elements have yet been constructed. +template +void +deque<_Tp,_Alloc,__bufsize>::_M_fill_initialize(const value_type& __value) { + _Map_pointer __cur; + __STL_TRY { + for (__cur = _M_start._M_node; __cur < _M_finish._M_node; ++__cur) + uninitialized_fill(*__cur, *__cur + _S_buffer_size(), __value); + uninitialized_fill(_M_finish._M_first, _M_finish._M_cur, __value); + } + __STL_UNWIND(destroy(_M_start, iterator(*__cur, __cur))); +} + +#ifdef __STL_MEMBER_TEMPLATES + +template +template +void +deque<_Tp,_Alloc,__bufsize>::_M_range_initialize(_InputIterator __first, + _InputIterator __last, + input_iterator_tag) +{ + _M_initialize_map(0); + for ( ; __first != __last; ++__first) + push_back(*__first); +} + +template +template +void +deque<_Tp,_Alloc,__bufsize>::_M_range_initialize(_ForwardIterator __first, + _ForwardIterator __last, + forward_iterator_tag) +{ + size_type __n = 0; + distance(__first, __last, __n); + _M_initialize_map(__n); + + _Map_pointer __cur_node; + __STL_TRY { + for (__cur_node = _M_start._M_node; + __cur_node < _M_finish._M_node; + ++__cur_node) { + _ForwardIterator __mid = __first; + advance(__mid, _S_buffer_size()); + uninitialized_copy(__first, __mid, *__cur_node); + __first = __mid; + } + uninitialized_copy(__first, __last, _M_finish._M_first); + } + __STL_UNWIND(destroy(_M_start, iterator(*__cur_node, __cur_node))); +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +// Called only if _M_finish._M_cur == _M_finish._M_last - 1. +template +void +deque<_Tp,_Alloc,__bufsize>::_M_push_back_aux(const value_type& __t) +{ + value_type __t_copy = __t; + _M_reserve_map_at_back(); + *(_M_finish._M_node + 1) = _M_allocate_node(); + __STL_TRY { + construct(_M_finish._M_cur, __t_copy); + _M_finish._M_set_node(_M_finish._M_node + 1); + _M_finish._M_cur = _M_finish._M_first; + } + __STL_UNWIND(_M_deallocate_node(*(_M_finish._M_node + 1))); +} + +// Called only if _M_finish._M_cur == _M_finish._M_last - 1. +template +void +deque<_Tp,_Alloc,__bufsize>::_M_push_back_aux() +{ + _M_reserve_map_at_back(); + *(_M_finish._M_node + 1) = _M_allocate_node(); + __STL_TRY { + construct(_M_finish._M_cur); + _M_finish._M_set_node(_M_finish._M_node + 1); + _M_finish._M_cur = _M_finish._M_first; + } + __STL_UNWIND(_M_deallocate_node(*(_M_finish._M_node + 1))); +} + +// Called only if _M_start._M_cur == _M_start._M_first. +template +void +deque<_Tp,_Alloc,__bufsize>::_M_push_front_aux(const value_type& __t) +{ + value_type __t_copy = __t; + _M_reserve_map_at_front(); + *(_M_start._M_node - 1) = _M_allocate_node(); + __STL_TRY { + _M_start._M_set_node(_M_start._M_node - 1); + _M_start._M_cur = _M_start._M_last - 1; + construct(_M_start._M_cur, __t_copy); + } + __STL_UNWIND((++_M_start, _M_deallocate_node(*(_M_start._M_node - 1)))); +} + +// Called only if _M_start._M_cur == _M_start._M_first. +template +void +deque<_Tp,_Alloc,__bufsize>::_M_push_front_aux() +{ + _M_reserve_map_at_front(); + *(_M_start._M_node - 1) = _M_allocate_node(); + __STL_TRY { + _M_start._M_set_node(_M_start._M_node - 1); + _M_start._M_cur = _M_start._M_last - 1; + construct(_M_start._M_cur); + } + __STL_UNWIND((++_M_start, _M_deallocate_node(*(_M_start._M_node - 1)))); +} + +// Called only if _M_finish._M_cur == _M_finish._M_first. +template +void +deque<_Tp,_Alloc,__bufsize>::_M_pop_back_aux() +{ + _M_deallocate_node(_M_finish._M_first); + _M_finish._M_set_node(_M_finish._M_node - 1); + _M_finish._M_cur = _M_finish._M_last - 1; + destroy(_M_finish._M_cur); +} + +// Called only if _M_start._M_cur == _M_start._M_last - 1. Note that +// if the deque has at least one element (a precondition for this member +// function), and if _M_start._M_cur == _M_start._M_last, then the deque +// must have at least two nodes. +template +void +deque<_Tp,_Alloc,__bufsize>::_M_pop_front_aux() +{ + destroy(_M_start._M_cur); + _M_deallocate_node(_M_start._M_first); + _M_start._M_set_node(_M_start._M_node + 1); + _M_start._M_cur = _M_start._M_first; +} + +#ifdef __STL_MEMBER_TEMPLATES + +template +template +void +deque<_Tp,_Alloc,__bufsize>::insert(iterator __pos, + _InputIterator __first, + _InputIterator __last, + input_iterator_tag) +{ + copy(__first, __last, inserter(*this, __pos)); +} + +template +template +void +deque<_Tp,_Alloc,__bufsize>::insert(iterator __pos, + _ForwardIterator __first, + _ForwardIterator __last, + forward_iterator_tag) { + size_type __n = 0; + distance(__first, __last, __n); + if (__pos._M_cur == _M_start._M_cur) { + iterator __new_start = _M_reserve_elements_at_front(__n); + __STL_TRY { + uninitialized_copy(__first, __last, __new_start); + _M_start = __new_start; + } + __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node)); + } + else if (__pos._M_cur == _M_finish._M_cur) { + iterator __new_finish = _M_reserve_elements_at_back(__n); + __STL_TRY { + uninitialized_copy(__first, __last, _M_finish); + _M_finish = __new_finish; + } + __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, + __new_finish._M_node + 1)); + } + else + _M_insert_aux(__pos, __first, __last, __n); +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +template +typename deque<_Tp, _Alloc, __bufsize>::iterator +deque<_Tp,_Alloc,__bufsize>::_M_insert_aux(iterator __pos, + const value_type& __x) +{ + difference_type __index = __pos - _M_start; + value_type __x_copy = __x; + if (static_cast(__index) < size() / 2) { + push_front(front()); + iterator __front1 = _M_start; + ++__front1; + iterator __front2 = __front1; + ++__front2; + __pos = _M_start + __index; + iterator __pos1 = __pos; + ++__pos1; + copy(__front2, __pos1, __front1); + } + else { + push_back(back()); + iterator __back1 = _M_finish; + --__back1; + iterator __back2 = __back1; + --__back2; + __pos = _M_start + __index; + copy_backward(__pos, __back2, __back1); + } + *__pos = __x_copy; + return __pos; +} + +template +typename deque<_Tp,_Alloc,__bufsize>::iterator +deque<_Tp,_Alloc,__bufsize>::_M_insert_aux(iterator __pos) +{ + difference_type __index = __pos - _M_start; + if (static_cast(__index) < size() / 2) { + push_front(front()); + iterator __front1 = _M_start; + ++__front1; + iterator __front2 = __front1; + ++__front2; + __pos = _M_start + __index; + iterator __pos1 = __pos; + ++__pos1; + copy(__front2, __pos1, __front1); + } + else { + push_back(back()); + iterator __back1 = _M_finish; + --__back1; + iterator __back2 = __back1; + --__back2; + __pos = _M_start + __index; + copy_backward(__pos, __back2, __back1); + } + *__pos = value_type(); + return __pos; +} + +template +void +deque<_Tp,_Alloc,__bufsize>::_M_insert_aux(iterator __pos, + size_type __n, + const value_type& __x) +{ + const difference_type __elems_before = __pos - _M_start; + size_type __length = size(); + value_type __x_copy = __x; + if (static_cast(__elems_before) < __length / 2) { + iterator __new_start = _M_reserve_elements_at_front(__n); + iterator __old_start = _M_start; + __pos = _M_start + __elems_before; + __STL_TRY { + if (__elems_before >= difference_type(__n)) { + iterator __start_n = _M_start + difference_type(__n); + uninitialized_copy(_M_start, __start_n, __new_start); + _M_start = __new_start; + copy(__start_n, __pos, __old_start); + fill(__pos - difference_type(__n), __pos, __x_copy); + } + else { + __uninitialized_copy_fill(_M_start, __pos, __new_start, + _M_start, __x_copy); + _M_start = __new_start; + fill(__old_start, __pos, __x_copy); + } + } + __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node)); + } + else { + iterator __new_finish = _M_reserve_elements_at_back(__n); + iterator __old_finish = _M_finish; + const difference_type __elems_after = + difference_type(__length) - __elems_before; + __pos = _M_finish - __elems_after; + __STL_TRY { + if (__elems_after > difference_type(__n)) { + iterator __finish_n = _M_finish - difference_type(__n); + uninitialized_copy(__finish_n, _M_finish, _M_finish); + _M_finish = __new_finish; + copy_backward(__pos, __finish_n, __old_finish); + fill(__pos, __pos + difference_type(__n), __x_copy); + } + else { + __uninitialized_fill_copy(_M_finish, __pos + difference_type(__n), + __x_copy, __pos, _M_finish); + _M_finish = __new_finish; + fill(__pos, __old_finish, __x_copy); + } + } + __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, + __new_finish._M_node + 1)); + } +} + +#ifdef __STL_MEMBER_TEMPLATES + +template +template +void +deque<_Tp,_Alloc,__bufsize>::_M_insert_aux(iterator __pos, + _ForwardIterator __first, + _ForwardIterator __last, + size_type __n) +{ + const difference_type __elemsbefore = __pos - _M_start; + size_type __length = size(); + if (static_cast(__elemsbefore) < __length / 2) { + iterator __new_start = _M_reserve_elements_at_front(__n); + iterator __old_start = _M_start; + __pos = _M_start + __elemsbefore; + __STL_TRY { + if (__elemsbefore >= difference_type(__n)) { + iterator __start_n = _M_start + difference_type(__n); + uninitialized_copy(_M_start, __start_n, __new_start); + _M_start = __new_start; + copy(__start_n, __pos, __old_start); + copy(__first, __last, __pos - difference_type(__n)); + } + else { + _ForwardIterator __mid = __first; + advance(__mid, difference_type(__n) - __elemsbefore); + __uninitialized_copy_copy(_M_start, __pos, __first, __mid, + __new_start); + _M_start = __new_start; + copy(__mid, __last, __old_start); + } + } + __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node)); + } + else { + iterator __new_finish = _M_reserve_elements_at_back(__n); + iterator __old_finish = _M_finish; + const difference_type __elemsafter = + difference_type(__length) - __elemsbefore; + __pos = _M_finish - __elemsafter; + __STL_TRY { + if (__elemsafter > difference_type(__n)) { + iterator __finish_n = _M_finish - difference_type(__n); + uninitialized_copy(__finish_n, _M_finish, _M_finish); + _M_finish = __new_finish; + copy_backward(__pos, __finish_n, __old_finish); + copy(__first, __last, __pos); + } + else { + _ForwardIterator __mid = __first; + advance(__mid, __elemsafter); + __uninitialized_copy_copy(__mid, __last, __pos, _M_finish, _M_finish); + _M_finish = __new_finish; + copy(__first, __mid, __pos); + } + } + __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, + __new_finish._M_node + 1)); + } +} + +#else /* __STL_MEMBER_TEMPLATES */ + +template +void +deque<_Tp,_Alloc,__bufsize>::_M_insert_aux(iterator __pos, + const value_type* __first, + const value_type* __last, + size_type __n) +{ + const difference_type __elemsbefore = __pos - _M_start; + size_type __length = size(); + if (__elemsbefore < __length / 2) { + iterator __new_start = _M_reserve_elements_at_front(__n); + iterator __old_start = _M_start; + __pos = _M_start + __elemsbefore; + __STL_TRY { + if (__elemsbefore >= difference_type(__n)) { + iterator __start_n = _M_start + difference_type(__n); + uninitialized_copy(_M_start, __start_n, __new_start); + _M_start = __new_start; + copy(__start_n, __pos, __old_start); + copy(__first, __last, __pos - difference_type(__n)); + } + else { + const value_type* __mid = + __first + (difference_type(__n) - __elemsbefore); + __uninitialized_copy_copy(_M_start, __pos, __first, __mid, + __new_start); + _M_start = __new_start; + copy(__mid, __last, __old_start); + } + } + __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node)); + } + else { + iterator __new_finish = _M_reserve_elements_at_back(__n); + iterator __old_finish = _M_finish; + const difference_type __elemsafter = + difference_type(__length) - __elemsbefore; + __pos = _M_finish - __elemsafter; + __STL_TRY { + if (__elemsafter > difference_type(__n)) { + iterator __finish_n = _M_finish - difference_type(__n); + uninitialized_copy(__finish_n, _M_finish, _M_finish); + _M_finish = __new_finish; + copy_backward(__pos, __finish_n, __old_finish); + copy(__first, __last, __pos); + } + else { + const value_type* __mid = __first + __elemsafter; + __uninitialized_copy_copy(__mid, __last, __pos, _M_finish, _M_finish); + _M_finish = __new_finish; + copy(__first, __mid, __pos); + } + } + __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, + __new_finish._M_node + 1)); + } +} + +template +void +deque<_Tp,_Alloc,__bufsize>::_M_insert_aux(iterator __pos, + const_iterator __first, + const_iterator __last, + size_type __n) +{ + const difference_type __elemsbefore = __pos - _M_start; + size_type __length = size(); + if (__elemsbefore < __length / 2) { + iterator __new_start = _M_reserve_elements_at_front(__n); + iterator __old_start = _M_start; + __pos = _M_start + __elemsbefore; + __STL_TRY { + if (__elemsbefore >= __n) { + iterator __start_n = _M_start + __n; + uninitialized_copy(_M_start, __start_n, __new_start); + _M_start = __new_start; + copy(__start_n, __pos, __old_start); + copy(__first, __last, __pos - difference_type(__n)); + } + else { + const_iterator __mid = __first + (__n - __elemsbefore); + __uninitialized_copy_copy(_M_start, __pos, __first, __mid, + __new_start); + _M_start = __new_start; + copy(__mid, __last, __old_start); + } + } + __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node)); + } + else { + iterator __new_finish = _M_reserve_elements_at_back(__n); + iterator __old_finish = _M_finish; + const difference_type __elemsafter = __length - __elemsbefore; + __pos = _M_finish - __elemsafter; + __STL_TRY { + if (__elemsafter > __n) { + iterator __finish_n = _M_finish - difference_type(__n); + uninitialized_copy(__finish_n, _M_finish, _M_finish); + _M_finish = __new_finish; + copy_backward(__pos, __finish_n, __old_finish); + copy(__first, __last, __pos); + } + else { + const_iterator __mid = __first + __elemsafter; + __uninitialized_copy_copy(__mid, __last, __pos, _M_finish, _M_finish); + _M_finish = __new_finish; + copy(__first, __mid, __pos); + } + } + __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, + __new_finish._M_node + 1)); + } +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +template +void +deque<_Tp,_Alloc,__bufsize>::_M_new_elements_at_front(size_type __new_elems) +{ + size_type __new_nodes + = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size(); + _M_reserve_map_at_front(__new_nodes); + size_type __i; + __STL_TRY { + for (__i = 1; __i <= __new_nodes; ++__i) + *(_M_start._M_node - __i) = _M_allocate_node(); + } +# ifdef __STL_USE_EXCEPTIONS + catch(...) { + for (size_type __j = 1; __j < __i; ++__j) + _M_deallocate_node(*(_M_start._M_node - __j)); + throw; + } +# endif /* __STL_USE_EXCEPTIONS */ +} + +template +void +deque<_Tp,_Alloc,__bufsize>::_M_new_elements_at_back(size_type __new_elems) +{ + size_type __new_nodes + = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size(); + _M_reserve_map_at_back(__new_nodes); + size_type __i; + __STL_TRY { + for (__i = 1; __i <= __new_nodes; ++__i) + *(_M_finish._M_node + __i) = _M_allocate_node(); + } +# ifdef __STL_USE_EXCEPTIONS + catch(...) { + for (size_type __j = 1; __j < __i; ++__j) + _M_deallocate_node(*(_M_finish._M_node + __j)); + throw; + } +# endif /* __STL_USE_EXCEPTIONS */ +} + +template +void +deque<_Tp,_Alloc,__bufsize>::_M_reallocate_map(size_type __nodes_to_add, + bool __add_at_front) +{ + size_type __old_num_nodes = _M_finish._M_node - _M_start._M_node + 1; + size_type __new_num_nodes = __old_num_nodes + __nodes_to_add; + + _Map_pointer __new_nstart; + if (_M_map_size > 2 * __new_num_nodes) { + __new_nstart = _M_map + (_M_map_size - __new_num_nodes) / 2 + + (__add_at_front ? __nodes_to_add : 0); + if (__new_nstart < _M_start._M_node) + copy(_M_start._M_node, _M_finish._M_node + 1, __new_nstart); + else + copy_backward(_M_start._M_node, _M_finish._M_node + 1, + __new_nstart + __old_num_nodes); + } + else { + size_type __new_map_size = + _M_map_size + max(_M_map_size, __nodes_to_add) + 2; + + _Map_pointer __new_map = _M_allocate_map(__new_map_size); + __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2 + + (__add_at_front ? __nodes_to_add : 0); + copy(_M_start._M_node, _M_finish._M_node + 1, __new_nstart); + _M_deallocate_map(_M_map, _M_map_size); + + _M_map = __new_map; + _M_map_size = __new_map_size; + } + + _M_start._M_set_node(__new_nstart); + _M_finish._M_set_node(__new_nstart + __old_num_nodes - 1); +} + + +// Nonmember functions. + +#ifndef __STL_NON_TYPE_TMPL_PARAM_BUG + +template +bool operator==(const deque<_Tp, _Alloc, __bufsiz>& __x, + const deque<_Tp, _Alloc, __bufsiz>& __y) +{ + return __x.size() == __y.size() && + equal(__x.begin(), __x.end(), __y.begin()); +} + +template +bool operator<(const deque<_Tp, _Alloc, __bufsiz>& __x, + const deque<_Tp, _Alloc, __bufsiz>& __y) +{ + return lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); +} + +#endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */ + +#if defined(__STL_FUNCTION_TMPL_PARTIAL_ORDER) && \ + !defined(__STL_NON_TYPE_TMPL_PARAM_BUG) + +template +inline void +swap(deque<_Tp,_Alloc,__bufsiz>& __x, deque<_Tp,_Alloc,__bufsiz>& __y) +{ + __x.swap(__y); +} + +#endif + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#pragma reset woff 1375 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_DEQUE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/stl_function.h b/headers/cpp/stl_function.h new file mode 100644 index 0000000000..a5a8486576 --- /dev/null +++ b/headers/cpp/stl_function.h @@ -0,0 +1,700 @@ +/* + * + * 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. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_FUNCTION_H +#define __SGI_STL_INTERNAL_FUNCTION_H + +__STL_BEGIN_NAMESPACE + +template +struct unary_function { + typedef _Arg argument_type; + typedef _Result result_type; +}; + +template +struct binary_function { + typedef _Arg1 first_argument_type; + typedef _Arg2 second_argument_type; + typedef _Result result_type; +}; + +template +struct plus : public binary_function<_Tp,_Tp,_Tp> { + _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x + __y; } +}; + +template +struct minus : public binary_function<_Tp,_Tp,_Tp> { + _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x - __y; } +}; + +template +struct multiplies : public binary_function<_Tp,_Tp,_Tp> { + _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x * __y; } +}; + +template +struct divides : public binary_function<_Tp,_Tp,_Tp> { + _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x / __y; } +}; + +// identity_element (not part of the C++ standard). + +template inline _Tp identity_element(plus<_Tp>) { + return _Tp(0); +} +template inline _Tp identity_element(multiplies<_Tp>) { + return _Tp(1); +} + +template +struct modulus : public binary_function<_Tp,_Tp,_Tp> +{ + _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x % __y; } +}; + +template +struct negate : public unary_function<_Tp,_Tp> +{ + _Tp operator()(const _Tp& __x) const { return -__x; } +}; + +template +struct equal_to : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __y) const { return __x == __y; } +}; + +template +struct not_equal_to : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __y) const { return __x != __y; } +}; + +template +struct greater : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __y) const { return __x > __y; } +}; + +template +struct less : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __y) const { return __x < __y; } +}; + +template +struct greater_equal : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __y) const { return __x >= __y; } +}; + +template +struct less_equal : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __y) const { return __x <= __y; } +}; + +template +struct logical_and : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __y) const { return __x && __y; } +}; + +template +struct logical_or : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __y) const { return __x || __y; } +}; + +template +struct logical_not : public unary_function<_Tp,bool> +{ + bool operator()(const _Tp& __x) const { return !__x; } +}; + +template +class unary_negate + : public unary_function { +protected: + _Predicate _M_pred; +public: + explicit unary_negate(const _Predicate& __x) : _M_pred(__x) {} + bool operator()(const typename _Predicate::argument_type& __x) const { + return !_M_pred(__x); + } +}; + +template +inline unary_negate<_Predicate> +not1(const _Predicate& __pred) +{ + return unary_negate<_Predicate>(__pred); +} + +template +class binary_negate + : public binary_function { +protected: + _Predicate _M_pred; +public: + explicit binary_negate(const _Predicate& __x) : _M_pred(__x) {} + bool operator()(const typename _Predicate::first_argument_type& __x, + const typename _Predicate::second_argument_type& __y) const + { + return !_M_pred(__x, __y); + } +}; + +template +inline binary_negate<_Predicate> +not2(const _Predicate& __pred) +{ + return binary_negate<_Predicate>(__pred); +} + +template +class binder1st + : public unary_function { +protected: + _Operation op; + typename _Operation::first_argument_type value; +public: + binder1st(const _Operation& __x, + const typename _Operation::first_argument_type& __y) + : op(__x), value(__y) {} + typename _Operation::result_type + operator()(const typename _Operation::second_argument_type& __x) const { + return op(value, __x); + } +}; + +template +inline binder1st<_Operation> +bind1st(const _Operation& __oper, const _Tp& __x) +{ + typedef typename _Operation::first_argument_type _Arg1_type; + return binder1st<_Operation>(__oper, _Arg1_type(__x)); +} + +template +class binder2nd + : public unary_function { +protected: + _Operation op; + typename _Operation::second_argument_type value; +public: + binder2nd(const _Operation& __x, + const typename _Operation::second_argument_type& __y) + : op(__x), value(__y) {} + typename _Operation::result_type + operator()(const typename _Operation::first_argument_type& __x) const { + return op(__x, value); + } +}; + +template +inline binder2nd<_Operation> +bind2nd(const _Operation& __oper, const _Tp& __x) +{ + typedef typename _Operation::second_argument_type _Arg2_type; + return binder2nd<_Operation>(__oper, _Arg2_type(__x)); +} + +// unary_compose and binary_compose (extensions, not part of the standard). + +template +class unary_compose + : public unary_function +{ +protected: + _Operation1 __op1; + _Operation2 __op2; +public: + unary_compose(const _Operation1& __x, const _Operation2& __y) + : __op1(__x), __op2(__y) {} + typename _Operation1::result_type + operator()(const typename _Operation2::argument_type& __x) const { + return __op1(__op2(__x)); + } +}; + +template +inline unary_compose<_Operation1,_Operation2> +compose1(const _Operation1& __op1, const _Operation2& __op2) +{ + return unary_compose<_Operation1,_Operation2>(__op1, __op2); +} + +template +class binary_compose + : public unary_function { +protected: + _Operation1 _M_op1; + _Operation2 _M_op2; + _Operation3 _M_op3; +public: + binary_compose(const _Operation1& __x, const _Operation2& __y, + const _Operation3& __z) + : _M_op1(__x), _M_op2(__y), _M_op3(__z) { } + typename _Operation1::result_type + operator()(const typename _Operation2::argument_type& __x) const { + return _M_op1(_M_op2(__x), _M_op3(__x)); + } +}; + +template +inline binary_compose<_Operation1, _Operation2, _Operation3> +compose2(const _Operation1& __op1, const _Operation2& __op2, + const _Operation3& __op3) +{ + return binary_compose<_Operation1,_Operation2,_Operation3> + (__op1, __op2, __op3); +} + +template +class pointer_to_unary_function : public unary_function<_Arg, _Result> { +protected: + _Result (*_M_ptr)(_Arg); +public: + pointer_to_unary_function() {} + explicit pointer_to_unary_function(_Result (*__x)(_Arg)) : _M_ptr(__x) {} + _Result operator()(_Arg __x) const { return _M_ptr(__x); } +}; + +template +inline pointer_to_unary_function<_Arg, _Result> ptr_fun(_Result (*__x)(_Arg)) +{ + return pointer_to_unary_function<_Arg, _Result>(__x); +} + +template +class pointer_to_binary_function : + public binary_function<_Arg1,_Arg2,_Result> { +protected: + _Result (*_M_ptr)(_Arg1, _Arg2); +public: + pointer_to_binary_function() {} + explicit pointer_to_binary_function(_Result (*__x)(_Arg1, _Arg2)) + : _M_ptr(__x) {} + _Result operator()(_Arg1 __x, _Arg2 __y) const { + return _M_ptr(__x, __y); + } +}; + +template +inline pointer_to_binary_function<_Arg1,_Arg2,_Result> +ptr_fun(_Result (*__x)(_Arg1, _Arg2)) { + return pointer_to_binary_function<_Arg1,_Arg2,_Result>(__x); +} + +// identity is an extensions: it is not part of the standard. +template +struct _Identity : public unary_function<_Tp,_Tp> { + const _Tp& operator()(const _Tp& __x) const { return __x; } +}; + +template struct identity : public _Identity<_Tp> {}; + +// select1st and select2nd are extensions: they are not part of the standard. +template +struct _Select1st : public unary_function<_Pair, typename _Pair::first_type> { + const typename _Pair::first_type& operator()(const _Pair& __x) const { + return __x.first; + } +}; + +template +struct _Select2nd : public unary_function<_Pair, typename _Pair::second_type> +{ + const typename _Pair::second_type& operator()(const _Pair& __x) const { + return __x.second; + } +}; + +template struct select1st : public _Select1st<_Pair> {}; +template struct select2nd : public _Select2nd<_Pair> {}; + +// project1st and project2nd are extensions: they are not part of the standard +template +struct _Project1st : public binary_function<_Arg1, _Arg2, _Arg1> { + _Arg1 operator()(const _Arg1& __x, const _Arg2&) const { return __x; } +}; + +template +struct _Project2nd : public binary_function<_Arg1, _Arg2, _Arg2> { + _Arg2 operator()(const _Arg1&, const _Arg2& __y) const { return __y; } +}; + +template +struct project1st : public _Project1st<_Arg1, _Arg2> {}; + +template +struct project2nd : public _Project2nd<_Arg1, _Arg2> {}; + +// constant_void_fun, constant_unary_fun, and constant_binary_fun are +// extensions: they are not part of the standard. (The same, of course, +// is true of the helper functions constant0, constant1, and constant2.) +template +struct constant_void_fun +{ + typedef _Result result_type; + result_type __val; + constant_void_fun(const result_type& __v) : __val(__v) {} + const result_type& operator()() const { return __val; } +}; + +#ifndef __STL_LIMITED_DEFAULT_TEMPLATES +template +#else +template +#endif +struct constant_unary_fun : public unary_function<_Argument, _Result> { + _Result _M_val; + constant_unary_fun(const _Result& __v) : _M_val(__v) {} + const _Result& operator()(const _Argument&) const { return _M_val; } +}; + +#ifndef __STL_LIMITED_DEFAULT_TEMPLATES +template +#else +template +#endif +struct constant_binary_fun : public binary_function<_Arg1, _Arg2, _Result> { + _Result _M_val; + constant_binary_fun(const _Result& __v) : _M_val(__v) {} + const _Result& operator()(const _Arg1&, const _Arg2&) const { + return _M_val; + } +}; + +template +inline constant_void_fun<_Result> constant0(const _Result& __val) +{ + return constant_void_fun<_Result>(__val); +} + +template +inline constant_unary_fun<_Result,_Result> constant1(const _Result& __val) +{ + return constant_unary_fun<_Result,_Result>(__val); +} + +template +inline constant_binary_fun<_Result,_Result,_Result> +constant2(const _Result& __val) +{ + return constant_binary_fun<_Result,_Result,_Result>(__val); +} + +// subtractive_rng is an extension: it is not part of the standard. +// Note: this code assumes that int is 32 bits. +class subtractive_rng : public unary_function { +private: + unsigned int _M_table[55]; + size_t _M_index1; + size_t _M_index2; +public: + 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; + } + + subtractive_rng(unsigned int __seed) { _M_initialize(__seed); } + subtractive_rng() { _M_initialize(161803398u); } +}; + + +// Adaptor function objects: pointers to member functions. + +// There are a total of 16 = 2^4 function objects in this family. +// (1) Member functions taking no arguments vs member functions taking +// one argument. +// (2) Call through pointer vs call through reference. +// (3) Member function with void return type vs member function with +// non-void return type. +// (4) Const vs non-const member function. + +// Note that choice (3) is nothing more than a workaround: according +// to the draft, compilers should handle void and non-void the same way. +// This feature is not yet widely implemented, though. You can only use +// member functions returning void if your compiler supports partial +// specialization. + +// All of this complexity is in the function objects themselves. You can +// ignore it by using the helper function mem_fun and mem_fun_ref, +// which create whichever type of adaptor is appropriate. +// (mem_fun1 and mem_fun1_ref are no longer part of the C++ standard, +// but they are provided for backward compatibility.) + + +template +class mem_fun_t : public unary_function<_Tp*,_Ret> { +public: + explicit mem_fun_t(_Ret (_Tp::*__pf)()) : _M_f(__pf) {} + _Ret operator()(_Tp* __p) const { return (__p->*_M_f)(); } +private: + _Ret (_Tp::*_M_f)(); +}; + +template +class const_mem_fun_t : public unary_function { +public: + explicit const_mem_fun_t(_Ret (_Tp::*__pf)() const) : _M_f(__pf) {} + _Ret operator()(const _Tp* __p) const { return (__p->*_M_f)(); } +private: + _Ret (_Tp::*_M_f)() const; +}; + + +template +class mem_fun_ref_t : public unary_function<_Tp,_Ret> { +public: + explicit mem_fun_ref_t(_Ret (_Tp::*__pf)()) : _M_f(__pf) {} + _Ret operator()(_Tp& __r) const { return (__r.*_M_f)(); } +private: + _Ret (_Tp::*_M_f)(); +}; + +template +class const_mem_fun_ref_t : public unary_function<_Tp,_Ret> { +public: + explicit const_mem_fun_ref_t(_Ret (_Tp::*__pf)() const) : _M_f(__pf) {} + _Ret operator()(const _Tp& __r) const { return (__r.*_M_f)(); } +private: + _Ret (_Tp::*_M_f)() const; +}; + +template +class mem_fun1_t : public binary_function<_Tp*,_Arg,_Ret> { +public: + explicit mem_fun1_t(_Ret (_Tp::*__pf)(_Arg)) : _M_f(__pf) {} + _Ret operator()(_Tp* __p, _Arg __x) const { return (__p->*_M_f)(__x); } +private: + _Ret (_Tp::*_M_f)(_Arg); +}; + +template +class const_mem_fun1_t : public binary_function { +public: + explicit const_mem_fun1_t(_Ret (_Tp::*__pf)(_Arg) const) : _M_f(__pf) {} + _Ret operator()(const _Tp* __p, _Arg __x) const + { return (__p->*_M_f)(__x); } +private: + _Ret (_Tp::*_M_f)(_Arg) const; +}; + +template +class mem_fun1_ref_t : public binary_function<_Tp,_Arg,_Ret> { +public: + explicit mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg)) : _M_f(__pf) {} + _Ret operator()(_Tp& __r, _Arg __x) const { return (__r.*_M_f)(__x); } +private: + _Ret (_Tp::*_M_f)(_Arg); +}; + +template +class const_mem_fun1_ref_t : public binary_function<_Tp,_Arg,_Ret> { +public: + explicit const_mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg) const) : _M_f(__pf) {} + _Ret operator()(const _Tp& __r, _Arg __x) const { return (__r.*_M_f)(__x); } +private: + _Ret (_Tp::*_M_f)(_Arg) const; +}; + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +class mem_fun_t : public unary_function<_Tp*,void> { +public: + explicit mem_fun_t(void (_Tp::*__pf)()) : _M_f(__pf) {} + void operator()(_Tp* __p) const { (__p->*_M_f)(); } +private: + void (_Tp::*_M_f)(); +}; + +template +class const_mem_fun_t : public unary_function { +public: + explicit const_mem_fun_t(void (_Tp::*__pf)() const) : _M_f(__pf) {} + void operator()(const _Tp* __p) const { (__p->*_M_f)(); } +private: + void (_Tp::*_M_f)() const; +}; + +template +class mem_fun_ref_t : public unary_function<_Tp,void> { +public: + explicit mem_fun_ref_t(void (_Tp::*__pf)()) : _M_f(__pf) {} + void operator()(_Tp& __r) const { (__r.*_M_f)(); } +private: + void (_Tp::*_M_f)(); +}; + +template +class const_mem_fun_ref_t : public unary_function<_Tp,void> { +public: + explicit const_mem_fun_ref_t(void (_Tp::*__pf)() const) : _M_f(__pf) {} + void operator()(const _Tp& __r) const { (__r.*_M_f)(); } +private: + void (_Tp::*_M_f)() const; +}; + +template +class mem_fun1_t : public binary_function<_Tp*,_Arg,void> { +public: + explicit mem_fun1_t(void (_Tp::*__pf)(_Arg)) : _M_f(__pf) {} + void operator()(_Tp* __p, _Arg __x) const { (__p->*_M_f)(__x); } +private: + void (_Tp::*_M_f)(_Arg); +}; + +template +class const_mem_fun1_t + : public binary_function { +public: + explicit const_mem_fun1_t(void (_Tp::*__pf)(_Arg) const) : _M_f(__pf) {} + void operator()(const _Tp* __p, _Arg __x) const { (__p->*_M_f)(__x); } +private: + void (_Tp::*_M_f)(_Arg) const; +}; + +template +class mem_fun1_ref_t + : public binary_function<_Tp,_Arg,void> { +public: + explicit mem_fun1_ref_t(void (_Tp::*__pf)(_Arg)) : _M_f(__pf) {} + void operator()(_Tp& __r, _Arg __x) const { (__r.*_M_f)(__x); } +private: + void (_Tp::*_M_f)(_Arg); +}; + +template +class const_mem_fun1_ref_t + : public binary_function<_Tp,_Arg,void> { +public: + explicit const_mem_fun1_ref_t(void (_Tp::*__pf)(_Arg) const) : _M_f(__pf) {} + void operator()(const _Tp& __r, _Arg __x) const { (__r.*_M_f)(__x); } +private: + void (_Tp::*_M_f)(_Arg) const; +}; + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +// Mem_fun adaptor helper functions. There are only two: +// mem_fun and mem_fun_ref. (mem_fun1 and mem_fun1_ref +// are provided for backward compatibility, but they are no longer +// part of the C++ standard.) + +template +inline mem_fun_t<_Ret,_Tp> mem_fun(_Ret (_Tp::*__f)()) + { return mem_fun_t<_Ret,_Tp>(__f); } + +template +inline const_mem_fun_t<_Ret,_Tp> mem_fun(_Ret (_Tp::*__f)() const) + { return const_mem_fun_t<_Ret,_Tp>(__f); } + +template +inline mem_fun_ref_t<_Ret,_Tp> mem_fun_ref(_Ret (_Tp::*__f)()) + { return mem_fun_ref_t<_Ret,_Tp>(__f); } + +template +inline const_mem_fun_ref_t<_Ret,_Tp> mem_fun_ref(_Ret (_Tp::*__f)() const) + { return const_mem_fun_ref_t<_Ret,_Tp>(__f); } + +template +inline mem_fun1_t<_Ret,_Tp,_Arg> mem_fun(_Ret (_Tp::*__f)(_Arg)) + { return mem_fun1_t<_Ret,_Tp,_Arg>(__f); } + +template +inline const_mem_fun1_t<_Ret,_Tp,_Arg> mem_fun(_Ret (_Tp::*__f)(_Arg) const) + { return const_mem_fun1_t<_Ret,_Tp,_Arg>(__f); } + +template +inline mem_fun1_ref_t<_Ret,_Tp,_Arg> mem_fun_ref(_Ret (_Tp::*__f)(_Arg)) + { return mem_fun1_ref_t<_Ret,_Tp,_Arg>(__f); } + +template +inline const_mem_fun1_ref_t<_Ret,_Tp,_Arg> +mem_fun_ref(_Ret (_Tp::*__f)(_Arg) const) + { return const_mem_fun1_ref_t<_Ret,_Tp,_Arg>(__f); } + +template +inline mem_fun1_t<_Ret,_Tp,_Arg> mem_fun1(_Ret (_Tp::*__f)(_Arg)) + { return mem_fun1_t<_Ret,_Tp,_Arg>(__f); } + +template +inline const_mem_fun1_t<_Ret,_Tp,_Arg> mem_fun1(_Ret (_Tp::*__f)(_Arg) const) + { return const_mem_fun1_t<_Ret,_Tp,_Arg>(__f); } + +template +inline mem_fun1_ref_t<_Ret,_Tp,_Arg> mem_fun1_ref(_Ret (_Tp::*__f)(_Arg)) + { return mem_fun1_ref_t<_Ret,_Tp,_Arg>(__f); } + +template +inline const_mem_fun1_ref_t<_Ret,_Tp,_Arg> +mem_fun1_ref(_Ret (_Tp::*__f)(_Arg) const) + { return const_mem_fun1_ref_t<_Ret,_Tp,_Arg>(__f); } + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_FUNCTION_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/stl_hash_fun.h b/headers/cpp/stl_hash_fun.h new file mode 100644 index 0000000000..44ab9bb567 --- /dev/null +++ b/headers/cpp/stl_hash_fun.h @@ -0,0 +1,93 @@ +/* + * 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. + * + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_HASH_FUN_H +#define __SGI_STL_HASH_FUN_H + +#include + +__STL_BEGIN_NAMESPACE + +template 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); +} + +__STL_TEMPLATE_NULL struct hash +{ + size_t operator()(const char* __s) const { return __stl_hash_string(__s); } +}; + +__STL_TEMPLATE_NULL struct hash +{ + size_t operator()(const char* __s) const { return __stl_hash_string(__s); } +}; + +__STL_TEMPLATE_NULL struct hash { + size_t operator()(char __x) const { return __x; } +}; +__STL_TEMPLATE_NULL struct hash { + size_t operator()(unsigned char __x) const { return __x; } +}; +__STL_TEMPLATE_NULL struct hash { + size_t operator()(unsigned char __x) const { return __x; } +}; +__STL_TEMPLATE_NULL struct hash { + size_t operator()(short __x) const { return __x; } +}; +__STL_TEMPLATE_NULL struct hash { + size_t operator()(unsigned short __x) const { return __x; } +}; +__STL_TEMPLATE_NULL struct hash { + size_t operator()(int __x) const { return __x; } +}; +__STL_TEMPLATE_NULL struct hash { + size_t operator()(unsigned int __x) const { return __x; } +}; +__STL_TEMPLATE_NULL struct hash { + size_t operator()(long __x) const { return __x; } +}; +__STL_TEMPLATE_NULL struct hash { + size_t operator()(unsigned long __x) const { return __x; } +}; + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_HASH_FUN_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/stl_hash_map.h b/headers/cpp/stl_hash_map.h new file mode 100644 index 0000000000..bf16f60eca --- /dev/null +++ b/headers/cpp/stl_hash_map.h @@ -0,0 +1,416 @@ +/* + * 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. + * + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_HASH_MAP_H +#define __SGI_STL_INTERNAL_HASH_MAP_H + + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1174 +#pragma set woff 1375 +#endif + +#ifndef __STL_LIMITED_DEFAULT_TEMPLATES +template , + class _EqualKey = equal_to<_Key>, + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) > +#else +template +#endif +class hash_map +{ +private: + typedef hashtable,_Key,_HashFcn, + _Select1st >,_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) {} + +#ifdef __STL_MEMBER_TEMPLATES + template + hash_map(_InputIterator __f, _InputIterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + template + hash_map(_InputIterator __f, _InputIterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + template + hash_map(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + template + hash_map(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_unique(__f, __l); } + +#else + hash_map(const value_type* __f, const value_type* __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_map(const value_type* __f, const value_type* __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_map(const value_type* __f, const value_type* __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_map(const value_type* __f, const value_type* __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_unique(__f, __l); } + + hash_map(const_iterator __f, const_iterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_map(const_iterator __f, const_iterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_map(const_iterator __f, const_iterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_map(const_iterator __f, const_iterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_unique(__f, __l); } +#endif /*__STL_MEMBER_TEMPLATES */ + +public: + size_type size() const { return _M_ht.size(); } + size_type max_size() const { return _M_ht.max_size(); } + bool empty() const { return _M_ht.empty(); } + void swap(hash_map& __hs) { _M_ht.swap(__hs._M_ht); } + friend bool + operator== __STL_NULL_TMPL_ARGS (const hash_map&, const hash_map&); + + iterator begin() { return _M_ht.begin(); } + iterator end() { return _M_ht.end(); } + const_iterator begin() const { return _M_ht.begin(); } + const_iterator end() const { return _M_ht.end(); } + +public: + pair insert(const value_type& __obj) + { return _M_ht.insert_unique(__obj); } +#ifdef __STL_MEMBER_TEMPLATES + template + void insert(_InputIterator __f, _InputIterator __l) + { _M_ht.insert_unique(__f,__l); } +#else + void insert(const value_type* __f, const value_type* __l) { + _M_ht.insert_unique(__f,__l); + } + void insert(const_iterator __f, const_iterator __l) + { _M_ht.insert_unique(__f, __l); } +#endif /*__STL_MEMBER_TEMPLATES */ + pair insert_noresize(const value_type& __obj) + { return _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 equal_range(const key_type& __key) + { return _M_ht.equal_range(__key); } + pair + equal_range(const key_type& __key) const + { return _M_ht.equal_range(__key); } + + size_type erase(const key_type& __key) {return _M_ht.erase(__key); } + void erase(iterator __it) { _M_ht.erase(__it); } + void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } + void clear() { _M_ht.clear(); } + + void resize(size_type __hint) { _M_ht.resize(__hint); } + size_type bucket_count() const { return _M_ht.bucket_count(); } + size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } + size_type elems_in_bucket(size_type __n) const + { return _M_ht.elems_in_bucket(__n); } +}; + +template +inline bool +operator==(const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1, + const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2) +{ + return __hm1._M_ht == __hm2._M_ht; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline void +swap(hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1, + hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2) +{ + __hm1.swap(__hm2); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +#ifndef __STL_LIMITED_DEFAULT_TEMPLATES +template , + class _EqualKey = equal_to<_Key>, + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) > +#else +template +#endif +class hash_multimap +{ +private: + typedef hashtable, _Key, _HashFcn, + _Select1st >, _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) {} + +#ifdef __STL_MEMBER_TEMPLATES + template + hash_multimap(_InputIterator __f, _InputIterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + template + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + template + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + template + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_equal(__f, __l); } + +#else + hash_multimap(const value_type* __f, const value_type* __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multimap(const value_type* __f, const value_type* __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multimap(const value_type* __f, const value_type* __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multimap(const value_type* __f, const value_type* __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_equal(__f, __l); } + + hash_multimap(const_iterator __f, const_iterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multimap(const_iterator __f, const_iterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multimap(const_iterator __f, const_iterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multimap(const_iterator __f, const_iterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_equal(__f, __l); } +#endif /*__STL_MEMBER_TEMPLATES */ + +public: + size_type size() const { return _M_ht.size(); } + size_type max_size() const { return _M_ht.max_size(); } + bool empty() const { return _M_ht.empty(); } + void swap(hash_multimap& __hs) { _M_ht.swap(__hs._M_ht); } + friend bool + operator== __STL_NULL_TMPL_ARGS (const hash_multimap&, + const hash_multimap&); + + 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); } +#ifdef __STL_MEMBER_TEMPLATES + template + void insert(_InputIterator __f, _InputIterator __l) + { _M_ht.insert_equal(__f,__l); } +#else + void insert(const value_type* __f, const value_type* __l) { + _M_ht.insert_equal(__f,__l); + } + void insert(const_iterator __f, const_iterator __l) + { _M_ht.insert_equal(__f, __l); } +#endif /*__STL_MEMBER_TEMPLATES */ + iterator insert_noresize(const value_type& __obj) + { return _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 equal_range(const key_type& __key) + { return _M_ht.equal_range(__key); } + pair + equal_range(const key_type& __key) const + { return _M_ht.equal_range(__key); } + + size_type erase(const key_type& __key) {return _M_ht.erase(__key); } + void erase(iterator __it) { _M_ht.erase(__it); } + void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } + void clear() { _M_ht.clear(); } + +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 +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; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline void +swap(hash_multimap<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1, + hash_multimap<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2) +{ + __hm1.swap(__hm2); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#pragma reset woff 1375 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_HASH_MAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/stl_hash_set.h b/headers/cpp/stl_hash_set.h new file mode 100644 index 0000000000..b623a642cf --- /dev/null +++ b/headers/cpp/stl_hash_set.h @@ -0,0 +1,401 @@ +/* + * 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. + * + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_HASH_SET_H +#define __SGI_STL_INTERNAL_HASH_SET_H + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1174 +#pragma set woff 1375 +#endif + +#ifndef __STL_LIMITED_DEFAULT_TEMPLATES +template , + class _EqualKey = equal_to<_Value>, + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Value) > +#else +template +#endif +class hash_set +{ +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) {} + +#ifdef __STL_MEMBER_TEMPLATES + template + hash_set(_InputIterator __f, _InputIterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + template + hash_set(_InputIterator __f, _InputIterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + template + hash_set(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + template + hash_set(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_unique(__f, __l); } +#else + + hash_set(const value_type* __f, const value_type* __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_set(const value_type* __f, const value_type* __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_set(const value_type* __f, const value_type* __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_set(const value_type* __f, const value_type* __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_unique(__f, __l); } + + hash_set(const_iterator __f, const_iterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_set(const_iterator __f, const_iterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_set(const_iterator __f, const_iterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_set(const_iterator __f, const_iterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_unique(__f, __l); } +#endif /*__STL_MEMBER_TEMPLATES */ + +public: + size_type size() const { return _M_ht.size(); } + size_type max_size() const { return _M_ht.max_size(); } + bool empty() const { return _M_ht.empty(); } + void swap(hash_set& __hs) { _M_ht.swap(__hs._M_ht); } + friend bool operator== __STL_NULL_TMPL_ARGS (const hash_set&, + const hash_set&); + + iterator begin() const { return _M_ht.begin(); } + iterator end() const { return _M_ht.end(); } + +public: + pair insert(const value_type& __obj) + { + pair __p = _M_ht.insert_unique(__obj); + return pair(__p.first, __p.second); + } +#ifdef __STL_MEMBER_TEMPLATES + template + void insert(_InputIterator __f, _InputIterator __l) + { _M_ht.insert_unique(__f,__l); } +#else + void insert(const value_type* __f, const value_type* __l) { + _M_ht.insert_unique(__f,__l); + } + void insert(const_iterator __f, const_iterator __l) + {_M_ht.insert_unique(__f, __l); } +#endif /*__STL_MEMBER_TEMPLATES */ + pair insert_noresize(const value_type& __obj) + { + pair __p = + _M_ht.insert_unique_noresize(__obj); + return pair(__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 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 +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; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline void +swap(hash_set<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, + hash_set<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2) +{ + __hs1.swap(__hs2); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + + +#ifndef __STL_LIMITED_DEFAULT_TEMPLATES +template , + class _EqualKey = equal_to<_Value>, + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Value) > +#else +template +#endif +class hash_multiset +{ +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) {} + +#ifdef __STL_MEMBER_TEMPLATES + template + hash_multiset(_InputIterator __f, _InputIterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + template + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + template + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + template + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_equal(__f, __l); } +#else + + hash_multiset(const value_type* __f, const value_type* __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multiset(const value_type* __f, const value_type* __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multiset(const value_type* __f, const value_type* __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multiset(const value_type* __f, const value_type* __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_equal(__f, __l); } + + hash_multiset(const_iterator __f, const_iterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multiset(const_iterator __f, const_iterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multiset(const_iterator __f, const_iterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multiset(const_iterator __f, const_iterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_equal(__f, __l); } +#endif /*__STL_MEMBER_TEMPLATES */ + +public: + size_type size() const { return _M_ht.size(); } + size_type max_size() const { return _M_ht.max_size(); } + bool empty() const { return _M_ht.empty(); } + void swap(hash_multiset& hs) { _M_ht.swap(hs._M_ht); } + friend bool operator== __STL_NULL_TMPL_ARGS (const hash_multiset&, + const hash_multiset&); + + iterator begin() const { return _M_ht.begin(); } + iterator end() const { return _M_ht.end(); } + +public: + iterator insert(const value_type& __obj) + { return _M_ht.insert_equal(__obj); } +#ifdef __STL_MEMBER_TEMPLATES + template + void insert(_InputIterator __f, _InputIterator __l) + { _M_ht.insert_equal(__f,__l); } +#else + void insert(const value_type* __f, const value_type* __l) { + _M_ht.insert_equal(__f,__l); + } + void insert(const_iterator __f, const_iterator __l) + { _M_ht.insert_equal(__f, __l); } +#endif /*__STL_MEMBER_TEMPLATES */ + iterator insert_noresize(const value_type& __obj) + { return _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 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 +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; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline void +swap(hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, + hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2) { + __hs1.swap(__hs2); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#pragma reset woff 1375 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_HASH_SET_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/stl_hashtable.h b/headers/cpp/stl_hashtable.h new file mode 100644 index 0000000000..c0354fa38e --- /dev/null +++ b/headers/cpp/stl_hashtable.h @@ -0,0 +1,1039 @@ +/* + * 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. + * + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#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 +#include +#include +#include +#include +#include +#include +#include +#include + +__STL_BEGIN_NAMESPACE + +template +struct _Hashtable_node +{ + _Hashtable_node* _M_next; + _Val _M_val; +}; + +template +class hashtable; + +template +struct _Hashtable_iterator; + +template +struct _Hashtable_const_iterator; + +template +struct _Hashtable_iterator { + typedef hashtable<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc> + _Hashtable; + typedef _Hashtable_iterator<_Val, _Key, _HashFcn, + _ExtractKey, _EqualKey, _Alloc> + iterator; + typedef _Hashtable_const_iterator<_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; } +#ifndef __SGI_STL_NO_ARROW_OPERATOR + pointer operator->() const { return &(operator*()); } +#endif /* __SGI_STL_NO_ARROW_OPERATOR */ + iterator& operator++(); + iterator operator++(int); + bool operator==(const iterator& __it) const + { return _M_cur == __it._M_cur; } + bool operator!=(const iterator& __it) const + { return _M_cur != __it._M_cur; } +}; + + +template +struct _Hashtable_const_iterator { + typedef hashtable<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc> + _Hashtable; + typedef _Hashtable_iterator<_Val,_Key,_HashFcn, + _ExtractKey,_EqualKey,_Alloc> + iterator; + typedef _Hashtable_const_iterator<_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; } +#ifndef __SGI_STL_NO_ARROW_OPERATOR + pointer operator->() const { return &(operator*()); } +#endif /* __SGI_STL_NO_ARROW_OPERATOR */ + const_iterator& operator++(); + const_iterator operator++(int); + bool operator==(const const_iterator& __it) const + { return _M_cur == __it._M_cur; } + bool operator!=(const const_iterator& __it) const + { return _M_cur != __it._M_cur; } +}; + +// Note: assumes long is at least 32 bits. +static const int __stl_num_primes = 28; +static const unsigned long __stl_prime_list[__stl_num_primes] = +{ + 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 + __stl_num_primes; + const unsigned long* pos = lower_bound(__first, __last, __n); + return pos == __last ? *(__last - 1) : *pos; +} + +// Forward declaration of operator==. + +template +class hashtable; + +template +bool operator==(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1, + const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2); + + +// Hashtables handle allocators a bit differently than other containers +// do. If we're using standard-conforming allocators, then a hashtable +// unconditionally has a member variable to hold its allocator, even if +// it so happens that all instances of the allocator type are identical. +// This is because, for hashtables, this extra storage is negligible. +// Additionally, a base class wouldn't serve any other purposes; it +// wouldn't, for example, simplify the exception-handling code. + +template +class hashtable { +public: + typedef _Key key_type; + typedef _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; + +#ifdef __STL_USE_STD_ALLOCATORS +public: + typedef typename _Alloc_traits<_Val,_Alloc>::allocator_type allocator_type; + allocator_type get_allocator() const { return _M_node_allocator; } +private: + typename _Alloc_traits<_Node, _Alloc>::allocator_type _M_node_allocator; + _Node* _M_get_node() { return _M_node_allocator.allocate(1); } + void _M_put_node(_Node* __p) { _M_node_allocator.deallocate(__p, 1); } +# define __HASH_ALLOC_INIT(__a) _M_node_allocator(__a), +#else /* __STL_USE_STD_ALLOCATORS */ +public: + typedef _Alloc allocator_type; + allocator_type get_allocator() const { return allocator_type(); } +private: + typedef simple_alloc<_Node, _Alloc> _M_node_allocator_type; + _Node* _M_get_node() { return _M_node_allocator_type::allocate(1); } + void _M_put_node(_Node* __p) { _M_node_allocator_type::deallocate(__p, 1); } +# define __HASH_ALLOC_INIT(__a) +#endif /* __STL_USE_STD_ALLOCATORS */ + +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()) + : __HASH_ALLOC_INIT(__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()) + : __HASH_ALLOC_INIT(__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) + : __HASH_ALLOC_INIT(__ht.get_allocator()) + _M_hash(__ht._M_hash), + _M_equals(__ht._M_equals), + _M_get_key(__ht._M_get_key), + _M_buckets(__ht.get_allocator()), + _M_num_elements(0) + { + _M_copy_from(__ht); + } + +#undef __HASH_ALLOC_INIT + + 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); } + + friend bool + operator== __STL_NULL_TMPL_ARGS (const hashtable&, const hashtable&); + +public: + + size_type bucket_count() const { return _M_buckets.size(); } + + size_type max_bucket_count() const + { return __stl_prime_list[__stl_num_primes - 1]; } + + size_type elems_in_bucket(size_type __bucket) const + { + size_type __result = 0; + for (_Node* __cur = _M_buckets[__bucket]; __cur; __cur = __cur->_M_next) + __result += 1; + return __result; + } + + pair 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 insert_unique_noresize(const value_type& __obj); + iterator insert_equal_noresize(const value_type& __obj); + +#ifdef __STL_MEMBER_TEMPLATES + template + void insert_unique(_InputIterator __f, _InputIterator __l) + { + insert_unique(__f, __l, __ITERATOR_CATEGORY(__f)); + } + + template + void insert_equal(_InputIterator __f, _InputIterator __l) + { + insert_equal(__f, __l, __ITERATOR_CATEGORY(__f)); + } + + template + void insert_unique(_InputIterator __f, _InputIterator __l, + input_iterator_tag) + { + for ( ; __f != __l; ++__f) + insert_unique(*__f); + } + + template + void insert_equal(_InputIterator __f, _InputIterator __l, + input_iterator_tag) + { + for ( ; __f != __l; ++__f) + insert_equal(*__f); + } + + template + void insert_unique(_ForwardIterator __f, _ForwardIterator __l, + forward_iterator_tag) + { + size_type __n = 0; + distance(__f, __l, __n); + resize(_M_num_elements + __n); + for ( ; __n > 0; --__n, ++__f) + insert_unique_noresize(*__f); + } + + template + void insert_equal(_ForwardIterator __f, _ForwardIterator __l, + forward_iterator_tag) + { + size_type __n = 0; + distance(__f, __l, __n); + resize(_M_num_elements + __n); + for ( ; __n > 0; --__n, ++__f) + insert_equal_noresize(*__f); + } + +#else /* __STL_MEMBER_TEMPLATES */ + void insert_unique(const value_type* __f, const value_type* __l) + { + size_type __n = __l - __f; + resize(_M_num_elements + __n); + for ( ; __n > 0; --__n, ++__f) + insert_unique_noresize(*__f); + } + + void insert_equal(const value_type* __f, const value_type* __l) + { + size_type __n = __l - __f; + resize(_M_num_elements + __n); + for ( ; __n > 0; --__n, ++__f) + insert_equal_noresize(*__f); + } + + void insert_unique(const_iterator __f, const_iterator __l) + { + size_type __n = 0; + distance(__f, __l, __n); + resize(_M_num_elements + __n); + for ( ; __n > 0; --__n, ++__f) + insert_unique_noresize(*__f); + } + + void insert_equal(const_iterator __f, const_iterator __l) + { + size_type __n = 0; + distance(__f, __l, __n); + resize(_M_num_elements + __n); + for ( ; __n > 0; --__n, ++__f) + insert_equal_noresize(*__f); + } +#endif /*__STL_MEMBER_TEMPLATES */ + + reference find_or_insert(const value_type& __obj); + + 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 + equal_range(const key_type& __key); + + pair + 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; + __STL_TRY { + construct(&__n->_M_val, __obj); + return __n; + } + __STL_UNWIND(_M_put_node(__n)); + } + + 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 +_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 +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 +_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 +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; +} + +#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +inline forward_iterator_tag +iterator_category(const _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&) +{ + return forward_iterator_tag(); +} + +template +inline _Val* +value_type(const _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&) +{ + return (_Val*) 0; +} + +template +inline hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::difference_type* +distance_type(const _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&) +{ + return (hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::difference_type*) 0; +} + +template +inline forward_iterator_tag +iterator_category(const _Hashtable_const_iterator<_Val,_Key,_HF, + _ExK,_EqK,_All>&) +{ + return forward_iterator_tag(); +} + +template +inline _Val* +value_type(const _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&) +{ + return (_Val*) 0; +} + +template +inline hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::difference_type* +distance_type(const _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&) +{ + return (hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::difference_type*) 0; +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template +inline bool operator==(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1, + const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2) +{ + typedef typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::_Node _Node; + if (__ht1._M_buckets.size() != __ht2._M_buckets.size()) + return false; + for (int __n = 0; __n < __ht1._M_buckets.size(); ++__n) { + _Node* __cur1 = __ht1._M_buckets[__n]; + _Node* __cur2 = __ht2._M_buckets[__n]; + for ( ; __cur1 && __cur2 && __cur1->_M_val == __cur2->_M_val; + __cur1 = __cur1->_M_next, __cur2 = __cur2->_M_next) + {} + if (__cur1 || __cur2) + return false; + } + return true; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline void swap(hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht1, + hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht2) { + __ht1.swap(__ht2); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + + +template +pair::iterator, bool> +hashtable<_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(__cur, this), false); + + _Node* __tmp = _M_new_node(__obj); + __tmp->_M_next = __first; + _M_buckets[__n] = __tmp; + ++_M_num_elements; + return pair(iterator(__tmp, this), true); +} + +template +typename hashtable<_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 +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 +pair::iterator, + typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator> +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::equal_range(const key_type& __key) +{ + typedef pair _Pii; + const size_type __n = _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 +pair::const_iterator, + typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::const_iterator> +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::equal_range(const key_type& __key) const +{ + typedef pair _Pii; + const size_type __n = _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 +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 +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const iterator& __it) +{ + if (_Node* const __p = __it._M_cur) { + const size_type __n = _M_bkt_num(__p->_M_val); + _Node* __cur = _M_buckets[__n]; + + if (__cur == __p) { + _M_buckets[__n] = __cur->_M_next; + _M_delete_node(__cur); + --_M_num_elements; + } + else { + _Node* __next = __cur->_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 +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 +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(__first._M_ht)), + iterator(const_cast<_Node*>(__last._M_cur), + const_cast(__last._M_ht))); +} + +template +inline void +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const const_iterator& __it) +{ + erase(iterator(const_cast<_Node*>(__it._M_cur), + const_cast(__it._M_ht))); +} + +template +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()); + __STL_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); + } +# ifdef __STL_USE_EXCEPTIONS + 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; + } +# endif /* __STL_USE_EXCEPTIONS */ + } + } +} + +template +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) { + __cur->_M_next = __next->_M_next; + _M_delete_node(__next); + __next = __cur->_M_next; + --_M_num_elements; + } + } +} + +template +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 +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 +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); + __STL_TRY { + for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) { + if (const _Node* __cur = __ht._M_buckets[__i]) { + _Node* ___copy = _M_new_node(__cur->_M_val); + _M_buckets[__i] = ___copy; + + for (_Node* __next = __cur->_M_next; + __next; + __cur = __next, __next = __cur->_M_next) { + ___copy->_M_next = _M_new_node(__next->_M_val); + ___copy = ___copy->_M_next; + } + } + } + _M_num_elements = __ht._M_num_elements; + } + __STL_UNWIND(clear()); +} + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_HASHTABLE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/stl_heap.h b/headers/cpp/stl_heap.h new file mode 100644 index 0000000000..62f142ec97 --- /dev/null +++ b/headers/cpp/stl_heap.h @@ -0,0 +1,281 @@ +/* + * + * 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) 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. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_HEAP_H +#define __SGI_STL_INTERNAL_HEAP_H + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1209 +#endif + +// Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap. + +template +void +__push_heap(_RandomAccessIterator __first, + _Distance __holeIndex, _Distance __topIndex, _Tp __value) +{ + _Distance __parent = (__holeIndex - 1) / 2; + while (__holeIndex > __topIndex && *(__first + __parent) < __value) { + *(__first + __holeIndex) = *(__first + __parent); + __holeIndex = __parent; + __parent = (__holeIndex - 1) / 2; + } + *(__first + __holeIndex) = __value; +} + +template +inline void +__push_heap_aux(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Distance*, _Tp*) +{ + __push_heap(__first, _Distance((__last - __first) - 1), _Distance(0), + _Tp(*(__last - 1))); +} + +template +inline void +push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) +{ + __push_heap_aux(__first, __last, + __DISTANCE_TYPE(__first), __VALUE_TYPE(__first)); +} + +template +void +__push_heap(_RandomAccessIterator __first, _Distance __holeIndex, + _Distance __topIndex, _Tp __value, _Compare __comp) +{ + _Distance __parent = (__holeIndex - 1) / 2; + while (__holeIndex > __topIndex && __comp(*(__first + __parent), __value)) { + *(__first + __holeIndex) = *(__first + __parent); + __holeIndex = __parent; + __parent = (__holeIndex - 1) / 2; + } + *(__first + __holeIndex) = __value; +} + +template +inline void +__push_heap_aux(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp, + _Distance*, _Tp*) +{ + __push_heap(__first, _Distance((__last - __first) - 1), _Distance(0), + _Tp(*(__last - 1)), __comp); +} + +template +inline void +push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) +{ + __push_heap_aux(__first, __last, __comp, + __DISTANCE_TYPE(__first), __VALUE_TYPE(__first)); +} + +template +void +__adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex, + _Distance __len, _Tp __value) +{ + _Distance __topIndex = __holeIndex; + _Distance __secondChild = 2 * __holeIndex + 2; + while (__secondChild < __len) { + if (*(__first + __secondChild) < *(__first + (__secondChild - 1))) + __secondChild--; + *(__first + __holeIndex) = *(__first + __secondChild); + __holeIndex = __secondChild; + __secondChild = 2 * (__secondChild + 1); + } + if (__secondChild == __len) { + *(__first + __holeIndex) = *(__first + (__secondChild - 1)); + __holeIndex = __secondChild - 1; + } + __push_heap(__first, __holeIndex, __topIndex, __value); +} + +template +inline void +__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _RandomAccessIterator __result, _Tp __value, _Distance*) +{ + *__result = *__first; + __adjust_heap(__first, _Distance(0), _Distance(__last - __first), __value); +} + +template +inline void +__pop_heap_aux(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Tp*) +{ + __pop_heap(__first, __last - 1, __last - 1, + _Tp(*(__last - 1)), __DISTANCE_TYPE(__first)); +} + +template +inline void pop_heap(_RandomAccessIterator __first, + _RandomAccessIterator __last) +{ + __pop_heap_aux(__first, __last, __VALUE_TYPE(__first)); +} + +template +void +__adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex, + _Distance __len, _Tp __value, _Compare __comp) +{ + _Distance __topIndex = __holeIndex; + _Distance __secondChild = 2 * __holeIndex + 2; + while (__secondChild < __len) { + if (__comp(*(__first + __secondChild), *(__first + (__secondChild - 1)))) + __secondChild--; + *(__first + __holeIndex) = *(__first + __secondChild); + __holeIndex = __secondChild; + __secondChild = 2 * (__secondChild + 1); + } + if (__secondChild == __len) { + *(__first + __holeIndex) = *(__first + (__secondChild - 1)); + __holeIndex = __secondChild - 1; + } + __push_heap(__first, __holeIndex, __topIndex, __value, __comp); +} + +template +inline void +__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _RandomAccessIterator __result, _Tp __value, _Compare __comp, + _Distance*) +{ + *__result = *__first; + __adjust_heap(__first, _Distance(0), _Distance(__last - __first), + __value, __comp); +} + +template +inline void +__pop_heap_aux(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Tp*, _Compare __comp) +{ + __pop_heap(__first, __last - 1, __last - 1, _Tp(*(__last - 1)), __comp, + __DISTANCE_TYPE(__first)); +} + +template +inline void +pop_heap(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) +{ + __pop_heap_aux(__first, __last, __VALUE_TYPE(__first), __comp); +} + +template +void +__make_heap(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Tp*, _Distance*) +{ + if (__last - __first < 2) return; + _Distance __len = __last - __first; + _Distance __parent = (__len - 2)/2; + + while (true) { + __adjust_heap(__first, __parent, __len, _Tp(*(__first + __parent))); + if (__parent == 0) return; + __parent--; + } +} + +template +inline void +make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) +{ + __make_heap(__first, __last, + __VALUE_TYPE(__first), __DISTANCE_TYPE(__first)); +} + +template +void +__make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp, _Tp*, _Distance*) +{ + if (__last - __first < 2) return; + _Distance __len = __last - __first; + _Distance __parent = (__len - 2)/2; + + while (true) { + __adjust_heap(__first, __parent, __len, _Tp(*(__first + __parent)), + __comp); + if (__parent == 0) return; + __parent--; + } +} + +template +inline void +make_heap(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) +{ + __make_heap(__first, __last, __comp, + __VALUE_TYPE(__first), __DISTANCE_TYPE(__first)); +} + +template +void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) +{ + while (__last - __first > 1) + pop_heap(__first, __last--); +} + +template +void +sort_heap(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) +{ + while (__last - __first > 1) + pop_heap(__first, __last--, __comp); +} + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1209 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_HEAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/stl_iterator.h b/headers/cpp/stl_iterator.h new file mode 100644 index 0000000000..e2bd714969 --- /dev/null +++ b/headers/cpp/stl_iterator.h @@ -0,0 +1,915 @@ +/* + * + * 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. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_ITERATOR_H +#define __SGI_STL_INTERNAL_ITERATOR_H + +__STL_BEGIN_NAMESPACE + +struct input_iterator_tag {}; +struct output_iterator_tag {}; +struct forward_iterator_tag : public input_iterator_tag {}; +struct bidirectional_iterator_tag : public forward_iterator_tag {}; +struct random_access_iterator_tag : public bidirectional_iterator_tag {}; + +// The base classes input_iterator, output_iterator, forward_iterator, +// bidirectional_iterator, and random_access_iterator are not part of +// the C++ standard. (they have been replaced by struct iterator.) +// They are included for backward compatibility with the HP STL. + +template struct input_iterator { + typedef input_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; +}; + +struct output_iterator { + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; +}; + +template struct forward_iterator { + typedef forward_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; +}; + + +template struct bidirectional_iterator { + typedef bidirectional_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; +}; + +template struct random_access_iterator { + typedef random_access_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; +}; + +#ifdef __STL_USE_NAMESPACES +template +struct iterator { + typedef _Category iterator_category; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Pointer pointer; + typedef _Reference reference; +}; +#endif /* __STL_USE_NAMESPACES */ + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +struct iterator_traits { + typedef typename _Iterator::iterator_category iterator_category; + typedef typename _Iterator::value_type value_type; + typedef typename _Iterator::difference_type difference_type; + typedef typename _Iterator::pointer pointer; + typedef typename _Iterator::reference reference; +}; + +template +struct iterator_traits<_Tp*> { + typedef random_access_iterator_tag iterator_category; + typedef _Tp value_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; +}; + +template +struct iterator_traits { + typedef random_access_iterator_tag iterator_category; + typedef _Tp value_type; + typedef ptrdiff_t difference_type; + typedef const _Tp* pointer; + typedef const _Tp& reference; +}; + +// The overloaded functions iterator_category, distance_type, and +// value_type are not part of the C++ standard. (They have been +// replaced by struct iterator_traits.) They are included for +// backward compatibility with the HP STL. + +// We introduce internal names for these functions. + +template +inline typename iterator_traits<_Iter>::iterator_category +__iterator_category(const _Iter&) +{ + typedef typename iterator_traits<_Iter>::iterator_category _Category; + return _Category(); +} + +template +inline typename iterator_traits<_Iter>::difference_type* +__distance_type(const _Iter&) +{ + return static_cast::difference_type*>(0); +} + +template +inline typename iterator_traits<_Iter>::value_type* +__value_type(const _Iter&) +{ + return static_cast::value_type*>(0); +} + +template +inline typename iterator_traits<_Iter>::iterator_category +iterator_category(const _Iter& __i) { return __iterator_category(__i); } + + +template +inline typename iterator_traits<_Iter>::difference_type* +distance_type(const _Iter& __i) { return __distance_type(__i); } + +template +inline typename iterator_traits<_Iter>::value_type* +value_type(const _Iter& __i) { return __value_type(__i); } + +#define __ITERATOR_CATEGORY(__i) __iterator_category(__i) +#define __DISTANCE_TYPE(__i) __distance_type(__i) +#define __VALUE_TYPE(__i) __value_type(__i) + +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template +inline input_iterator_tag +iterator_category(const input_iterator<_Tp, _Distance>&) + { return input_iterator_tag(); } + +inline output_iterator_tag iterator_category(const output_iterator&) + { return output_iterator_tag(); } + +template +inline forward_iterator_tag +iterator_category(const forward_iterator<_Tp, _Distance>&) + { return forward_iterator_tag(); } + +template +inline bidirectional_iterator_tag +iterator_category(const bidirectional_iterator<_Tp, _Distance>&) + { return bidirectional_iterator_tag(); } + +template +inline random_access_iterator_tag +iterator_category(const random_access_iterator<_Tp, _Distance>&) + { return random_access_iterator_tag(); } + +template +inline random_access_iterator_tag iterator_category(const _Tp*) + { return random_access_iterator_tag(); } + +template +inline _Tp* value_type(const input_iterator<_Tp, _Distance>&) + { return (_Tp*)(0); } + +template +inline _Tp* value_type(const forward_iterator<_Tp, _Distance>&) + { return (_Tp*)(0); } + +template +inline _Tp* value_type(const bidirectional_iterator<_Tp, _Distance>&) + { return (_Tp*)(0); } + +template +inline _Tp* value_type(const random_access_iterator<_Tp, _Distance>&) + { return (_Tp*)(0); } + +template +inline _Tp* value_type(const _Tp*) { return (_Tp*)(0); } + +template +inline _Distance* distance_type(const input_iterator<_Tp, _Distance>&) +{ + return (_Distance*)(0); +} + +template +inline _Distance* distance_type(const forward_iterator<_Tp, _Distance>&) +{ + return (_Distance*)(0); +} + +template +inline _Distance* +distance_type(const bidirectional_iterator<_Tp, _Distance>&) +{ + return (_Distance*)(0); +} + +template +inline _Distance* +distance_type(const random_access_iterator<_Tp, _Distance>&) +{ + return (_Distance*)(0); +} + +template +inline ptrdiff_t* distance_type(const _Tp*) { return (ptrdiff_t*)(0); } + +// Without partial specialization we can't use iterator_traits, so +// we must keep the old iterator query functions around. + +#define __ITERATOR_CATEGORY(__i) iterator_category(__i) +#define __DISTANCE_TYPE(__i) distance_type(__i) +#define __VALUE_TYPE(__i) value_type(__i) + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template +inline void __distance(_InputIterator __first, _InputIterator __last, + _Distance& __n, input_iterator_tag) +{ + while (__first != __last) { ++__first; ++__n; } +} + +template +inline void __distance(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Distance& __n, random_access_iterator_tag) +{ + __n += __last - __first; +} + +template +inline void distance(_InputIterator __first, + _InputIterator __last, _Distance& __n) +{ + __distance(__first, __last, __n, iterator_category(__first)); +} + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +inline typename iterator_traits<_InputIterator>::difference_type +__distance(_InputIterator __first, _InputIterator __last, input_iterator_tag) +{ + typename iterator_traits<_InputIterator>::difference_type __n = 0; + while (__first != __last) { + ++__first; ++__n; + } + return __n; +} + +template +inline typename iterator_traits<_RandomAccessIterator>::difference_type +__distance(_RandomAccessIterator __first, _RandomAccessIterator __last, + random_access_iterator_tag) { + return __last - __first; +} + +template +inline typename iterator_traits<_InputIterator>::difference_type +distance(_InputIterator __first, _InputIterator __last) { + typedef typename iterator_traits<_InputIterator>::iterator_category + _Category; + return __distance(__first, __last, _Category()); +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template +inline void __advance(_InputIter& __i, _Distance __n, input_iterator_tag) { + while (__n--) ++__i; +} + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1183 +#endif + +template +inline void __advance(_BidirectionalIterator& __i, _Distance __n, + bidirectional_iterator_tag) { + if (__n >= 0) + while (__n--) ++__i; + else + while (__n++) --__i; +} + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1183 +#endif + +template +inline void __advance(_RandomAccessIterator& __i, _Distance __n, + random_access_iterator_tag) { + __i += __n; +} + +template +inline void advance(_InputIterator& __i, _Distance __n) { + __advance(__i, __n, iterator_category(__i)); +} + +template +class back_insert_iterator { +protected: + _Container* container; +public: + typedef _Container container_type; + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + explicit back_insert_iterator(_Container& __x) : container(&__x) {} + back_insert_iterator<_Container>& + operator=(const typename _Container::value_type& __value) { + container->push_back(__value); + return *this; + } + back_insert_iterator<_Container>& operator*() { return *this; } + back_insert_iterator<_Container>& operator++() { return *this; } + back_insert_iterator<_Container>& operator++(int) { return *this; } +}; + +#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +inline output_iterator_tag +iterator_category(const back_insert_iterator<_Container>&) +{ + return output_iterator_tag(); +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template +inline back_insert_iterator<_Container> back_inserter(_Container& __x) { + return back_insert_iterator<_Container>(__x); +} + +template +class front_insert_iterator { +protected: + _Container* container; +public: + typedef _Container container_type; + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + explicit front_insert_iterator(_Container& __x) : container(&__x) {} + front_insert_iterator<_Container>& + operator=(const typename _Container::value_type& __value) { + container->push_front(__value); + return *this; + } + front_insert_iterator<_Container>& operator*() { return *this; } + front_insert_iterator<_Container>& operator++() { return *this; } + front_insert_iterator<_Container>& operator++(int) { return *this; } +}; + +#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +inline output_iterator_tag +iterator_category(const front_insert_iterator<_Container>&) +{ + return output_iterator_tag(); +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template +inline front_insert_iterator<_Container> front_inserter(_Container& __x) { + return front_insert_iterator<_Container>(__x); +} + +template +class insert_iterator { +protected: + _Container* container; + typename _Container::iterator iter; +public: + typedef _Container container_type; + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + insert_iterator(_Container& __x, typename _Container::iterator __i) + : container(&__x), iter(__i) {} + insert_iterator<_Container>& + operator=(const typename _Container::value_type& __value) { + iter = container->insert(iter, __value); + ++iter; + return *this; + } + insert_iterator<_Container>& operator*() { return *this; } + insert_iterator<_Container>& operator++() { return *this; } + insert_iterator<_Container>& operator++(int) { return *this; } +}; + +#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +inline output_iterator_tag +iterator_category(const insert_iterator<_Container>&) +{ + return output_iterator_tag(); +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template +inline +insert_iterator<_Container> inserter(_Container& __x, _Iterator __i) +{ + typedef typename _Container::iterator __iter; + return insert_iterator<_Container>(__x, __iter(__i)); +} + +#ifndef __STL_LIMITED_DEFAULT_TEMPLATES +template +#else +template +#endif +class reverse_bidirectional_iterator { + typedef reverse_bidirectional_iterator<_BidirectionalIterator, _Tp, + _Reference, _Distance> _Self; +protected: + _BidirectionalIterator current; +public: + typedef bidirectional_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Reference reference; + + reverse_bidirectional_iterator() {} + explicit reverse_bidirectional_iterator(_BidirectionalIterator __x) + : current(__x) {} + _BidirectionalIterator base() const { return current; } + _Reference operator*() const { + _BidirectionalIterator __tmp = current; + return *--__tmp; + } +#ifndef __SGI_STL_NO_ARROW_OPERATOR + pointer operator->() const { return &(operator*()); } +#endif /* __SGI_STL_NO_ARROW_OPERATOR */ + _Self& operator++() { + --current; + return *this; + } + _Self operator++(int) { + _Self __tmp = *this; + --current; + return __tmp; + } + _Self& operator--() { + ++current; + return *this; + } + _Self operator--(int) { + _Self __tmp = *this; + ++current; + return __tmp; + } +}; + +#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +inline bidirectional_iterator_tag +iterator_category(const reverse_bidirectional_iterator<_BidirectionalIterator, + _Tp, _Reference, + _Distance>&) +{ + return bidirectional_iterator_tag(); +} + +template +inline _Tp* +value_type(const reverse_bidirectional_iterator<_BidirectionalIterator, _Tp, + _Reference, _Distance>&) +{ + return (_Tp*) 0; +} + +template +inline _Distance* +distance_type(const reverse_bidirectional_iterator<_BidirectionalIterator, + _Tp, + _Reference, _Distance>&) +{ + return (_Distance*) 0; +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template +inline bool operator==( + const reverse_bidirectional_iterator<_BiIter, _Tp, _Ref, _Distance>& __x, + const reverse_bidirectional_iterator<_BiIter, _Tp, _Ref, _Distance>& __y) +{ + return __x.base() == __y.base(); +} + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + +// This is the new version of reverse_iterator, as defined in the +// draft C++ standard. It relies on the iterator_traits template, +// which in turn relies on partial specialization. The class +// reverse_bidirectional_iterator is no longer part of the draft +// standard, but it is retained for backward compatibility. + +template +class reverse_iterator +{ +protected: + _Iterator current; +public: + typedef typename iterator_traits<_Iterator>::iterator_category + iterator_category; + typedef typename iterator_traits<_Iterator>::value_type + value_type; + typedef typename iterator_traits<_Iterator>::difference_type + difference_type; + typedef typename iterator_traits<_Iterator>::pointer + pointer; + typedef typename iterator_traits<_Iterator>::reference + reference; + + typedef _Iterator iterator_type; + typedef reverse_iterator<_Iterator> _Self; + +public: + reverse_iterator() {} + explicit reverse_iterator(iterator_type __x) : current(__x) {} + + reverse_iterator(const _Self& __x) : current(__x.current) {} +#ifdef __STL_MEMBER_TEMPLATES + template + reverse_iterator(const reverse_iterator<_Iter>& __x) + : current(__x.base()) {} +#endif /* __STL_MEMBER_TEMPLATES */ + + iterator_type base() const { return current; } + reference operator*() const { + _Iterator __tmp = current; + return *--__tmp; + } +#ifndef __SGI_STL_NO_ARROW_OPERATOR + pointer operator->() const { return &(operator*()); } +#endif /* __SGI_STL_NO_ARROW_OPERATOR */ + + _Self& operator++() { + --current; + return *this; + } + _Self operator++(int) { + _Self __tmp = *this; + --current; + return __tmp; + } + _Self& operator--() { + ++current; + return *this; + } + _Self operator--(int) { + _Self __tmp = *this; + ++current; + return __tmp; + } + + _Self operator+(difference_type __n) const { + return _Self(current - __n); + } + _Self& operator+=(difference_type __n) { + current -= __n; + return *this; + } + _Self operator-(difference_type __n) const { + return _Self(current + __n); + } + _Self& operator-=(difference_type __n) { + current += __n; + return *this; + } + reference operator[](difference_type __n) const { return *(*this + __n); } +}; + +template +inline bool operator==(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) { + return __x.base() == __y.base(); +} + +template +inline bool operator<(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) { + return __y.base() < __x.base(); +} + +template +inline typename reverse_iterator<_Iterator>::difference_type +operator-(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) { + return __y.base() - __x.base(); +} + +template +inline reverse_iterator<_Iterator> +operator+(typename reverse_iterator<_Iterator>::difference_type __n, + const reverse_iterator<_Iterator>& __x) { + return reverse_iterator<_Iterator>(__x.base() - __n); +} + +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +// This is the old version of reverse_iterator, as found in the original +// HP STL. It does not use partial specialization. + +#ifndef __STL_LIMITED_DEFAULT_TEMPLATES +template +#else +template +#endif +class reverse_iterator { + typedef reverse_iterator<_RandomAccessIterator, _Tp, _Reference, _Distance> + _Self; +protected: + _RandomAccessIterator current; +public: + typedef random_access_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Reference reference; + + reverse_iterator() {} + explicit reverse_iterator(_RandomAccessIterator __x) : current(__x) {} + _RandomAccessIterator base() const { return current; } + _Reference operator*() const { return *(current - 1); } +#ifndef __SGI_STL_NO_ARROW_OPERATOR + pointer operator->() const { return &(operator*()); } +#endif /* __SGI_STL_NO_ARROW_OPERATOR */ + _Self& operator++() { + --current; + return *this; + } + _Self operator++(int) { + _Self __tmp = *this; + --current; + return __tmp; + } + _Self& operator--() { + ++current; + return *this; + } + _Self operator--(int) { + _Self __tmp = *this; + ++current; + return __tmp; + } + _Self operator+(_Distance __n) const { + return _Self(current - __n); + } + _Self& operator+=(_Distance __n) { + current -= __n; + return *this; + } + _Self operator-(_Distance __n) const { + return _Self(current + __n); + } + _Self& operator-=(_Distance __n) { + current += __n; + return *this; + } + _Reference operator[](_Distance __n) const { return *(*this + __n); } +}; + +template +inline random_access_iterator_tag +iterator_category(const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>&) +{ + return random_access_iterator_tag(); +} + +template +inline _Tp* value_type(const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>&) +{ + return (_Tp*) 0; +} + +template +inline _Distance* +distance_type(const reverse_iterator<_RandomAccessIterator, + _Tp, _Reference, _Distance>&) +{ + return (_Distance*) 0; +} + + +template +inline bool +operator==(const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __x, + const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __y) +{ + return __x.base() == __y.base(); +} + +template +inline bool +operator<(const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __x, + const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __y) +{ + return __y.base() < __x.base(); +} + +template +inline _Distance +operator-(const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __x, + const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __y) +{ + return __y.base() - __x.base(); +} + +template +inline reverse_iterator<_RandAccIter, _Tp, _Ref, _Dist> +operator+(_Dist __n, + const reverse_iterator<_RandAccIter, _Tp, _Ref, _Dist>& __x) +{ + return reverse_iterator<_RandAccIter, _Tp, _Ref, _Dist>(__x.base() - __n); +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +// When we have templatized iostreams, istream_iterator and ostream_iterator +// must be rewritten. + +template +class istream_iterator { + friend bool operator== __STL_NULL_TMPL_ARGS (const istream_iterator&, + const istream_iterator&); +protected: + istream* _M_stream; + _Tp _M_value; + bool _M_end_marker; + void _M_read() { + _M_end_marker = (*_M_stream) ? true : false; + if (_M_end_marker) *_M_stream >> _M_value; + _M_end_marker = (*_M_stream) ? true : false; + } +public: + typedef input_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Dist difference_type; + typedef const _Tp* pointer; + typedef const _Tp& reference; + + istream_iterator() : _M_stream(&cin), _M_end_marker(false) {} + istream_iterator(istream& __s) : _M_stream(&__s) { _M_read(); } + reference operator*() const { return _M_value; } +#ifndef __SGI_STL_NO_ARROW_OPERATOR + pointer operator->() const { return &(operator*()); } +#endif /* __SGI_STL_NO_ARROW_OPERATOR */ + istream_iterator<_Tp, _Dist>& operator++() { + _M_read(); + return *this; + } + istream_iterator<_Tp, _Dist> operator++(int) { + istream_iterator<_Tp, _Dist> __tmp = *this; + _M_read(); + return __tmp; + } +}; + +#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +inline input_iterator_tag +iterator_category(const istream_iterator<_Tp, _Dist>&) +{ + return input_iterator_tag(); +} + +template +inline _Tp* +value_type(const istream_iterator<_Tp, _Dist>&) { return (_Tp*) 0; } + +template +inline _Dist* +distance_type(const istream_iterator<_Tp, _Dist>&) { return (_Dist*)0; } + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template +inline bool operator==(const istream_iterator<_Tp, _Distance>& __x, + const istream_iterator<_Tp, _Distance>& __y) { + return (__x._M_stream == __y._M_stream && + __x._M_end_marker == __y._M_end_marker) || + __x._M_end_marker == false && __y._M_end_marker == false; +} + +template +class ostream_iterator { +protected: + ostream* _M_stream; + const char* _M_string; +public: + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + ostream_iterator(ostream& __s) : _M_stream(&__s), _M_string(0) {} + ostream_iterator(ostream& __s, const char* __c) + : _M_stream(&__s), _M_string(__c) {} + ostream_iterator<_Tp>& operator=(const _Tp& __value) { + *_M_stream << __value; + if (_M_string) *_M_stream << _M_string; + return *this; + } + ostream_iterator<_Tp>& operator*() { return *this; } + ostream_iterator<_Tp>& operator++() { return *this; } + ostream_iterator<_Tp>& operator++(int) { return *this; } +}; + +#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +inline output_iterator_tag +iterator_category(const ostream_iterator<_Tp>&) { + return output_iterator_tag(); +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_ITERATOR_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/stl_list.h b/headers/cpp/stl_list.h new file mode 100644 index 0000000000..5d95d641e5 --- /dev/null +++ b/headers/cpp/stl_list.h @@ -0,0 +1,840 @@ +/* + * + * 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,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. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_LIST_H +#define __SGI_STL_INTERNAL_LIST_H + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1174 +#pragma set woff 1375 +#endif + +template +struct _List_node { + typedef void* _Void_pointer; + _Void_pointer _M_next; + _Void_pointer _M_prev; + _Tp _M_data; +}; + +template +struct _List_iterator { + typedef _List_iterator<_Tp,_Tp&,_Tp*> iterator; + typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator; + typedef _List_iterator<_Tp,_Ref,_Ptr> _Self; + + typedef bidirectional_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Ptr pointer; + typedef _Ref reference; + typedef _List_node<_Tp> _Node; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + + _Node* _M_node; + + _List_iterator(_Node* __x) : _M_node(__x) {} + _List_iterator() {} + _List_iterator(const iterator& __x) : _M_node(__x._M_node) {} + + bool operator==(const _Self& __x) const { return _M_node == __x._M_node; } + bool operator!=(const _Self& __x) const { return _M_node != __x._M_node; } + reference operator*() const { return (*_M_node)._M_data; } + +#ifndef __SGI_STL_NO_ARROW_OPERATOR + pointer operator->() const { return &(operator*()); } +#endif /* __SGI_STL_NO_ARROW_OPERATOR */ + + _Self& operator++() { + _M_node = (_Node*)(_M_node->_M_next); + return *this; + } + _Self operator++(int) { + _Self __tmp = *this; + ++*this; + return __tmp; + } + _Self& operator--() { + _M_node = (_Node*)(_M_node->_M_prev); + return *this; + } + _Self operator--(int) { + _Self __tmp = *this; + --*this; + return __tmp; + } +}; + +#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +inline bidirectional_iterator_tag +iterator_category(const _List_iterator<_Tp, _Ref, _Ptr>&) +{ + return bidirectional_iterator_tag(); +} + +template +inline _Tp* +value_type(const _List_iterator<_Tp, _Ref, _Ptr>&) +{ + return 0; +} + +template +inline ptrdiff_t* +distance_type(const _List_iterator<_Tp, _Ref, _Ptr>&) +{ + return 0; +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + + +// Base class that encapsulates details of allocators. Three cases: +// an ordinary standard-conforming allocator, a standard-conforming +// allocator with no non-static data, and an SGI-style allocator. +// This complexity is necessary only because we're worrying about backward +// compatibility and because we want to avoid wasting storage on an +// allocator instance if it isn't necessary. + +#ifdef __STL_USE_STD_ALLOCATORS + +// Base for general standard-conforming allocators. +template +class _List_alloc_base { +public: + typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return _Node_allocator; } + + _List_alloc_base(const allocator_type& __a) : _Node_allocator(__a) {} + +protected: + _List_node<_Tp>* _M_get_node() + { return _Node_allocator.allocate(1); } + void _M_put_node(_List_node<_Tp>* __p) + { _Node_allocator.deallocate(__p, 1); } + +protected: + typename _Alloc_traits<_List_node<_Tp>, _Allocator>::allocator_type + _Node_allocator; + _List_node<_Tp>* _M_node; +}; + +// Specialization for instanceless allocators. + +template +class _List_alloc_base<_Tp, _Allocator, true> { +public: + typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _List_alloc_base(const allocator_type&) {} + +protected: + typedef typename _Alloc_traits<_List_node<_Tp>, _Allocator>::_Alloc_type + _Alloc_type; + _List_node<_Tp>* _M_get_node() { return _Alloc_type::allocate(1); } + void _M_put_node(_List_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); } + +protected: + _List_node<_Tp>* _M_node; +}; + +template +class _List_base + : public _List_alloc_base<_Tp, _Alloc, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> +{ +public: + typedef _List_alloc_base<_Tp, _Alloc, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> + _Base; + typedef typename _Base::allocator_type allocator_type; + + _List_base(const allocator_type& __a) : _Base(__a) { + _M_node = _M_get_node(); + _M_node->_M_next = _M_node; + _M_node->_M_prev = _M_node; + } + ~_List_base() { + clear(); + _M_put_node(_M_node); + } + + void clear(); +}; + +#else /* __STL_USE_STD_ALLOCATORS */ + +template +class _List_base +{ +public: + typedef _Alloc allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _List_base(const allocator_type&) { + _M_node = _M_get_node(); + _M_node->_M_next = _M_node; + _M_node->_M_prev = _M_node; + } + ~_List_base() { + clear(); + _M_put_node(_M_node); + } + + void clear(); + +protected: + typedef simple_alloc<_List_node<_Tp>, _Alloc> _Alloc_type; + _List_node<_Tp>* _M_get_node() { return _Alloc_type::allocate(1); } + void _M_put_node(_List_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); } + +protected: + _List_node<_Tp>* _M_node; +}; + +#endif /* __STL_USE_STD_ALLOCATORS */ + +template +void +_List_base<_Tp,_Alloc>::clear() +{ + _List_node<_Tp>* __cur = (_List_node<_Tp>*) _M_node->_M_next; + while (__cur != _M_node) { + _List_node<_Tp>* __tmp = __cur; + __cur = (_List_node<_Tp>*) __cur->_M_next; + destroy(&__tmp->_M_data); + _M_put_node(__tmp); + } + _M_node->_M_next = _M_node; + _M_node->_M_prev = _M_node; +} + +template +class list : protected _List_base<_Tp, _Alloc> { + typedef _List_base<_Tp, _Alloc> _Base; +protected: + typedef void* _Void_pointer; + +public: + typedef _Tp value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef _List_node<_Tp> _Node; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + + typedef typename _Base::allocator_type allocator_type; + allocator_type get_allocator() const { return _Base::get_allocator(); } + +public: + typedef _List_iterator<_Tp,_Tp&,_Tp*> iterator; + typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator; + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + typedef reverse_iterator const_reverse_iterator; + typedef reverse_iterator reverse_iterator; +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + typedef reverse_bidirectional_iterator + const_reverse_iterator; + typedef reverse_bidirectional_iterator + reverse_iterator; +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +protected: +#ifdef __STL_HAS_NAMESPACES + using _Base::_M_node; + using _Base::_M_put_node; + using _Base::_M_get_node; +#endif /* __STL_HAS_NAMESPACES */ + +protected: + _Node* _M_create_node(const _Tp& __x) + { + _Node* __p = _M_get_node(); + __STL_TRY { + construct(&__p->_M_data, __x); + } + __STL_UNWIND(_M_put_node(__p)); + return __p; + } + + _Node* _M_create_node() + { + _Node* __p = _M_get_node(); + __STL_TRY { + construct(&__p->_M_data); + } + __STL_UNWIND(_M_put_node(__p)); + return __p; + } + +public: + explicit list(const allocator_type& __a = allocator_type()) : _Base(__a) {} + + iterator begin() { return (_Node*)(_M_node->_M_next); } + const_iterator begin() const { return (_Node*)(_M_node->_M_next); } + + iterator end() { return _M_node; } + const_iterator end() const { return _M_node; } + + reverse_iterator rbegin() + { return reverse_iterator(end()); } + const_reverse_iterator rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator rend() + { return reverse_iterator(begin()); } + const_reverse_iterator rend() const + { return const_reverse_iterator(begin()); } + + bool empty() const { return _M_node->_M_next == _M_node; } + size_type size() const { + size_type __result = 0; + distance(begin(), end(), __result); + return __result; + } + size_type max_size() const { return size_type(-1); } + + reference front() { return *begin(); } + const_reference front() const { return *begin(); } + reference back() { return *(--end()); } + const_reference back() const { return *(--end()); } + + void swap(list<_Tp, _Alloc>& __x) { __STD::swap(_M_node, __x._M_node); } + + iterator insert(iterator __position, const _Tp& __x) { + _Node* __tmp = _M_create_node(__x); + __tmp->_M_next = __position._M_node; + __tmp->_M_prev = __position._M_node->_M_prev; + ((_Node*) (__position._M_node->_M_prev))->_M_next = __tmp; + __position._M_node->_M_prev = __tmp; + return __tmp; + } + iterator insert(iterator __position) { return insert(__position, _Tp()); } +#ifdef __STL_MEMBER_TEMPLATES + // Check whether it's an integral type. If so, it's not an iterator. + + template + void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, + __true_type) { + insert(__pos, (size_type) __n, (_Tp) __x); + } + + template + void _M_insert_dispatch(iterator __pos, + _InputIterator __first, _InputIterator __last, + __false_type); + + template + void insert(iterator __pos, _InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_insert_dispatch(__pos, __first, __last, _Integral()); + } + +#else /* __STL_MEMBER_TEMPLATES */ + void insert(iterator __position, const _Tp* __first, const _Tp* __last); + void insert(iterator __position, + const_iterator __first, const_iterator __last); +#endif /* __STL_MEMBER_TEMPLATES */ + void insert(iterator __pos, size_type __n, const _Tp& __x); + + void push_front(const _Tp& __x) { insert(begin(), __x); } + void push_front() {insert(begin());} + void push_back(const _Tp& __x) { insert(end(), __x); } + void push_back() {insert(end());} + + iterator erase(iterator __position) { + _Node* __next_node = (_Node*) (__position._M_node->_M_next); + _Node* __prev_node = (_Node*) (__position._M_node->_M_prev); + __prev_node->_M_next = __next_node; + __next_node->_M_prev = __prev_node; + destroy(&__position._M_node->_M_data); + _M_put_node(__position._M_node); + return iterator(__next_node); + } + iterator erase(iterator __first, iterator __last); + void clear() { _Base::clear(); } + + void resize(size_type __new_size, const _Tp& __x); + void resize(size_type __new_size) { resize(__new_size, _Tp()); } + + void pop_front() { erase(begin()); } + void pop_back() { + iterator __tmp = end(); + erase(--__tmp); + } + list(size_type __n, const _Tp& __value, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { insert(begin(), __n, __value); } + explicit list(size_type __n) + : _Base(allocator_type()) + { insert(begin(), __n, _Tp()); } + +#ifdef __STL_MEMBER_TEMPLATES + + // We don't need any dispatching tricks here, because insert does all of + // that anyway. + template + list(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { insert(begin(), __first, __last); } + +#else /* __STL_MEMBER_TEMPLATES */ + + list(const _Tp* __first, const _Tp* __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { insert(begin(), __first, __last); } + list(const_iterator __first, const_iterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { insert(begin(), __first, __last); } + +#endif /* __STL_MEMBER_TEMPLATES */ + list(const list<_Tp, _Alloc>& __x) : _Base(__x.get_allocator()) + { insert(begin(), __x.begin(), __x.end()); } + + ~list() { } + + list<_Tp, _Alloc>& operator=(const list<_Tp, _Alloc>& __x); + +public: + // assign(), a generalized assignment member function. Two + // versions: one that takes a count, and one that takes a range. + // The range version is a member template, so we dispatch on whether + // or not the type is an integer. + + void assign(size_type __n, const _Tp& __val); + +#ifdef __STL_MEMBER_TEMPLATES + + template + void assign(_InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } + + template + void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { assign((size_type) __n, (_Tp) __val); } + + template + void _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type); + +#endif /* __STL_MEMBER_TEMPLATES */ + +protected: + void transfer(iterator __position, iterator __first, iterator __last) { + if (__position != __last) { + // Remove [first, last) from its old position. + ((_Node*) (__last._M_node->_M_prev))->_M_next = __position._M_node; + ((_Node*) (__first._M_node->_M_prev))->_M_next = __last._M_node; + ((_Node*) (__position._M_node->_M_prev))->_M_next = __first._M_node; + + // Splice [first, last) into its new position. + _Node* __tmp = (_Node*) (__position._M_node->_M_prev); + __position._M_node->_M_prev = __last._M_node->_M_prev; + __last._M_node->_M_prev = __first._M_node->_M_prev; + __first._M_node->_M_prev = __tmp; + } + } + +public: + void splice(iterator __position, list& __x) { + if (!__x.empty()) + transfer(__position, __x.begin(), __x.end()); + } + void splice(iterator __position, list&, iterator __i) { + iterator __j = __i; + ++__j; + if (__position == __i || __position == __j) return; + transfer(__position, __i, __j); + } + void splice(iterator __position, list&, iterator __first, iterator __last) { + if (__first != __last) + transfer(__position, __first, __last); + } + void remove(const _Tp& __value); + void unique(); + void merge(list& __x); + void reverse(); + void sort(); + +#ifdef __STL_MEMBER_TEMPLATES + template void remove_if(_Predicate); + template void unique(_BinaryPredicate); + template void merge(list&, _StrictWeakOrdering); + template void sort(_StrictWeakOrdering); +#endif /* __STL_MEMBER_TEMPLATES */ + + friend bool operator== __STL_NULL_TMPL_ARGS ( + const list& __x, const list& __y); +}; + +template +inline bool operator==(const list<_Tp,_Alloc>& __x, + const list<_Tp,_Alloc>& __y) +{ + typedef typename list<_Tp,_Alloc>::_Node _Node; + _Node* __e1 = __x._M_node; + _Node* __e2 = __y._M_node; + _Node* __n1 = (_Node*) __e1->_M_next; + _Node* __n2 = (_Node*) __e2->_M_next; + for ( ; __n1 != __e1 && __n2 != __e2 ; + __n1 = (_Node*) __n1->_M_next, __n2 = (_Node*) __n2->_M_next) + if (__n1->_M_data != __n2->_M_data) + return false; + return __n1 == __e1 && __n2 == __e2; +} + +template +inline bool operator<(const list<_Tp,_Alloc>& __x, + const list<_Tp,_Alloc>& __y) +{ + return lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline void +swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y) +{ + __x.swap(__y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +#ifdef __STL_MEMBER_TEMPLATES + +template template +void +list<_Tp, _Alloc>::_M_insert_dispatch(iterator __position, + _InputIter __first, _InputIter __last, + __false_type) +{ + for ( ; __first != __last; ++__first) + insert(__position, *__first); +} + +#else /* __STL_MEMBER_TEMPLATES */ + +template +void +list<_Tp, _Alloc>::insert(iterator __position, + const _Tp* __first, const _Tp* __last) +{ + for ( ; __first != __last; ++__first) + insert(__position, *__first); +} + +template +void +list<_Tp, _Alloc>::insert(iterator __position, + const_iterator __first, const_iterator __last) +{ + for ( ; __first != __last; ++__first) + insert(__position, *__first); +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +template +void +list<_Tp, _Alloc>::insert(iterator __position, size_type __n, const _Tp& __x) +{ + for ( ; __n > 0; --__n) + insert(__position, __x); +} + +template +list<_Tp,_Alloc>::iterator list<_Tp, _Alloc>::erase(iterator __first, + iterator __last) +{ + while (__first != __last) + erase(__first++); + return __last; +} + +template +void list<_Tp, _Alloc>::resize(size_type __new_size, const _Tp& __x) +{ + iterator __i = begin(); + size_type __len = 0; + for ( ; __i != end() && __len < __new_size; ++__i, ++__len) + ; + if (__len == __new_size) + erase(__i, end()); + else // __i == end() + insert(end(), __new_size - __len, __x); +} + +template +list<_Tp, _Alloc>& list<_Tp, _Alloc>::operator=(const list<_Tp, _Alloc>& __x) +{ + if (this != &__x) { + iterator __first1 = begin(); + iterator __last1 = end(); + const_iterator __first2 = __x.begin(); + const_iterator __last2 = __x.end(); + while (__first1 != __last1 && __first2 != __last2) + *__first1++ = *__first2++; + if (__first2 == __last2) + erase(__first1, __last1); + else + insert(__last1, __first2, __last2); + } + return *this; +} + +template +void list<_Tp, _Alloc>::assign(size_type __n, const _Tp& __val) { + iterator __i = begin(); + for ( ; __i != end() && __n > 0; ++__i, --__n) + *__i = __val; + if (__n > 0) + insert(end(), __n, __val); + else + erase(__i, end()); +} + +#ifdef __STL_MEMBER_TEMPLATES + +template template +void +list<_Tp, _Alloc>::_M_assign_dispatch(_InputIter __first2, _InputIter __last2, + __false_type) +{ + iterator __first1 = begin(); + iterator __last1 = end(); + for ( ; __first1 != __last1 && __first2 != __last2; ++__first1, ++__first2) + *__first1 = *__first2; + if (__first2 == __last2) + erase(__first1, __last1); + else + insert(__last1, __first2, __last2); +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +template +void list<_Tp, _Alloc>::remove(const _Tp& __value) +{ + iterator __first = begin(); + iterator __last = end(); + while (__first != __last) { + iterator __next = __first; + ++__next; + if (*__first == __value) erase(__first); + __first = __next; + } +} + +template +void list<_Tp, _Alloc>::unique() +{ + iterator __first = begin(); + iterator __last = end(); + if (__first == __last) return; + iterator __next = __first; + while (++__next != __last) { + if (*__first == *__next) + erase(__next); + else + __first = __next; + __next = __first; + } +} + +template +void list<_Tp, _Alloc>::merge(list<_Tp, _Alloc>& __x) +{ + iterator __first1 = begin(); + iterator __last1 = end(); + iterator __first2 = __x.begin(); + iterator __last2 = __x.end(); + while (__first1 != __last1 && __first2 != __last2) + if (*__first2 < *__first1) { + iterator __next = __first2; + transfer(__first1, __first2, ++__next); + __first2 = __next; + } + else + ++__first1; + if (__first2 != __last2) transfer(__last1, __first2, __last2); +} + +template +void list<_Tp, _Alloc>::reverse() +{ + // Do nothing if the list has length 0 or 1. + if (_M_node->_M_next != _M_node && + ((_Node*) (_M_node->_M_next))->_M_next != _M_node) { + iterator __first = begin(); + ++__first; + while (__first != end()) { + iterator __old = __first; + ++__first; + transfer(begin(), __old, __first); + } + } +} + +template +void list<_Tp, _Alloc>::sort() +{ + // Do nothing if the list has length 0 or 1. + if (_M_node->_M_next != _M_node && + ((_Node*) (_M_node->_M_next))->_M_next != _M_node) { + list<_Tp, _Alloc> __carry; + list<_Tp, _Alloc> __counter[64]; + int __fill = 0; + while (!empty()) { + __carry.splice(__carry.begin(), *this, begin()); + int __i = 0; + while(__i < __fill && !__counter[__i].empty()) { + __counter[__i].merge(__carry); + __carry.swap(__counter[__i++]); + } + __carry.swap(__counter[__i]); + if (__i == __fill) ++__fill; + } + + for (int __i = 1; __i < __fill; ++__i) + __counter[__i].merge(__counter[__i-1]); + swap(__counter[__fill-1]); + } +} + +#ifdef __STL_MEMBER_TEMPLATES + +template template +void list<_Tp, _Alloc>::remove_if(_Predicate __pred) +{ + iterator __first = begin(); + iterator __last = end(); + while (__first != __last) { + iterator __next = __first; + ++__next; + if (__pred(*__first)) erase(__first); + __first = __next; + } +} + +template template +void list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred) +{ + iterator __first = begin(); + iterator __last = end(); + if (__first == __last) return; + iterator __next = __first; + while (++__next != __last) { + if (__binary_pred(*__first, *__next)) + erase(__next); + else + __first = __next; + __next = __first; + } +} + +template template +void list<_Tp, _Alloc>::merge(list<_Tp, _Alloc>& __x, + _StrictWeakOrdering __comp) +{ + iterator __first1 = begin(); + iterator __last1 = end(); + iterator __first2 = __x.begin(); + iterator __last2 = __x.end(); + while (__first1 != __last1 && __first2 != __last2) + if (__comp(*__first2, *__first1)) { + iterator __next = __first2; + transfer(__first1, __first2, ++__next); + __first2 = __next; + } + else + ++__first1; + if (__first2 != __last2) transfer(__last1, __first2, __last2); +} + +template template +void list<_Tp, _Alloc>::sort(_StrictWeakOrdering __comp) +{ + // Do nothing if the list has length 0 or 1. + if (_M_node->_M_next != _M_node && + ((_Node*) (_M_node->_M_next))->_M_next != _M_node) { + list<_Tp, _Alloc> __carry; + list<_Tp, _Alloc> __counter[64]; + int __fill = 0; + while (!empty()) { + __carry.splice(__carry.begin(), *this, begin()); + int __i = 0; + while(__i < __fill && !__counter[__i].empty()) { + __counter[__i].merge(__carry, __comp); + __carry.swap(__counter[__i++]); + } + __carry.swap(__counter[__i]); + if (__i == __fill) ++__fill; + } + + for (int __i = 1; __i < __fill; ++__i) + __counter[__i].merge(__counter[__i-1], __comp); + swap(__counter[__fill-1]); + } +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#pragma reset woff 1375 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_LIST_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/stl_map.h b/headers/cpp/stl_map.h new file mode 100644 index 0000000000..a702e8023e --- /dev/null +++ b/headers/cpp/stl_map.h @@ -0,0 +1,242 @@ +/* + * + * 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,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. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_MAP_H +#define __SGI_STL_INTERNAL_MAP_H + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1174 +#pragma set woff 1375 +#endif + +#ifndef __STL_LIMITED_DEFAULT_TEMPLATES +template , + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) > +#else +template +#endif +class map { +public: + +// typedefs: + + typedef _Key key_type; + typedef _Tp data_type; + typedef _Tp mapped_type; + typedef pair value_type; + typedef _Compare key_compare; + + class value_compare + : public binary_function { + friend class map<_Key,_Tp,_Compare,_Alloc>; + protected : + _Compare _M_comp; + value_compare(_Compare __c) : _M_comp(__c) {} + public: + bool operator()(const value_type& __x, const value_type& __y) const { + return _M_comp(__x.first, __y.first); + } + }; + +private: + typedef _Rb_tree, key_compare, _Alloc> _Rep_type; + _Rep_type _M_t; // red-black tree representing map +public: + typedef typename _Rep_type::pointer pointer; + typedef typename _Rep_type::const_pointer const_pointer; + typedef typename _Rep_type::reference reference; + typedef typename _Rep_type::const_reference const_reference; + typedef typename _Rep_type::iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + typedef typename _Rep_type::allocator_type allocator_type; + + // allocation/deallocation + + map() : _M_t(_Compare(), allocator_type()) {} + explicit map(const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) {} + +#ifdef __STL_MEMBER_TEMPLATES + template + map(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_unique(__first, __last); } + + template + map(_InputIterator __first, _InputIterator __last, const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); } +#else + map(const value_type* __first, const value_type* __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_unique(__first, __last); } + + map(const value_type* __first, + const value_type* __last, const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); } + + map(const_iterator __first, const_iterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_unique(__first, __last); } + + map(const_iterator __first, const_iterator __last, const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); } + +#endif /* __STL_MEMBER_TEMPLATES */ + + map(const map<_Key,_Tp,_Compare,_Alloc>& __x) : _M_t(__x._M_t) {} + map<_Key,_Tp,_Compare,_Alloc>& + operator=(const map<_Key, _Tp, _Compare, _Alloc>& __x) + { + _M_t = __x._M_t; + return *this; + } + + // accessors: + + key_compare key_comp() const { return _M_t.key_comp(); } + value_compare value_comp() const { return value_compare(_M_t.key_comp()); } + allocator_type get_allocator() const { return _M_t.get_allocator(); } + + iterator begin() { return _M_t.begin(); } + const_iterator begin() const { return _M_t.begin(); } + iterator end() { return _M_t.end(); } + const_iterator end() const { return _M_t.end(); } + reverse_iterator rbegin() { return _M_t.rbegin(); } + const_reverse_iterator rbegin() const { return _M_t.rbegin(); } + reverse_iterator rend() { return _M_t.rend(); } + const_reverse_iterator rend() const { return _M_t.rend(); } + bool empty() const { return _M_t.empty(); } + size_type size() const { return _M_t.size(); } + size_type max_size() const { return _M_t.max_size(); } + _Tp& operator[](const key_type& __k) { + iterator __i = lower_bound(__k); + // __i->first is greater than or equivalent to __k. + if (__i == end() || key_comp()(__k, (*__i).first)) + __i = insert(__i, value_type(__k, _Tp())); + return (*__i).second; + } + void swap(map<_Key,_Tp,_Compare,_Alloc>& __x) { _M_t.swap(__x._M_t); } + + // insert/erase + + pair insert(const value_type& __x) + { return _M_t.insert_unique(__x); } + iterator insert(iterator position, const value_type& __x) + { return _M_t.insert_unique(position, __x); } +#ifdef __STL_MEMBER_TEMPLATES + template + void insert(_InputIterator __first, _InputIterator __last) { + _M_t.insert_unique(__first, __last); + } +#else + void insert(const value_type* __first, const value_type* __last) { + _M_t.insert_unique(__first, __last); + } + void insert(const_iterator __first, const_iterator __last) { + _M_t.insert_unique(__first, __last); + } +#endif /* __STL_MEMBER_TEMPLATES */ + + void erase(iterator __position) { _M_t.erase(__position); } + size_type erase(const key_type& __x) { return _M_t.erase(__x); } + void erase(iterator __first, iterator __last) + { _M_t.erase(__first, __last); } + void clear() { _M_t.clear(); } + + // map operations: + + iterator find(const key_type& __x) { return _M_t.find(__x); } + const_iterator find(const key_type& __x) const { return _M_t.find(__x); } + size_type count(const key_type& __x) const { return _M_t.count(__x); } + iterator lower_bound(const key_type& __x) {return _M_t.lower_bound(__x); } + const_iterator lower_bound(const key_type& __x) const { + return _M_t.lower_bound(__x); + } + iterator upper_bound(const key_type& __x) {return _M_t.upper_bound(__x); } + const_iterator upper_bound(const key_type& __x) const { + return _M_t.upper_bound(__x); + } + + pair equal_range(const key_type& __x) { + return _M_t.equal_range(__x); + } + pair equal_range(const key_type& __x) const { + return _M_t.equal_range(__x); + } + friend bool operator== __STL_NULL_TMPL_ARGS (const map&, const map&); + friend bool operator< __STL_NULL_TMPL_ARGS (const map&, const map&); +}; + +template +inline bool operator==(const map<_Key,_Tp,_Compare,_Alloc>& __x, + const map<_Key,_Tp,_Compare,_Alloc>& __y) { + return __x._M_t == __y._M_t; +} + +template +inline bool operator<(const map<_Key,_Tp,_Compare,_Alloc>& __x, + const map<_Key,_Tp,_Compare,_Alloc>& __y) { + return __x._M_t < __y._M_t; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline void swap(map<_Key,_Tp,_Compare,_Alloc>& __x, + map<_Key,_Tp,_Compare,_Alloc>& __y) { + __x.swap(__y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#pragma reset woff 1375 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_MAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/stl_multimap.h b/headers/cpp/stl_multimap.h new file mode 100644 index 0000000000..b7d3b87e52 --- /dev/null +++ b/headers/cpp/stl_multimap.h @@ -0,0 +1,232 @@ +/* + * + * 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,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. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_MULTIMAP_H +#define __SGI_STL_INTERNAL_MULTIMAP_H + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1174 +#pragma set woff 1375 +#endif + +#ifndef __STL_LIMITED_DEFAULT_TEMPLATES +template , + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) > +#else +template +#endif +class multimap { +public: + +// typedefs: + + typedef _Key key_type; + typedef _Tp data_type; + typedef _Tp mapped_type; + typedef pair value_type; + typedef _Compare key_compare; + + class value_compare : public binary_function { + friend class multimap<_Key,_Tp,_Compare,_Alloc>; + protected: + _Compare _M_comp; + value_compare(_Compare __c) : _M_comp(__c) {} + public: + bool operator()(const value_type& __x, const value_type& __y) const { + return _M_comp(__x.first, __y.first); + } + }; + +private: + typedef _Rb_tree, key_compare, _Alloc> _Rep_type; + _Rep_type _M_t; // red-black tree representing multimap +public: + typedef typename _Rep_type::pointer pointer; + typedef typename _Rep_type::const_pointer const_pointer; + typedef typename _Rep_type::reference reference; + typedef typename _Rep_type::const_reference const_reference; + typedef typename _Rep_type::iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + typedef typename _Rep_type::allocator_type allocator_type; + +// allocation/deallocation + + multimap() : _M_t(_Compare(), allocator_type()) { } + explicit multimap(const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { } + +#ifdef __STL_MEMBER_TEMPLATES + template + multimap(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_equal(__first, __last); } + + template + multimap(_InputIterator __first, _InputIterator __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); } +#else + multimap(const value_type* __first, const value_type* __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_equal(__first, __last); } + multimap(const value_type* __first, const value_type* __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); } + + multimap(const_iterator __first, const_iterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_equal(__first, __last); } + multimap(const_iterator __first, const_iterator __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); } +#endif /* __STL_MEMBER_TEMPLATES */ + + multimap(const multimap<_Key,_Tp,_Compare,_Alloc>& __x) : _M_t(__x._M_t) { } + multimap<_Key,_Tp,_Compare,_Alloc>& + operator=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x) { + _M_t = __x._M_t; + return *this; + } + + // accessors: + + key_compare key_comp() const { return _M_t.key_comp(); } + value_compare value_comp() const { return value_compare(_M_t.key_comp()); } + allocator_type get_allocator() const { return _M_t.get_allocator(); } + + iterator begin() { return _M_t.begin(); } + const_iterator begin() const { return _M_t.begin(); } + iterator end() { return _M_t.end(); } + const_iterator end() const { return _M_t.end(); } + reverse_iterator rbegin() { return _M_t.rbegin(); } + const_reverse_iterator rbegin() const { return _M_t.rbegin(); } + reverse_iterator rend() { return _M_t.rend(); } + const_reverse_iterator rend() const { return _M_t.rend(); } + bool empty() const { return _M_t.empty(); } + size_type size() const { return _M_t.size(); } + size_type max_size() const { return _M_t.max_size(); } + void swap(multimap<_Key,_Tp,_Compare,_Alloc>& __x) { _M_t.swap(__x._M_t); } + + // insert/erase + + iterator insert(const value_type& __x) { return _M_t.insert_equal(__x); } + iterator insert(iterator __position, const value_type& __x) { + return _M_t.insert_equal(__position, __x); + } +#ifdef __STL_MEMBER_TEMPLATES + template + void insert(_InputIterator __first, _InputIterator __last) { + _M_t.insert_equal(__first, __last); + } +#else + void insert(const value_type* __first, const value_type* __last) { + _M_t.insert_equal(__first, __last); + } + void insert(const_iterator __first, const_iterator __last) { + _M_t.insert_equal(__first, __last); + } +#endif /* __STL_MEMBER_TEMPLATES */ + void erase(iterator __position) { _M_t.erase(__position); } + size_type erase(const key_type& __x) { return _M_t.erase(__x); } + void erase(iterator __first, iterator __last) + { _M_t.erase(__first, __last); } + void clear() { _M_t.clear(); } + + // multimap operations: + + iterator find(const key_type& __x) { return _M_t.find(__x); } + const_iterator find(const key_type& __x) const { return _M_t.find(__x); } + size_type count(const key_type& __x) const { return _M_t.count(__x); } + iterator lower_bound(const key_type& __x) {return _M_t.lower_bound(__x); } + const_iterator lower_bound(const key_type& __x) const { + return _M_t.lower_bound(__x); + } + iterator upper_bound(const key_type& __x) {return _M_t.upper_bound(__x); } + const_iterator upper_bound(const key_type& __x) const { + return _M_t.upper_bound(__x); + } + pair equal_range(const key_type& __x) { + return _M_t.equal_range(__x); + } + pair equal_range(const key_type& __x) const { + return _M_t.equal_range(__x); + } + friend bool operator== __STL_NULL_TMPL_ARGS (const multimap&, + const multimap&); + friend bool operator< __STL_NULL_TMPL_ARGS (const multimap&, + const multimap&); +}; + +template +inline bool operator==(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y) { + return __x._M_t == __y._M_t; +} + +template +inline bool operator<(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y) { + return __x._M_t < __y._M_t; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline void swap(multimap<_Key,_Tp,_Compare,_Alloc>& __x, + multimap<_Key,_Tp,_Compare,_Alloc>& __y) { + __x.swap(__y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#pragma reset woff 1375 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_MULTIMAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/stl_multiset.h b/headers/cpp/stl_multiset.h new file mode 100644 index 0000000000..7378e43f8b --- /dev/null +++ b/headers/cpp/stl_multiset.h @@ -0,0 +1,224 @@ +/* + * + * 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. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_MULTISET_H +#define __SGI_STL_INTERNAL_MULTISET_H + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1174 +#pragma set woff 1375 +#endif + +#ifndef __STL_LIMITED_DEFAULT_TEMPLATES +template , + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Key) > +#else +template +#endif +class multiset { +public: + // typedefs: + + typedef _Key key_type; + typedef _Key value_type; + typedef _Compare key_compare; + typedef _Compare value_compare; +private: + typedef _Rb_tree, key_compare, _Alloc> _Rep_type; + _Rep_type _M_t; // red-black tree representing multiset +public: + typedef typename _Rep_type::const_pointer pointer; + typedef typename _Rep_type::const_pointer const_pointer; + typedef typename _Rep_type::const_reference reference; + typedef typename _Rep_type::const_reference const_reference; + typedef typename _Rep_type::const_iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::const_reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + typedef typename _Rep_type::allocator_type allocator_type; + + // allocation/deallocation + + multiset() : _M_t(_Compare(), allocator_type()) {} + explicit multiset(const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) {} + +#ifdef __STL_MEMBER_TEMPLATES + + template + multiset(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_equal(__first, __last); } + + template + multiset(_InputIterator __first, _InputIterator __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); } + +#else + + multiset(const value_type* __first, const value_type* __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_equal(__first, __last); } + + multiset(const value_type* __first, const value_type* __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); } + + multiset(const_iterator __first, const_iterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_equal(__first, __last); } + + multiset(const_iterator __first, const_iterator __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); } + +#endif /* __STL_MEMBER_TEMPLATES */ + + multiset(const multiset<_Key,_Compare,_Alloc>& __x) : _M_t(__x._M_t) {} + multiset<_Key,_Compare,_Alloc>& + operator=(const multiset<_Key,_Compare,_Alloc>& __x) { + _M_t = __x._M_t; + return *this; + } + + // accessors: + + key_compare key_comp() const { return _M_t.key_comp(); } + value_compare value_comp() const { return _M_t.key_comp(); } + allocator_type get_allocator() const { return _M_t.get_allocator(); } + + iterator begin() const { return _M_t.begin(); } + iterator end() const { return _M_t.end(); } + reverse_iterator rbegin() const { return _M_t.rbegin(); } + reverse_iterator rend() const { return _M_t.rend(); } + bool empty() const { return _M_t.empty(); } + size_type size() const { return _M_t.size(); } + size_type max_size() const { return _M_t.max_size(); } + void swap(multiset<_Key,_Compare,_Alloc>& __x) { _M_t.swap(__x._M_t); } + + // insert/erase + iterator insert(const value_type& __x) { + return _M_t.insert_equal(__x); + } + iterator insert(iterator __position, const value_type& __x) { + typedef typename _Rep_type::iterator _Rep_iterator; + return _M_t.insert_equal((_Rep_iterator&)__position, __x); + } + +#ifdef __STL_MEMBER_TEMPLATES + template + void insert(_InputIterator __first, _InputIterator __last) { + _M_t.insert_equal(__first, __last); + } +#else + void insert(const value_type* __first, const value_type* __last) { + _M_t.insert_equal(__first, __last); + } + void insert(const_iterator __first, const_iterator __last) { + _M_t.insert_equal(__first, __last); + } +#endif /* __STL_MEMBER_TEMPLATES */ + void erase(iterator __position) { + typedef typename _Rep_type::iterator _Rep_iterator; + _M_t.erase((_Rep_iterator&)__position); + } + size_type erase(const key_type& __x) { + return _M_t.erase(__x); + } + void erase(iterator __first, iterator __last) { + typedef typename _Rep_type::iterator _Rep_iterator; + _M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last); + } + void clear() { _M_t.clear(); } + + // multiset operations: + + iterator find(const key_type& __x) const { return _M_t.find(__x); } + size_type count(const key_type& __x) const { return _M_t.count(__x); } + iterator lower_bound(const key_type& __x) const { + return _M_t.lower_bound(__x); + } + iterator upper_bound(const key_type& __x) const { + return _M_t.upper_bound(__x); + } + pair equal_range(const key_type& __x) const { + return _M_t.equal_range(__x); + } + friend bool operator== __STL_NULL_TMPL_ARGS (const multiset&, + const multiset&); + friend bool operator< __STL_NULL_TMPL_ARGS (const multiset&, + const multiset&); +}; + +template +inline bool operator==(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y) { + return __x._M_t == __y._M_t; +} + +template +inline bool operator<(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y) { + return __x._M_t < __y._M_t; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline void swap(multiset<_Key,_Compare,_Alloc>& __x, + multiset<_Key,_Compare,_Alloc>& __y) { + __x.swap(__y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#pragma reset woff 1375 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_MULTISET_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/stl_numeric.h b/headers/cpp/stl_numeric.h new file mode 100644 index 0000000000..392515a3d8 --- /dev/null +++ b/headers/cpp/stl_numeric.h @@ -0,0 +1,239 @@ +/* + * + * 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,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. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + + +#ifndef __SGI_STL_INTERNAL_NUMERIC_H +#define __SGI_STL_INTERNAL_NUMERIC_H + +__STL_BEGIN_NAMESPACE + +template +_Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init) +{ + for ( ; __first != __last; ++__first) + __init = __init + *__first; + return __init; +} + +template +_Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init, + _BinaryOperation __binary_op) +{ + for ( ; __first != __last; ++__first) + __init = __binary_op(__init, *__first); + return __init; +} + +template +_Tp inner_product(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _Tp __init) +{ + for ( ; __first1 != __last1; ++__first1, ++__first2) + __init = __init + (*__first1 * *__first2); + return __init; +} + +template +_Tp inner_product(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _Tp __init, + _BinaryOperation1 __binary_op1, + _BinaryOperation2 __binary_op2) +{ + for ( ; __first1 != __last1; ++__first1, ++__first2) + __init = __binary_op1(__init, __binary_op2(*__first1, *__first2)); + return __init; +} + +template +_OutputIterator +__partial_sum(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _Tp*) +{ + _Tp __value = *__first; + while (++__first != __last) { + __value = __value + *__first; + *++__result = __value; + } + return ++__result; +} + +template +_OutputIterator +partial_sum(_InputIterator __first, _InputIterator __last, + _OutputIterator __result) +{ + if (__first == __last) return __result; + *__result = *__first; + return __partial_sum(__first, __last, __result, __VALUE_TYPE(__first)); +} + +template +_OutputIterator +__partial_sum(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _Tp*, _BinaryOperation __binary_op) +{ + _Tp __value = *__first; + while (++__first != __last) { + __value = __binary_op(__value, *__first); + *++__result = __value; + } + return ++__result; +} + +template +_OutputIterator +partial_sum(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _BinaryOperation __binary_op) +{ + if (__first == __last) return __result; + *__result = *__first; + return __partial_sum(__first, __last, __result, __VALUE_TYPE(__first), + __binary_op); +} + +template +_OutputIterator +__adjacent_difference(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _Tp*) +{ + _Tp __value = *__first; + while (++__first != __last) { + _Tp __tmp = *__first; + *++__result = __tmp - __value; + __value = __tmp; + } + return ++__result; +} + +template +_OutputIterator +adjacent_difference(_InputIterator __first, + _InputIterator __last, _OutputIterator __result) +{ + if (__first == __last) return __result; + *__result = *__first; + return __adjacent_difference(__first, __last, __result, + __VALUE_TYPE(__first)); +} + +template +_OutputIterator +__adjacent_difference(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _Tp*, + _BinaryOperation __binary_op) { + _Tp __value = *__first; + while (++__first != __last) { + _Tp __tmp = *__first; + *++__result = __binary_op(__tmp, __value); + __value = __tmp; + } + return ++__result; +} + +template +_OutputIterator +adjacent_difference(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _BinaryOperation __binary_op) +{ + if (__first == __last) return __result; + *__result = *__first; + return __adjacent_difference(__first, __last, __result, + __VALUE_TYPE(__first), + __binary_op); +} + +// Returns __x ** __n, where __n >= 0. _Note that "multiplication" +// is required to be associative, but not necessarily commutative. + + +template +_Tp __power(_Tp __x, _Integer __n, _MonoidOperation __oper) +{ + if (__n == 0) + return identity_element(__oper); + else { + while ((__n & 1) == 0) { + __n >>= 1; + __x = __oper(__x, __x); + } + + _Tp __result = __x; + __n >>= 1; + while (__n != 0) { + __x = __oper(__x, __x); + if ((__n & 1) != 0) + __result = __oper(__result, __x); + __n >>= 1; + } + return __result; + } +} + +template +inline _Tp __power(_Tp __x, _Integer __n) +{ + return __power(__x, __n, multiplies<_Tp>()); +} + +// Alias for the internal name __power. Note that power is an extension, +// not part of the C++ standard. + +template +inline _Tp power(_Tp __x, _Integer __n, _MonoidOperation __oper) +{ + return __power(__x, __n, __oper); +} + +template +inline _Tp power(_Tp __x, _Integer __n) +{ + return __power(__x, __n); +} + +// iota is not part of the C++ standard. It is an extension. + +template +void +iota(_ForwardIterator __first, _ForwardIterator __last, _Tp __value) +{ + while (__first != __last) + *__first++ = __value++; +} + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_NUMERIC_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/stl_pair.h b/headers/cpp/stl_pair.h new file mode 100644 index 0000000000..3aa290b59e --- /dev/null +++ b/headers/cpp/stl_pair.h @@ -0,0 +1,77 @@ +/* + * + * 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,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. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_PAIR_H +#define __SGI_STL_INTERNAL_PAIR_H + +__STL_BEGIN_NAMESPACE + +template +struct pair { + typedef _T1 first_type; + typedef _T2 second_type; + + _T1 first; + _T2 second; + pair() : first(_T1()), second(_T2()) {} + pair(const _T1& __a, const _T2& __b) : first(__a), second(__b) {} + +#ifdef __STL_MEMBER_TEMPLATES + template + pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) {} +#endif +}; + +template +inline bool operator==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) +{ + return __x.first == __y.first && __x.second == __y.second; +} + +template +inline bool operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) +{ + return __x.first < __y.first || + (!(__y.first < __x.first) && __x.second < __y.second); +} + +template +inline pair<_T1, _T2> make_pair(const _T1& __x, const _T2& __y) +{ + return pair<_T1, _T2>(__x, __y); +} + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_PAIR_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/stl_queue.h b/headers/cpp/stl_queue.h new file mode 100644 index 0000000000..c1e2b69844 --- /dev/null +++ b/headers/cpp/stl_queue.h @@ -0,0 +1,202 @@ +/* + * + * 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,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. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_QUEUE_H +#define __SGI_STL_INTERNAL_QUEUE_H + +__STL_BEGIN_NAMESPACE + +#ifndef __STL_LIMITED_DEFAULT_TEMPLATES +template > +#else +template +#endif +class queue { + friend bool operator== __STL_NULL_TMPL_ARGS (const queue&, const queue&); + friend bool operator< __STL_NULL_TMPL_ARGS (const queue&, const queue&); +public: + typedef typename _Sequence::value_type value_type; + typedef typename _Sequence::size_type size_type; + typedef _Sequence container_type; + + typedef typename _Sequence::reference reference; + typedef typename _Sequence::const_reference const_reference; +protected: + _Sequence c; +public: + queue() : c() {} + explicit queue(const _Sequence& __c) : c(__c) {} + + bool empty() const { return c.empty(); } + size_type size() const { return c.size(); } + reference front() { return c.front(); } + const_reference front() const { return c.front(); } + reference back() { return c.back(); } + const_reference back() const { return c.back(); } + void push(const value_type& __x) { c.push_back(__x); } + void pop() { c.pop_front(); } +}; + +template +bool +operator==(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) +{ + return __x.c == __y.c; +} + +template +bool +operator<(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) +{ + return __x.c < __y.c; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +bool +operator!=(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) +{ + return !(__x == __y); +} + +template +bool +operator>(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) +{ + return __y < __x; +} + +template +bool +operator<=(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) +{ + return !(__y < __x); +} + +template +bool +operator>=(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) +{ + return !(__x < __y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +#ifndef __STL_LIMITED_DEFAULT_TEMPLATES +template , + class _Compare = less > +#else +template +#endif +class priority_queue { +public: + typedef typename _Sequence::value_type value_type; + typedef typename _Sequence::size_type size_type; + typedef _Sequence container_type; + + typedef typename _Sequence::reference reference; + typedef typename _Sequence::const_reference const_reference; +protected: + _Sequence c; + _Compare comp; +public: + priority_queue() : c() {} + explicit priority_queue(const _Compare& __x) : c(), comp(__x) {} + priority_queue(const _Compare& __x, const _Sequence& __s) + : c(__s), comp(__x) + { make_heap(c.begin(), c.end(), comp); } + +#ifdef __STL_MEMBER_TEMPLATES + template + priority_queue(_InputIterator __first, _InputIterator __last) + : c(__first, __last) { make_heap(c.begin(), c.end(), comp); } + + template + priority_queue(_InputIterator __first, + _InputIterator __last, const _Compare& __x) + : c(__first, __last), comp(__x) + { make_heap(c.begin(), c.end(), comp); } + + template + priority_queue(_InputIterator __first, _InputIterator __last, + const _Compare& __x, const _Sequence& __s) + : c(__s), comp(__x) + { + c.insert(c.end(), __first, __last); + make_heap(c.begin(), c.end(), comp); + } + +#else /* __STL_MEMBER_TEMPLATES */ + priority_queue(const value_type* __first, const value_type* __last) + : c(__first, __last) { make_heap(c.begin(), c.end(), comp); } + + priority_queue(const value_type* __first, const value_type* __last, + const _Compare& __x) + : c(__first, __last), comp(__x) + { make_heap(c.begin(), c.end(), comp); } + + priority_queue(const value_type* __first, const value_type* __last, + const _Compare& __x, const _Sequence& __c) + : c(__c), comp(__x) + { + c.insert(c.end(), __first, __last); + make_heap(c.begin(), c.end(), comp); + } +#endif /* __STL_MEMBER_TEMPLATES */ + + bool empty() const { return c.empty(); } + size_type size() const { return c.size(); } + const_reference top() const { return c.front(); } + void push(const value_type& __x) { + __STL_TRY { + c.push_back(__x); + push_heap(c.begin(), c.end(), comp); + } + __STL_UNWIND(c.clear()); + } + void pop() { + __STL_TRY { + pop_heap(c.begin(), c.end(), comp); + c.pop_back(); + } + __STL_UNWIND(c.clear()); + } +}; + +// no equality is provided + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_QUEUE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/stl_raw_storage_iter.h b/headers/cpp/stl_raw_storage_iter.h new file mode 100644 index 0000000000..6f3951cb8a --- /dev/null +++ b/headers/cpp/stl_raw_storage_iter.h @@ -0,0 +1,81 @@ +/* + * + * 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. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_RAW_STORAGE_ITERATOR_H +#define __SGI_STL_INTERNAL_RAW_STORAGE_ITERATOR_H + +__STL_BEGIN_NAMESPACE + +template +class raw_storage_iterator { +protected: + _ForwardIterator _M_iter; +public: + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + explicit raw_storage_iterator(_ForwardIterator __x) : _M_iter(__x) {} + raw_storage_iterator& operator*() { return *this; } + raw_storage_iterator& operator=(const _Tp& __element) { + construct(&*_M_iter, __element); + return *this; + } + raw_storage_iterator<_ForwardIterator, _Tp>& operator++() { + ++_M_iter; + return *this; + } + raw_storage_iterator<_ForwardIterator, _Tp> operator++(int) { + raw_storage_iterator<_ForwardIterator, _Tp> __tmp = *this; + ++_M_iter; + return __tmp; + } +}; + +#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +inline output_iterator_tag +iterator_category(const raw_storage_iterator<_ForwardIterator, _Tp>&) +{ + return output_iterator_tag(); +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_RAW_STORAGE_ITERATOR_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/stl_relops.h b/headers/cpp/stl_relops.h new file mode 100644 index 0000000000..16cad1b84e --- /dev/null +++ b/headers/cpp/stl_relops.h @@ -0,0 +1,62 @@ +/* + * + * 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,1997 + * Silicon Graphics + * + * 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. + * + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_RELOPS +#define __SGI_STL_INTERNAL_RELOPS + +__STL_BEGIN_RELOPS_NAMESPACE + +template +inline bool operator!=(const _Tp& __x, const _Tp& __y) { + return !(__x == __y); +} + +template +inline bool operator>(const _Tp& __x, const _Tp& __y) { + return __y < __x; +} + +template +inline bool operator<=(const _Tp& __x, const _Tp& __y) { + return !(__y < __x); +} + +template +inline bool operator>=(const _Tp& __x, const _Tp& __y) { + return !(__x < __y); +} + +__STL_END_RELOPS_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_RELOPS */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/stl_rope.h b/headers/cpp/stl_rope.h new file mode 100644 index 0000000000..fa1e848c06 --- /dev/null +++ b/headers/cpp/stl_rope.h @@ -0,0 +1,2541 @@ +/* + * 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. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +// rope<_CharT,_Alloc> is a sequence of _CharT. +// Ropes appear to be mutable, but update operations +// really copy enough of the data structure to leave the original +// valid. Thus ropes can be logically copied by just copying +// a pointer value. + +#ifndef __SGI_STL_INTERNAL_ROPE_H +# define __SGI_STL_INTERNAL_ROPE_H + +# ifdef __GC +# define __GC_CONST const +# else +# define __GC_CONST // constant except for deallocation +# endif +# ifdef __STL_SGI_THREADS +# include +# endif + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1174 +#endif + +// The _S_eos function is used for those functions that +// convert to/from C-like strings to detect the end of the string. + +// The end-of-C-string character. +// This is what the draft standard says it should be. +template +inline _CharT _S_eos(_CharT*) { return _CharT(); } + +// Test for basic character types. +// For basic character types leaves having a trailing eos. +template +inline bool _S_is_basic_char_type(_CharT*) { return false; } +template +inline bool _S_is_one_byte_char_type(_CharT*) { return false; } + +inline bool _S_is_basic_char_type(char*) { return true; } +inline bool _S_is_one_byte_char_type(char*) { return true; } +inline bool _S_is_basic_char_type(wchar_t*) { return true; } + +// Store an eos iff _CharT is a basic character type. +// Do not reference _S_eos if it isn't. +template +inline void _S_cond_store_eos(_CharT&) {} + +inline void _S_cond_store_eos(char& __c) { __c = 0; } +inline void _S_cond_store_eos(wchar_t& __c) { __c = 0; } + +// char_producers are logically functions that generate a section of +// a string. These can be convereted to ropes. The resulting rope +// invokes the char_producer on demand. This allows, for example, +// files to be viewed as ropes without reading the entire file. +template +class char_producer { + public: + virtual ~char_producer() {}; + virtual void operator()(size_t __start_pos, size_t __len, + _CharT* __buffer) = 0; + // Buffer should really be an arbitrary output iterator. + // That way we could flatten directly into an ostream, etc. + // This is thoroughly impossible, since iterator types don't + // have runtime descriptions. +}; + +// Sequence buffers: +// +// Sequence must provide an append operation that appends an +// array to the sequence. Sequence buffers are useful only if +// appending an entire array is cheaper than appending element by element. +// This is true for many string representations. +// This should perhaps inherit from ostream +// and be implemented correspondingly, so that they can be used +// for formatted. For the sake of portability, we don't do this yet. +// +// For now, sequence buffers behave as output iterators. But they also +// behave a little like basic_ostringstream and a +// little like containers. + +template +// The 3rd parameter works around a common compiler bug. +class sequence_buffer : public output_iterator { + public: +# ifndef __TYPEDEF_WORKAROUND + typedef typename _Sequence::value_type value_type; +# else + typedef _V value_type; +# endif + protected: + _Sequence* _M_prefix; + value_type _M_buffer[_Buf_sz]; + size_t _M_buf_count; + public: + void flush() { + _M_prefix->append(_M_buffer, _M_buffer + _M_buf_count); + _M_buf_count = 0; + } + ~sequence_buffer() { flush(); } + sequence_buffer() : _M_prefix(0), _M_buf_count(0) {} + sequence_buffer(const sequence_buffer& __x) { + _M_prefix = __x._M_prefix; + _M_buf_count = __x._M_buf_count; + copy(__x._M_buffer, __x._M_buffer + __x._M_buf_count, _M_buffer); + } + sequence_buffer(sequence_buffer& __x) { + __x.flush(); + _M_prefix = __x._M_prefix; + _M_buf_count = 0; + } + sequence_buffer(_Sequence& __s) : _M_prefix(&__s), _M_buf_count(0) {} + sequence_buffer& operator= (sequence_buffer& __x) { + __x.flush(); + _M_prefix = __x._M_prefix; + _M_buf_count = 0; + return *this; + } + sequence_buffer& operator= (const sequence_buffer& __x) { + _M_prefix = __x._M_prefix; + _M_buf_count = __x._M_buf_count; + copy(__x._M_buffer, __x._M_buffer + __x._M_buf_count, _M_buffer); + return *this; + } + void push_back(value_type __x) + { + if (_M_buf_count < _Buf_sz) { + _M_buffer[_M_buf_count] = __x; + ++_M_buf_count; + } else { + flush(); + _M_buffer[0] = __x; + _M_buf_count = 1; + } + } + void append(value_type* __s, size_t __len) + { + if (__len + _M_buf_count <= _Buf_sz) { + size_t __i = _M_buf_count; + size_t __j = 0; + for (; __j < __len; __i++, __j++) { + _M_buffer[__i] = __s[__j]; + } + _M_buf_count += __len; + } else if (0 == _M_buf_count) { + _M_prefix->append(__s, __s + __len); + } else { + flush(); + append(__s, __len); + } + } + sequence_buffer& write(value_type* __s, size_t __len) + { + append(__s, __len); + return *this; + } + sequence_buffer& put(value_type __x) + { + push_back(__x); + return *this; + } + sequence_buffer& operator=(const value_type& __rhs) + { + push_back(__rhs); + return *this; + } + sequence_buffer& operator*() { return *this; } + sequence_buffer& operator++() { return *this; } + sequence_buffer& operator++(int) { return *this; } +}; + +// The following should be treated as private, at least for now. +template +class _Rope_char_consumer { + public: + // If we had member templates, these should not be virtual. + // For now we need to use run-time parametrization where + // compile-time would do. _Hence this should all be private + // for now. + // The symmetry with char_producer is accidental and temporary. + virtual ~_Rope_char_consumer() {}; + virtual bool operator()(const _CharT* __buffer, size_t __len) = 0; +}; + +// +// What follows should really be local to rope. Unfortunately, +// that doesn't work, since it makes it impossible to define generic +// equality on rope iterators. According to the draft standard, the +// template parameters for such an equality operator cannot be inferred +// from the occurence of a member class as a parameter. +// (SGI compilers in fact allow this, but the __result wouldn't be +// portable.) +// Similarly, some of the static member functions are member functions +// only to avoid polluting the global namespace, and to circumvent +// restrictions on type inference for template functions. +// + +template class rope; +template struct _Rope_RopeConcatenation; +template struct _Rope_RopeLeaf; +template struct _Rope_RopeFunction; +template struct _Rope_RopeSubstring; +template class _Rope_iterator; +template class _Rope_const_iterator; +template class _Rope_char_ref_proxy; +template class _Rope_char_ptr_proxy; + +// +// The internal data structure for representing a rope. This is +// private to the implementation. A rope is really just a pointer +// to one of these. +// +// A few basic functions for manipulating this data structure +// are members of _RopeRep. Most of the more complex algorithms +// are implemented as rope members. +// +// Some of the static member functions of _RopeRep have identically +// named functions in rope that simply invoke the _RopeRep versions. +// +// A macro to introduce various allocation and deallocation functions +// These need to be defined differently depending on whether or not +// we are using standard conforming allocators, and whether the allocator +// instances have real state. Thus this macro is invoked repeatedly +// with different definitions of __ROPE_DEFINE_ALLOC. +// __ROPE_DEFINE_ALLOC(type,name) defines +// type * name_allocate(size_t) and +// void name_deallocate(tipe *, size_t) +// Both functions may or may not be static. + +#define __ROPE_DEFINE_ALLOCS(__a) \ + __ROPE_DEFINE_ALLOC(_CharT,_Data) /* character data */ \ + typedef _Rope_RopeConcatenation<_CharT,__a> __C; \ + __ROPE_DEFINE_ALLOC(__C,_C) \ + typedef _Rope_RopeLeaf<_CharT,__a> __L; \ + __ROPE_DEFINE_ALLOC(__L,_L) \ + typedef _Rope_RopeFunction<_CharT,__a> __F; \ + __ROPE_DEFINE_ALLOC(__F,_F) \ + typedef _Rope_RopeSubstring<_CharT,__a> __S; \ + __ROPE_DEFINE_ALLOC(__S,_S) + +// Internal rope nodes potentially store a copy of the allocator +// instance used to allocate them. This is mostly redundant. +// But the alternative would be to pass allocator instances around +// in some form to nearly all internal functions, since any pointer +// assignment may result in a zero reference count and thus require +// deallocation. +// The _Rope_rep_base class encapsulates +// the differences between SGI-style allocators and standard-conforming +// allocators. + +#ifdef __STL_USE_STD_ALLOCATORS + +#define __STATIC_IF_SGI_ALLOC /* not static */ + +// Base class for ordinary allocators. +template +class _Rope_rep_alloc_base { +public: + typedef typename _Alloc_traits<_CharT,_Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return _M_data_allocator; } + _Rope_rep_alloc_base(size_t __size, const allocator_type& __a) + : _M_size(__size), _M_data_allocator(__a) {} + size_t _M_size; // This is here only to avoid wasting space + // for an otherwise empty base class. + + +protected: + allocator_type _M_data_allocator; + +# define __ROPE_DEFINE_ALLOC(_Tp, __name) \ + typedef typename \ + _Alloc_traits<_Tp,_Allocator>::allocator_type __name##Allocator; \ + /*static*/ _Tp * __name##_allocate(size_t __n) \ + { return __name##Allocator(_M_data_allocator).allocate(__n); } \ + void __name##_deallocate(_Tp* __p, size_t __n) \ + { __name##Allocator(_M_data_allocator).deallocate(__p, __n); } + __ROPE_DEFINE_ALLOCS(_Allocator); +# undef __ROPE_DEFINE_ALLOC +}; + +// Specialization for allocators that have the property that we don't +// actually have to store an allocator object. +template +class _Rope_rep_alloc_base<_CharT,_Allocator,true> { +public: + typedef typename _Alloc_traits<_CharT,_Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + _Rope_rep_alloc_base(size_t __size, const allocator_type&) + : _M_size(__size) {} + size_t _M_size; + +protected: + +# define __ROPE_DEFINE_ALLOC(_Tp, __name) \ + typedef typename \ + _Alloc_traits<_Tp,_Allocator>::_Alloc_type __name##Alloc; \ + typedef typename \ + _Alloc_traits<_Tp,_Allocator>::allocator_type __name##Allocator; \ + static _Tp* __name##_allocate(size_t __n) \ + { return __name##Alloc::allocate(__n); } \ + void __name##_deallocate(_Tp *__p, size_t __n) \ + { __name##Alloc::deallocate(__p, __n); } + __ROPE_DEFINE_ALLOCS(_Allocator); +# undef __ROPE_DEFINE_ALLOC +}; + +template +struct _Rope_rep_base + : public _Rope_rep_alloc_base<_CharT,_Alloc, + _Alloc_traits<_CharT,_Alloc>::_S_instanceless> +{ + typedef _Rope_rep_alloc_base<_CharT,_Alloc, + _Alloc_traits<_CharT,_Alloc>::_S_instanceless> + _Base; + typedef typename _Base::allocator_type allocator_type; + _Rope_rep_base(size_t __size, const allocator_type& __a) + : _Base(__size, __a) {} +}; + +#else /* !__STL_USE_STD_ALLOCATORS */ + +#define __STATIC_IF_SGI_ALLOC static + +template +class _Rope_rep_base { +public: + typedef _Alloc allocator_type; + static allocator_type get_allocator() { return allocator_type(); } + _Rope_rep_base(size_t __size, const allocator_type&) : _M_size(__size) {} + size_t _M_size; + +protected: + +# define __ROPE_DEFINE_ALLOC(_Tp, __name) \ + typedef simple_alloc<_Tp, _Alloc> __name##Alloc; \ + static _Tp* __name##_allocate(size_t __n) \ + { return __name##Alloc::allocate(__n); } \ + static void __name##_deallocate(_Tp* __p, size_t __n) \ + { __name##Alloc::deallocate(__p, __n); } + __ROPE_DEFINE_ALLOCS(_Alloc); +# undef __ROPE_DEFINE_ALLOC +}; + +#endif /* __STL_USE_STD_ALLOCATORS */ + + +template +struct _Rope_RopeRep : public _Rope_rep_base<_CharT,_Alloc> { + public: + enum { _S_max_rope_depth = 45 }; + enum _Tag {_S_leaf, _S_concat, _S_substringfn, _S_function}; + _Tag _M_tag:8; + bool _M_is_balanced:8; + unsigned char _M_depth; + __GC_CONST _CharT* _M_c_string; + /* Flattened version of string, if needed. */ + /* typically 0. */ + /* If it's not 0, then the memory is owned */ + /* by this node. */ + /* In the case of a leaf, this may point to */ + /* the same memory as the data field. */ + typedef _Rope_rep_base<_CharT,_Alloc>::allocator_type allocator_type; + _Rope_RopeRep(_Tag __t, int __d, bool __b, size_t __size, + allocator_type __a) + : _Rope_rep_base<_CharT,_Alloc>(__size, __a), + _M_tag(__t), _M_depth(__d), _M_is_balanced(__b), _M_c_string(0) + { +# ifndef __GC + _M_refcount = 1; + _M_init_refcount_lock(); +# endif + } +# ifndef __GC +# if defined(__STL_WIN32THREADS) + long _M_refcount; // InterlockedIncrement wants a long * +# else + size_t _M_refcount; +# endif + // We count references from rope instances + // and references from other rope nodes. We + // do not count const_iterator references. + // Iterator references are counted so that rope modifications + // can be detected after the fact. + // Generally function results are counted, i.__e. + // a pointer returned by a function is included at the + // point at which the pointer is returned. + // The recipient should decrement the count if the + // __result is not needed. + // Generally function arguments are not reflected + // in the reference count. The callee should increment + // the count before saving the argument someplace that + // will outlive the call. +# endif +# ifndef __GC +# ifdef __STL_SGI_THREADS + // Reference counting with multiple threads and no + // hardware or thread package support is pretty awful. + // Mutexes are normally too expensive. + // We'll assume a COMPARE_AND_SWAP(destp, __old, new) + // operation, which might be cheaper. +# if __mips < 3 || !(defined (_ABIN32) || defined(_ABI64)) +# define __add_and_fetch(l,v) add_then_test((unsigned long*)l,v) +# endif + void _M_init_refcount_lock() {} + void _M_incr_refcount () + { + __add_and_fetch(&_M_refcount, 1); + } + size_t _M_decr_refcount () + { + return __add_and_fetch(&_M_refcount, (size_t)(-1)); + } +# elif defined(__STL_WIN32THREADS) + void _M_init_refcount_lock() {} + void _M_incr_refcount () + { + InterlockedIncrement(&_M_refcount); + } + size_t _M_decr_refcount () + { + return InterlockedDecrement(&_M_refcount); + } +# elif defined(__STL_PTHREADS) + // This should be portable, but performance is expected + // to be quite awful. This really needs platform specific + // code. + pthread_mutex_t _M_refcount_lock; + void _M_init_refcount_lock() { + pthread_mutex_init(&_M_refcount_lock, 0); + } + void _M_incr_refcount () + { + pthread_mutex_lock(&_M_refcount_lock); + ++_M_refcount; + pthread_mutex_unlock(&_M_refcount_lock); + } + size_t _M_decr_refcount () + { + size_t __result; + pthread_mutex_lock(&_M_refcount_lock); + __result = --_M_refcount; + pthread_mutex_unlock(&_M_refcount_lock); + return __result; + } +# else + void _M_init_refcount_lock() {} + void _M_incr_refcount () + { + ++_M_refcount; + } + size_t _M_decr_refcount () + { + --_M_refcount; + return _M_refcount; + } +# endif +# else + void _M_incr_refcount () {} +# endif +# ifdef __STL_USE_STD_ALLOCATORS + static void _S_free_string(__GC_CONST _CharT*, size_t __len, + allocator_type __a); +# define __STL_FREE_STRING(__s, __l, __a) _S_free_string(__s, __l, __a); +# else + static void _S_free_string(__GC_CONST _CharT*, size_t __len); +# define __STL_FREE_STRING(__s, __l, __a) _S_free_string(__s, __l); +# endif + // Deallocate data section of a leaf. + // This shouldn't be a member function. + // But its hard to do anything else at the + // moment, because it's templatized w.r.t. + // an allocator. + // Does nothing if __GC is defined. +# ifndef __GC + void _M_free_c_string(); + void _M_free_tree(); + // Deallocate t. Assumes t is not 0. + void _M_unref_nonnil() + { + if (0 == _M_decr_refcount()) _M_free_tree(); + } + void _M_ref_nonnil() + { + _M_incr_refcount(); + } + static void _S_unref(_Rope_RopeRep* __t) + { + if (0 != __t) { + __t->_M_unref_nonnil(); + } + } + static void _S_ref(_Rope_RopeRep* __t) + { + if (0 != __t) __t->_M_incr_refcount(); + } + static void _S_free_if_unref(_Rope_RopeRep* __t) + { + if (0 != __t && 0 == __t->_M_refcount) __t->_M_free_tree(); + } +# else /* __GC */ + void _M_unref_nonnil() {} + void _M_ref_nonnil() {} + static void _S_unref(_Rope_RopeRep*) {} + static void _S_ref(_Rope_RopeRep*) {} + static void _S_free_if_unref(_Rope_RopeRep*) {} +# endif + +}; + +template +struct _Rope_RopeLeaf : public _Rope_RopeRep<_CharT,_Alloc> { + public: + // Apparently needed by VC++ + // The data fields of leaves are allocated with some + // extra space, to accomodate future growth and for basic + // character types, to hold a trailing eos character. + enum { _S_alloc_granularity = 8 }; + static size_t _S_rounded_up_size(size_t __n) { + size_t __size_with_eos; + + if (_S_is_basic_char_type((_CharT*)0)) { + __size_with_eos = __n + 1; + } else { + __size_with_eos = __n; + } +# ifdef __GC + return __size_with_eos; +# else + // Allow slop for in-place expansion. + return (__size_with_eos + _S_alloc_granularity-1) + &~ (_S_alloc_granularity-1); +# endif + } + __GC_CONST _CharT* _M_data; /* Not necessarily 0 terminated. */ + /* The allocated size is */ + /* _S_rounded_up_size(size), except */ + /* in the GC case, in which it */ + /* doesn't matter. */ + typedef _Rope_rep_base<_CharT,_Alloc>::allocator_type allocator_type; + _Rope_RopeLeaf(__GC_CONST _CharT* __d, size_t __size, allocator_type __a) + : _Rope_RopeRep<_CharT,_Alloc>(_S_leaf, 0, true, __size, __a), + _M_data(__d) + { + __stl_assert(__size > 0); + if (_S_is_basic_char_type((_CharT *)0)) { + // already eos terminated. + _M_c_string = __d; + } + } + // The constructor assumes that d has been allocated with + // the proper allocator and the properly padded size. + // In contrast, the destructor deallocates the data: +# ifndef __GC + ~_Rope_RopeLeaf() { + if (_M_data != _M_c_string) { + _M_free_c_string(); + } + __STL_FREE_STRING(_M_data, _M_size, get_allocator()); + } +# endif +}; + +template +struct _Rope_RopeConcatenation : public _Rope_RopeRep<_CharT,_Alloc> { + public: + _Rope_RopeRep<_CharT,_Alloc>* _M_left; + _Rope_RopeRep<_CharT,_Alloc>* _M_right; + typedef _Rope_rep_base<_CharT,_Alloc>::allocator_type allocator_type; + _Rope_RopeConcatenation(_Rope_RopeRep<_CharT,_Alloc>* __l, + _Rope_RopeRep<_CharT,_Alloc>* __r, + allocator_type __a) + : _Rope_RopeRep<_CharT,_Alloc>( + _S_concat, max(__l->_M_depth, __r->_M_depth) + 1, false, + __l->_M_size + __r->_M_size, __a), + _M_left(__l), _M_right(__r) + {} +# ifndef __GC + ~_Rope_RopeConcatenation() { + _M_free_c_string(); + _M_left->_M_unref_nonnil(); + _M_right->_M_unref_nonnil(); + } +# endif +}; + +template +struct _Rope_RopeFunction : public _Rope_RopeRep<_CharT,_Alloc> { + public: + char_producer<_CharT>* _M_fn; +# ifndef __GC + bool _M_delete_when_done; // Char_producer is owned by the + // rope and should be explicitly + // deleted when the rope becomes + // inaccessible. +# else + // In the GC case, we either register the rope for + // finalization, or not. Thus the field is unnecessary; + // the information is stored in the collector data structures. + // We do need a finalization procedure to be invoked by the + // collector. + static void _S_fn_finalization_proc(void * __tree, void *) { + delete ((_Rope_RopeFunction *)__tree) -> _M_fn; + } +# endif + typedef _Rope_rep_base<_CharT,_Alloc>::allocator_type allocator_type; + _Rope_RopeFunction(char_producer<_CharT>* __f, size_t __size, + bool __d, allocator_type __a) + :_Rope_RopeRep<_CharT,_Alloc>(_S_function, 0, true, __size, __a), + _M_fn(__f) +# ifndef __GC + , _M_delete_when_done(__d) +# endif + { + __stl_assert(__size > 0); +# ifdef __GC + if (__d) { + GC_REGISTER_FINALIZER( + this, _Rope_RopeFunction::_S_fn_finalization_proc, 0, 0, 0); + } +# endif + } +# ifndef __GC + ~_Rope_RopeFunction() { + _M_free_c_string(); + if (_M_delete_when_done) { + delete _M_fn; + } + } +# endif +}; +// Substring results are usually represented using just +// concatenation nodes. But in the case of very long flat ropes +// or ropes with a functional representation that isn't practical. +// In that case, we represent the __result as a special case of +// RopeFunction, whose char_producer points back to the rope itself. +// In all cases except repeated substring operations and +// deallocation, we treat the __result as a RopeFunction. +template +struct _Rope_RopeSubstring : public _Rope_RopeFunction<_CharT,_Alloc>, + public char_producer<_CharT> { + public: + // XXX this whole class should be rewritten. + _Rope_RopeRep<_CharT,_Alloc>* _M_base; // not 0 + size_t _M_start; + virtual void operator()(size_t __start_pos, size_t __req_len, + _CharT* __buffer) { + switch(_M_base->_M_tag) { + case _S_function: + case _S_substringfn: + { + char_producer<_CharT>* __fn = + ((_Rope_RopeFunction<_CharT,_Alloc>*)_M_base)->_M_fn; + __stl_assert(__start_pos + __req_len <= _M_size); + __stl_assert(_M_start + _M_size <= _M_base->_M_size); + (*__fn)(__start_pos + _M_start, __req_len, __buffer); + } + break; + case _S_leaf: + { + __GC_CONST _CharT* __s = + ((_Rope_RopeLeaf<_CharT,_Alloc>*)_M_base)->_M_data; + uninitialized_copy_n(__s + __start_pos + _M_start, __req_len, + __buffer); + } + break; + default: + __stl_assert(false); + } + } + typedef _Rope_rep_base<_CharT,_Alloc>::allocator_type allocator_type; + _Rope_RopeSubstring(_Rope_RopeRep<_CharT,_Alloc>* __b, size_t __s, + size_t __l, allocator_type __a) + : _Rope_RopeFunction<_CharT,_Alloc>(this, __l, false, __a), _M_base(__b) + , _M_start(__s) + { + __stl_assert(__l > 0); + __stl_assert(__s + __l <= __b->_M_size); +# ifndef __GC + _M_base->_M_ref_nonnil(); +# endif + _M_tag = _S_substringfn; + } + virtual ~_Rope_RopeSubstring() + { +# ifndef __GC + _M_base->_M_unref_nonnil(); + // _M_free_c_string(); -- done by parent class +# endif + } +}; + + +// Self-destructing pointers to Rope_rep. +// These are not conventional smart pointers. Their +// only purpose in life is to ensure that unref is called +// on the pointer either at normal exit or if an exception +// is raised. It is the caller's responsibility to +// adjust reference counts when these pointers are initialized +// or assigned to. (This convention significantly reduces +// the number of potentially expensive reference count +// updates.) +#ifndef __GC + template + struct _Rope_self_destruct_ptr { + _Rope_RopeRep<_CharT,_Alloc>* _M_ptr; + ~_Rope_self_destruct_ptr() + { _Rope_RopeRep<_CharT,_Alloc>::_S_unref(_M_ptr); } +# ifdef __STL_USE_EXCEPTIONS + _Rope_self_destruct_ptr() : _M_ptr(0) {}; +# else + _Rope_self_destruct_ptr() {}; +# endif + _Rope_self_destruct_ptr(_Rope_RopeRep<_CharT,_Alloc>* __p) : _M_ptr(__p) {} + _Rope_RopeRep<_CharT,_Alloc>& operator*() { return *_M_ptr; } + _Rope_RopeRep<_CharT,_Alloc>* operator->() { return _M_ptr; } + operator _Rope_RopeRep<_CharT,_Alloc>*() { return _M_ptr; } + _Rope_self_destruct_ptr& operator= (_Rope_RopeRep<_CharT,_Alloc>* __x) + { _M_ptr = __x; return *this; } + }; +#endif + +// Dereferencing a nonconst iterator has to return something +// that behaves almost like a reference. It's not possible to +// return an actual reference since assignment requires extra +// work. And we would get into the same problems as with the +// CD2 version of basic_string. +template +class _Rope_char_ref_proxy { + friend class rope<_CharT,_Alloc>; + friend class _Rope_iterator<_CharT,_Alloc>; + friend class _Rope_char_ptr_proxy<_CharT,_Alloc>; +# ifdef __GC + typedef _Rope_RopeRep<_CharT,_Alloc>* _Self_destruct_ptr; +# else + typedef _Rope_self_destruct_ptr<_CharT,_Alloc> _Self_destruct_ptr; +# endif + typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep; + typedef rope<_CharT,_Alloc> _My_rope; + size_t _M_pos; + _CharT _M_current; + bool _M_current_valid; + _My_rope* _M_root; // The whole rope. + public: + _Rope_char_ref_proxy(_My_rope* __r, size_t __p) : + _M_pos(__p), _M_current_valid(false), _M_root(__r) {} + _Rope_char_ref_proxy(const _Rope_char_ref_proxy& __x) : + _M_pos(__x._M_pos), _M_current_valid(false), _M_root(__x._M_root) {} + // Don't preserve cache if the reference can outlive the + // expression. We claim that's not possible without calling + // a copy constructor or generating reference to a proxy + // reference. We declare the latter to have undefined semantics. + _Rope_char_ref_proxy(_My_rope* __r, size_t __p, + _CharT __c) : + _M_pos(__p), _M_current(__c), _M_current_valid(true), _M_root(__r) {} + inline operator _CharT () const; + _Rope_char_ref_proxy& operator= (_CharT __c); + _Rope_char_ptr_proxy<_CharT,_Alloc> operator& () const; + _Rope_char_ref_proxy& operator= (const _Rope_char_ref_proxy& __c) { + return operator=((_CharT)__c); + } +}; + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + template + inline void swap(_Rope_char_ref_proxy <_CharT, __Alloc > __a, + _Rope_char_ref_proxy <_CharT, __Alloc > __b) { + _CharT __tmp = __a; + __a = __b; + __b = __tmp; + } +#else +// There is no really acceptable way to handle this. The default +// definition of swap doesn't work for proxy references. +// It can't really be made to work, even with ugly hacks, since +// the only unusual operation it uses is the copy constructor, which +// is needed for other purposes. We provide a macro for +// full specializations, and instantiate the most common case. +# define _ROPE_SWAP_SPECIALIZATION(_CharT, __Alloc) \ + inline void swap(_Rope_char_ref_proxy <_CharT, __Alloc > __a, \ + _Rope_char_ref_proxy <_CharT, __Alloc > __b) { \ + _CharT __tmp = __a; \ + __a = __b; \ + __b = __tmp; \ + } + +_ROPE_SWAP_SPECIALIZATION(char,__STL_DEFAULT_ALLOCATOR(char)) + +#endif /* !__STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +template +class _Rope_char_ptr_proxy { + // XXX this class should be rewritten. + friend class _Rope_char_ref_proxy<_CharT,_Alloc>; + size_t _M_pos; + rope<_CharT,_Alloc>* _M_root; // The whole rope. + public: + _Rope_char_ptr_proxy(const _Rope_char_ref_proxy<_CharT,_Alloc>& __x) + : _M_pos(__x._M_pos), _M_root(__x._M_root) {} + _Rope_char_ptr_proxy(const _Rope_char_ptr_proxy& __x) + : _M_pos(__x._M_pos), _M_root(__x._M_root) {} + _Rope_char_ptr_proxy() {} + _Rope_char_ptr_proxy(_CharT* __x) : _M_root(0), _M_pos(0) { + __stl_assert(0 == __x); + } + _Rope_char_ptr_proxy& + operator= (const _Rope_char_ptr_proxy& __x) { + _M_pos = __x._M_pos; + _M_root = __x._M_root; + return *this; + } + friend bool operator== __STL_NULL_TMPL_ARGS + (const _Rope_char_ptr_proxy<_CharT,_Alloc>& __x, + const _Rope_char_ptr_proxy<_CharT,_Alloc>& __y); + + _Rope_char_ref_proxy<_CharT,_Alloc> operator*() const { + return _Rope_char_ref_proxy<_CharT,_Alloc>(_M_root, _M_pos); + } +}; + + +// Rope iterators: +// Unlike in the C version, we cache only part of the stack +// for rope iterators, since they must be efficiently copyable. +// When we run out of cache, we have to reconstruct the iterator +// value. +// Pointers from iterators are not included in reference counts. +// Iterators are assumed to be thread private. Ropes can +// be shared. + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1375 +#endif + +template +class _Rope_iterator_base + : public random_access_iterator<_CharT, ptrdiff_t> { + friend class rope<_CharT,_Alloc>; + public: + typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep; + // Borland doesnt want this to be protected. + protected: + enum { _S_path_cache_len = 4 }; // Must be <= 9. + enum { _S_iterator_buf_len = 15 }; + size_t _M_current_pos; + _RopeRep* _M_root; // The whole rope. + size_t _M_leaf_pos; // Starting position for current leaf + __GC_CONST _CharT* _M_buf_start; + // Buffer possibly + // containing current char. + __GC_CONST _CharT* _M_buf_ptr; + // Pointer to current char in buffer. + // != 0 ==> buffer valid. + __GC_CONST _CharT* _M_buf_end; + // One past __last valid char in buffer. + // What follows is the path cache. We go out of our + // way to make this compact. + // Path_end contains the bottom section of the path from + // the root to the current leaf. + const _RopeRep* _M_path_end[_S_path_cache_len]; + int _M_leaf_index; // Last valid __pos in path_end; + // _M_path_end[0] ... _M_path_end[leaf_index-1] + // point to concatenation nodes. + unsigned char _M_path_directions; + // (path_directions >> __i) & 1 is 1 + // iff we got from _M_path_end[leaf_index - __i - 1] + // to _M_path_end[leaf_index - __i] by going to the + // __right. Assumes path_cache_len <= 9. + _CharT _M_tmp_buf[_S_iterator_buf_len]; + // Short buffer for surrounding chars. + // This is useful primarily for + // RopeFunctions. We put the buffer + // here to avoid locking in the + // multithreaded case. + // The cached path is generally assumed to be valid + // only if the buffer is valid. + static void _S_setbuf(_Rope_iterator_base& __x); + // Set buffer contents given + // path cache. + static void _S_setcache(_Rope_iterator_base& __x); + // Set buffer contents and + // path cache. + static void _S_setcache_for_incr(_Rope_iterator_base& __x); + // As above, but assumes path + // cache is valid for previous posn. + _Rope_iterator_base() {} + _Rope_iterator_base(_RopeRep* __root, size_t __pos) + : _M_root(__root), _M_current_pos(__pos), _M_buf_ptr(0) {} + void _M_incr(size_t __n); + void _M_decr(size_t __n); + public: + size_t index() const { return _M_current_pos; } + _Rope_iterator_base(const _Rope_iterator_base& __x) { + if (0 != __x._M_buf_ptr) { + *this = __x; + } else { + _M_current_pos = __x._M_current_pos; + _M_root = __x._M_root; + _M_buf_ptr = 0; + } + } +}; + +template class _Rope_iterator; + +template +class _Rope_const_iterator : public _Rope_iterator_base<_CharT,_Alloc> { + friend class rope<_CharT,_Alloc>; + protected: + _Rope_const_iterator(const _RopeRep* __root, size_t __pos): + _Rope_iterator_base<_CharT,_Alloc>( + const_cast<_RopeRep*>(__root), __pos) + // Only nonconst iterators modify root ref count + {} + public: + typedef _CharT reference; // Really a value. Returning a reference + // Would be a mess, since it would have + // to be included in refcount. + typedef const _CharT* pointer; + + public: + _Rope_const_iterator() {}; + _Rope_const_iterator(const _Rope_const_iterator& __x) : + _Rope_iterator_base<_CharT,_Alloc>(__x) { } + _Rope_const_iterator(const _Rope_iterator<_CharT,_Alloc>& __x); + _Rope_const_iterator(const rope<_CharT,_Alloc>& __r, size_t __pos) : + _Rope_iterator_base<_CharT,_Alloc>(__r._M_tree_ptr, __pos) {} + _Rope_const_iterator& operator= (const _Rope_const_iterator& __x) { + if (0 != __x._M_buf_ptr) { + *(static_cast<_Rope_iterator_base<_CharT,_Alloc>*>(this)) = __x; + } else { + _M_current_pos = __x._M_current_pos; + _M_root = __x._M_root; + _M_buf_ptr = 0; + } + return(*this); + } + reference operator*() { + if (0 == _M_buf_ptr) _S_setcache(*this); + return *_M_buf_ptr; + } + _Rope_const_iterator& operator++() { + __GC_CONST _CharT* __next; + if (0 != _M_buf_ptr && (__next = _M_buf_ptr + 1) < _M_buf_end) { + _M_buf_ptr = __next; + ++_M_current_pos; + } else { + _M_incr(1); + } + return *this; + } + _Rope_const_iterator& operator+=(ptrdiff_t __n) { + if (__n >= 0) { + _M_incr(__n); + } else { + _M_decr(-__n); + } + return *this; + } + _Rope_const_iterator& operator--() { + _M_decr(1); + return *this; + } + _Rope_const_iterator& operator-=(ptrdiff_t __n) { + if (__n >= 0) { + _M_decr(__n); + } else { + _M_incr(-__n); + } + return *this; + } + _Rope_const_iterator operator++(int) { + size_t __old_pos = _M_current_pos; + _M_incr(1); + return _Rope_const_iterator<_CharT,_Alloc>(_M_root, __old_pos); + // This makes a subsequent dereference expensive. + // Perhaps we should instead copy the iterator + // if it has a valid cache? + } + _Rope_const_iterator operator--(int) { + size_t __old_pos = _M_current_pos; + _M_decr(1); + return _Rope_const_iterator<_CharT,_Alloc>(_M_root, __old_pos); + } + friend _Rope_const_iterator<_CharT,_Alloc> operator- __STL_NULL_TMPL_ARGS + (const _Rope_const_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n); + friend _Rope_const_iterator<_CharT,_Alloc> operator+ __STL_NULL_TMPL_ARGS + (const _Rope_const_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n); + friend _Rope_const_iterator<_CharT,_Alloc> operator+ __STL_NULL_TMPL_ARGS + (ptrdiff_t __n, + const _Rope_const_iterator<_CharT,_Alloc>& __x); + reference operator[](size_t __n) { + return rope<_CharT,_Alloc>::_S_fetch(_M_root, _M_current_pos + __n); + } + friend bool operator== __STL_NULL_TMPL_ARGS + (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y); + friend bool operator< __STL_NULL_TMPL_ARGS + (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y); + friend ptrdiff_t operator- __STL_NULL_TMPL_ARGS + (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y); +}; + +template +class _Rope_iterator : public _Rope_iterator_base<_CharT,_Alloc> { + friend class rope<_CharT,_Alloc>; + protected: + rope<_CharT,_Alloc>* _M_root_rope; + // root is treated as a cached version of this, + // and is used to detect changes to the underlying + // rope. + // Root is included in the reference count. + // This is necessary so that we can detect changes reliably. + // Unfortunately, it requires careful bookkeeping for the + // nonGC case. + _Rope_iterator(rope<_CharT,_Alloc>* __r, size_t __pos) + : _Rope_iterator_base<_CharT,_Alloc>(__r->_M_tree_ptr, __pos), + _M_root_rope(__r) + { _RopeRep::_S_ref(_M_root); } + + void _M_check(); + public: + typedef _Rope_char_ref_proxy<_CharT,_Alloc> reference; + typedef _Rope_char_ref_proxy<_CharT,_Alloc>* pointer; + + public: + rope<_CharT,_Alloc>& container() { return *_M_root_rope; } + _Rope_iterator() { + _M_root = 0; // Needed for reference counting. + }; + _Rope_iterator(const _Rope_iterator& __x) : + _Rope_iterator_base<_CharT,_Alloc>(__x) { + _M_root_rope = __x._M_root_rope; + _RopeRep::_S_ref(_M_root); + } + _Rope_iterator(rope<_CharT,_Alloc>& __r, size_t __pos); + ~_Rope_iterator() { + _RopeRep::_S_unref(_M_root); + } + _Rope_iterator& operator= (const _Rope_iterator& __x) { + _RopeRep* __old = _M_root; + + _RopeRep::_S_ref(__x._M_root); + if (0 != __x._M_buf_ptr) { + _M_root_rope = __x._M_root_rope; + *(static_cast<_Rope_iterator_base<_CharT,_Alloc>*>(this)) = __x; + } else { + _M_current_pos = __x._M_current_pos; + _M_root = __x._M_root; + _M_root_rope = __x._M_root_rope; + _M_buf_ptr = 0; + } + _RopeRep::_S_unref(__old); + return(*this); + } + reference operator*() { + _M_check(); + if (0 == _M_buf_ptr) { + return _Rope_char_ref_proxy<_CharT,_Alloc>( + _M_root_rope, _M_current_pos); + } else { + return _Rope_char_ref_proxy<_CharT,_Alloc>( + _M_root_rope, _M_current_pos, *_M_buf_ptr); + } + } + _Rope_iterator& operator++() { + _M_incr(1); + return *this; + } + _Rope_iterator& operator+=(difference_type __n) { + if (__n >= 0) { + _M_incr(__n); + } else { + _M_decr(-__n); + } + return *this; + } + _Rope_iterator& operator--() { + _M_decr(1); + return *this; + } + _Rope_iterator& operator-=(difference_type __n) { + if (__n >= 0) { + _M_decr(__n); + } else { + _M_incr(-__n); + } + return *this; + } + _Rope_iterator operator++(int) { + size_t __old_pos = _M_current_pos; + _M_incr(1); + return _Rope_iterator<_CharT,_Alloc>(_M_root_rope, __old_pos); + } + _Rope_iterator operator--(int) { + size_t __old_pos = _M_current_pos; + _M_decr(1); + return _Rope_iterator<_CharT,_Alloc>(_M_root_rope, __old_pos); + } + reference operator[](ptrdiff_t __n) { + return _Rope_char_ref_proxy<_CharT,_Alloc>( + _M_root_rope, _M_current_pos + __n); + } + friend bool operator== __STL_NULL_TMPL_ARGS + (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y); + friend bool operator< __STL_NULL_TMPL_ARGS + (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y); + friend ptrdiff_t operator- __STL_NULL_TMPL_ARGS + (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y); + friend _Rope_iterator<_CharT,_Alloc> operator- __STL_NULL_TMPL_ARGS + (const _Rope_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n); + friend _Rope_iterator<_CharT,_Alloc> operator+ __STL_NULL_TMPL_ARGS + (const _Rope_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n); + friend _Rope_iterator<_CharT,_Alloc> operator+ __STL_NULL_TMPL_ARGS + (ptrdiff_t __n, + const _Rope_iterator<_CharT,_Alloc>& __x); + +}; + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1375 +#endif + +// The rope base class encapsulates +// the differences between SGI-style allocators and standard-conforming +// allocators. + +#ifdef __STL_USE_STD_ALLOCATORS + +// Base class for ordinary allocators. +template +class _Rope_alloc_base { +public: + typedef _Rope_RopeRep<_CharT,_Allocator> _RopeRep; + typedef typename _Alloc_traits<_CharT,_Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return _M_data_allocator; } + _Rope_alloc_base(_RopeRep *__t, const allocator_type& __a) + : _M_tree_ptr(__t), _M_data_allocator(__a) {} + _Rope_alloc_base(const allocator_type& __a) + : _M_data_allocator(__a) {} + +protected: + // The only data members of a rope: + allocator_type _M_data_allocator; + _RopeRep* _M_tree_ptr; + +# define __ROPE_DEFINE_ALLOC(_Tp, __name) \ + typedef typename \ + _Alloc_traits<_Tp,_Allocator>::allocator_type __name##Allocator; \ + _Tp* __name##_allocate(size_t __n) const \ + { return __name##Allocator(_M_data_allocator).allocate(__n); } \ + void __name##_deallocate(_Tp *__p, size_t __n) const \ + { __name##Allocator(_M_data_allocator).deallocate(__p, __n); } + __ROPE_DEFINE_ALLOCS(_Allocator) +# undef __ROPE_DEFINE_ALLOC +}; + +// Specialization for allocators that have the property that we don't +// actually have to store an allocator object. +template +class _Rope_alloc_base<_CharT,_Allocator,true> { +public: + typedef _Rope_RopeRep<_CharT,_Allocator> _RopeRep; + typedef typename _Alloc_traits<_CharT,_Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + _Rope_alloc_base(_RopeRep *__t, const allocator_type&) + : _M_tree_ptr(__t) {} + _Rope_alloc_base(const allocator_type&) {} + +protected: + // The only data member of a rope: + _RopeRep *_M_tree_ptr; + +# define __ROPE_DEFINE_ALLOC(_Tp, __name) \ + typedef typename \ + _Alloc_traits<_Tp,_Allocator>::_Alloc_type __name##Alloc; \ + typedef typename \ + _Alloc_traits<_Tp,_Allocator>::allocator_type __name##Allocator; \ + static _Tp* __name##_allocate(size_t __n) \ + { return __name##Alloc::allocate(__n); } \ + static void __name##_deallocate(_Tp *__p, size_t __n) \ + { __name##Alloc::deallocate(__p, __n); } + __ROPE_DEFINE_ALLOCS(_Allocator) +# undef __ROPE_DEFINE_ALLOC +}; + +template +struct _Rope_base + : public _Rope_alloc_base<_CharT,_Alloc, + _Alloc_traits<_CharT,_Alloc>::_S_instanceless> +{ + typedef _Rope_alloc_base<_CharT,_Alloc, + _Alloc_traits<_CharT,_Alloc>::_S_instanceless> + _Base; + typedef typename _Base::allocator_type allocator_type; + _Rope_base(_RopeRep* __t, const allocator_type& __a) : _Base(__t, __a) {} + _Rope_base(const allocator_type& __a) : _Base(__a) {} +}; + +#else /* !__STL_USE_STD_ALLOCATORS */ + +template +class _Rope_base { +public: + typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep; + typedef _Alloc allocator_type; + static allocator_type get_allocator() { return allocator_type(); } + _Rope_base(_RopeRep * __t, const allocator_type&) : _M_tree_ptr(__t) {} + _Rope_base(const allocator_type&) {} + +protected: + // The only data member of a rope: + _RopeRep* _M_tree_ptr; + +# define __ROPE_DEFINE_ALLOC(_Tp, __name) \ + typedef simple_alloc<_Tp, _Alloc> __name##Alloc; \ + static _Tp* __name##_allocate(size_t __n) \ + { return __name##Alloc::allocate(__n); } \ + static void __name##_deallocate(_Tp *__p, size_t __n) \ + { __name##Alloc::deallocate(__p, __n); } + __ROPE_DEFINE_ALLOCS(_Alloc) +# undef __ROPE_DEFINE_ALLOC +}; + +#endif /* __STL_USE_STD_ALLOCATORS */ + + +template +class rope : public _Rope_base<_CharT,_Alloc> { + public: + typedef _CharT value_type; + typedef ptrdiff_t difference_type; + typedef size_t size_type; + typedef _CharT const_reference; + typedef const _CharT* const_pointer; + typedef _Rope_iterator<_CharT,_Alloc> iterator; + typedef _Rope_const_iterator<_CharT,_Alloc> const_iterator; + typedef _Rope_char_ref_proxy<_CharT,_Alloc> reference; + typedef _Rope_char_ptr_proxy<_CharT,_Alloc> pointer; + + friend class _Rope_iterator<_CharT,_Alloc>; + friend class _Rope_const_iterator<_CharT,_Alloc>; + friend struct _Rope_RopeRep<_CharT,_Alloc>; + friend class _Rope_iterator_base<_CharT,_Alloc>; + friend class _Rope_char_ptr_proxy<_CharT,_Alloc>; + friend class _Rope_char_ref_proxy<_CharT,_Alloc>; + friend struct _Rope_RopeSubstring<_CharT,_Alloc>; + + protected: + typedef _Rope_base<_CharT,_Alloc> _Base; + typedef typename _Base::allocator_type allocator_type; +# ifdef __STL_USE_NAMESPACES + using _Base::_M_tree_ptr; +# endif + typedef __GC_CONST _CharT* _Cstrptr; +# ifdef __STL_SGI_THREADS + static _Cstrptr _S_atomic_swap(_Cstrptr* __p, _Cstrptr __q) { +# if __mips < 3 || !(defined (_ABIN32) || defined(_ABI64)) + return (_Cstrptr) test_and_set((unsigned long*)__p, + (unsigned long)__q); +# else + return (_Cstrptr) __test_and_set((unsigned long*)__p, + (unsigned long)__q); +# endif + } +# elif defined(__STL_WIN32THREADS) + static _Cstrptr _S_atomic_swap(_Cstrptr* __p, _Cstrptr __q) { + return (_Cstrptr) InterlockedExchange( + (LPLONG)__p, (LONG)__q); + } +# elif defined(__STL_PTHREADS) + // This should be portable, but performance is expected + // to be quite awful. This really needs platform specific + // code. + static pthread_mutex_t _S_swap_lock; + static _Cstrptr _S_atomic_swap(_Cstrptr* __p, _Cstrptr __q) { + pthread_mutex_lock(&_S_swap_lock); + _Cstrptr __result = *__p; + *__p = __q; + pthread_mutex_unlock(&_S_swap_lock); + return __result; + } +# else + static _Cstrptr _S_atomic_swap(_Cstrptr* __p, _Cstrptr __q) { + _Cstrptr __result = *__p; + *__p = __q; + return __result; + } +# endif + + static _CharT _S_empty_c_str[1]; + + static bool _S_is0(_CharT __c) { return __c == _S_eos((_CharT*)0); } + enum { _S_copy_max = 23 }; + // For strings shorter than _S_copy_max, we copy to + // concatenate. + + typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep; + typedef _Rope_RopeConcatenation<_CharT,_Alloc> _RopeConcatenation; + typedef _Rope_RopeLeaf<_CharT,_Alloc> _RopeLeaf; + typedef _Rope_RopeFunction<_CharT,_Alloc> _RopeFunction; + typedef _Rope_RopeSubstring<_CharT,_Alloc> _RopeSubstring; + + // Retrieve a character at the indicated position. + static _CharT _S_fetch(_RopeRep* __r, size_type __pos); + +# ifndef __GC + // Obtain a pointer to the character at the indicated position. + // The pointer can be used to change the character. + // If such a pointer cannot be produced, as is frequently the + // case, 0 is returned instead. + // (Returns nonzero only if all nodes in the path have a refcount + // of 1.) + static _CharT* _S_fetch_ptr(_RopeRep* __r, size_type __pos); +# endif + + static bool _S_apply_to_pieces( + // should be template parameter + _Rope_char_consumer<_CharT>& __c, + const _RopeRep* __r, + size_t __begin, size_t __end); + // begin and end are assumed to be in range. + +# ifndef __GC + static void _S_unref(_RopeRep* __t) + { + _RopeRep::_S_unref(__t); + } + static void _S_ref(_RopeRep* __t) + { + _RopeRep::_S_ref(__t); + } +# else /* __GC */ + static void _S_unref(_RopeRep*) {} + static void _S_ref(_RopeRep*) {} +# endif + + +# ifdef __GC + typedef _Rope_RopeRep<_CharT,_Alloc>* _Self_destruct_ptr; +# else + typedef _Rope_self_destruct_ptr<_CharT,_Alloc> _Self_destruct_ptr; +# endif + + // _Result is counted in refcount. + static _RopeRep* _S_substring(_RopeRep* __base, + size_t __start, size_t __endp1); + + static _RopeRep* _S_concat_char_iter(_RopeRep* __r, + const _CharT* __iter, size_t __slen); + // Concatenate rope and char ptr, copying __s. + // Should really take an arbitrary iterator. + // Result is counted in refcount. + static _RopeRep* _S_destr_concat_char_iter(_RopeRep* __r, + const _CharT* __iter, size_t __slen) + // As above, but one reference to __r is about to be + // destroyed. Thus the pieces may be recycled if all + // relevent reference counts are 1. +# ifdef __GC + // We can't really do anything since refcounts are unavailable. + { return _S_concat_char_iter(__r, __iter, __slen); } +# else + ; +# endif + + static _RopeRep* _S_concat(_RopeRep* __left, _RopeRep* __right); + // General concatenation on _RopeRep. _Result + // has refcount of 1. Adjusts argument refcounts. + + public: + void apply_to_pieces( size_t __begin, size_t __end, + _Rope_char_consumer<_CharT>& __c) const { + _S_apply_to_pieces(__c, _M_tree_ptr, __begin, __end); + } + + + protected: + + static size_t _S_rounded_up_size(size_t __n) { + return _RopeLeaf::_S_rounded_up_size(__n); + } + + static size_t _S_allocated_capacity(size_t __n) { + if (_S_is_basic_char_type((_CharT*)0)) { + return _S_rounded_up_size(__n) - 1; + } else { + return _S_rounded_up_size(__n); + } + } + + // Allocate and construct a RopeLeaf using the supplied allocator + // Takes ownership of s instead of copying. + static _RopeLeaf* _S_new_RopeLeaf(__GC_CONST _CharT *__s, + size_t __size, allocator_type __a) + { +# ifdef __STL_USE_STD_ALLOCATORS + _RopeLeaf* __space = _LAllocator(__a).allocate(1); +# else + _RopeLeaf* __space = _L_allocate(1); +# endif + return new(__space) _RopeLeaf(__s, __size, __a); + } + + static _RopeConcatenation* _S_new_RopeConcatenation( + _RopeRep* __left, _RopeRep* __right, + allocator_type __a) + { +# ifdef __STL_USE_STD_ALLOCATORS + _RopeConcatenation* __space = _CAllocator(__a).allocate(1); +# else + _RopeConcatenation* __space = _C_allocate(1); +# endif + return new(__space) _RopeConcatenation(__left, __right, __a); + } + + static _RopeFunction* _S_new_RopeFunction(char_producer<_CharT>* __f, + size_t __size, bool __d, allocator_type __a) + { +# ifdef __STL_USE_STD_ALLOCATORS + _RopeFunction* __space = _FAllocator(__a).allocate(1); +# else + _RopeFunction* __space = _F_allocate(1); +# endif + return new(__space) _RopeFunction(__f, __size, __d, __a); + } + + static _RopeSubstring* _S_new_RopeSubstring( + _Rope_RopeRep<_CharT,_Alloc>* __b, size_t __s, + size_t __l, allocator_type __a) + { +# ifdef __STL_USE_STD_ALLOCATORS + _RopeSubstring* __space = _SAllocator(__a).allocate(1); +# else + _RopeSubstring* __space = _S_allocate(1); +# endif + return new(__space) _RopeSubstring(__b, __s, __l, __a); + } + +# ifdef __STL_USE_STD_ALLOCATORS + static + _RopeLeaf* _S_RopeLeaf_from_unowned_char_ptr(const _CharT *__s, + size_t __size, allocator_type __a) +# define __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __size, __a) \ + _S_RopeLeaf_from_unowned_char_ptr(__s, __size, __a) +# else + static + _RopeLeaf* _S_RopeLeaf_from_unowned_char_ptr2(const _CharT* __s, + size_t __size) +# define __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __size, __a) \ + _S_RopeLeaf_from_unowned_char_ptr2(__s, __size) +# endif + { + if (0 == __size) return 0; +# ifdef __STL_USE_STD_ALLOCATORS + _CharT* __buf = __a.allocate(_S_rounded_up_size(__size)); +# else + _CharT* __buf = _Data_allocate(_S_rounded_up_size(__size)); + allocator_type __a = allocator_type(); +# endif + + uninitialized_copy_n(__s, __size, __buf); + _S_cond_store_eos(__buf[__size]); + __STL_TRY { + return _S_new_RopeLeaf(__buf, __size, __a); + } + __STL_UNWIND(_RopeRep::__STL_FREE_STRING(__buf, __size, __a)) + } + + + // Concatenation of nonempty strings. + // Always builds a concatenation node. + // Rebalances if the result is too deep. + // Result has refcount 1. + // Does not increment left and right ref counts even though + // they are referenced. + static _RopeRep* + _S_tree_concat(_RopeRep* __left, _RopeRep* __right); + + // Concatenation helper functions + static _RopeLeaf* + _S_leaf_concat_char_iter(_RopeLeaf* __r, + const _CharT* __iter, size_t __slen); + // Concatenate by copying leaf. + // should take an arbitrary iterator + // result has refcount 1. +# ifndef __GC + static _RopeLeaf* _S_destr_leaf_concat_char_iter + (_RopeLeaf* __r, const _CharT* __iter, size_t __slen); + // A version that potentially clobbers __r if __r->_M_refcount == 1. +# endif + + // A helper function for exponentiating strings. + // This uses a nonstandard refcount convention. + // The result has refcount 0. + struct _Concat_fn + : public binary_function, + rope<_CharT,_Alloc>, + rope<_CharT,_Alloc> > { + rope operator() (const rope& __x, const rope& __y) { + return __x + __y; + } + }; + + // Needed by the call to "power" used to build ropes + // consisting of n copies of a character. + friend rope identity_element(_Concat_fn) + { return rope<_CharT,_Alloc>(); } + + static size_t _S_char_ptr_len(const _CharT* __s); + // slightly generalized strlen + + rope(_RopeRep* __t, const allocator_type& __a = allocator_type()) + : _Base(__t,__a) { } + + + // Copy __r to the _CharT buffer. + // Returns __buffer + __r->_M_size. + // Assumes that buffer is uninitialized. + static _CharT* _S_flatten(_RopeRep* __r, _CharT* __buffer); + + // Again, with explicit starting position and length. + // Assumes that buffer is uninitialized. + static _CharT* _S_flatten(_RopeRep* __r, + size_t __start, size_t __len, + _CharT* __buffer); + + static const unsigned long + _S_min_len[_RopeRep::_S_max_rope_depth + 1]; + + static bool _S_is_balanced(_RopeRep* __r) + { return (__r->_M_size >= _S_min_len[__r->_M_depth]); } + + static bool _S_is_almost_balanced(_RopeRep* __r) + { return (__r->_M_depth == 0 || + __r->_M_size >= _S_min_len[__r->_M_depth - 1]); } + + static bool _S_is_roughly_balanced(_RopeRep* __r) + { return (__r->_M_depth <= 1 || + __r->_M_size >= _S_min_len[__r->_M_depth - 2]); } + + // Assumes the result is not empty. + static _RopeRep* _S_concat_and_set_balanced(_RopeRep* __left, + _RopeRep* __right) + { + _RopeRep* __result = _S_concat(__left, __right); + if (_S_is_balanced(__result)) __result->_M_is_balanced = true; + return __result; + } + + // The basic rebalancing operation. Logically copies the + // rope. The result has refcount of 1. The client will + // usually decrement the reference count of __r. + // The result is within height 2 of balanced by the above + // definition. + static _RopeRep* _S_balance(_RopeRep* __r); + + // Add all unbalanced subtrees to the forest of balanceed trees. + // Used only by balance. + static void _S_add_to_forest(_RopeRep*__r, _RopeRep** __forest); + + // Add __r to forest, assuming __r is already balanced. + static void _S_add_leaf_to_forest(_RopeRep* __r, _RopeRep** __forest); + + // Print to stdout, exposing structure + static void _S_dump(_RopeRep* __r, int __indent = 0); + + // Return -1, 0, or 1 if __x < __y, __x == __y, or __x > __y resp. + static int _S_compare(const _RopeRep* __x, const _RopeRep* __y); + + public: + bool empty() const { return 0 == _M_tree_ptr; } + + // Comparison member function. This is public only for those + // clients that need a ternary comparison. Others + // should use the comparison operators below. + int compare(const rope& __y) const { + return _S_compare(_M_tree_ptr, __y._M_tree_ptr); + } + + rope(const _CharT* __s, const allocator_type& __a = allocator_type()) + : _Base(__STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, _S_char_ptr_len(__s), + __a),__a) + { } + + rope(const _CharT* __s, size_t __len, + const allocator_type& __a = allocator_type()) + : _Base(__STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __len, __a), __a) + { } + + // Should perhaps be templatized with respect to the iterator type + // and use Sequence_buffer. (It should perhaps use sequence_buffer + // even now.) + rope(const _CharT *__s, const _CharT *__e, + const allocator_type& __a = allocator_type()) + : _Base(__STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __e - __s, __a), __a) + { } + + rope(const const_iterator& __s, const const_iterator& __e, + const allocator_type& __a = allocator_type()) + : _Base(_S_substring(__s._M_root, __s._M_current_pos, + __e._M_current_pos), __a) + { } + + rope(const iterator& __s, const iterator& __e, + const allocator_type& __a = allocator_type()) + : _Base(_S_substring(__s._M_root, __s._M_current_pos, + __e._M_current_pos), __a) + { } + + rope(_CharT __c, const allocator_type& __a = allocator_type()) + : _Base(__a) + { + _CharT* __buf = _Data_allocate(_S_rounded_up_size(1)); + + construct(__buf, __c); + __STL_TRY { + _M_tree_ptr = _S_new_RopeLeaf(__buf, 1, __a); + } + __STL_UNWIND(_RopeRep::__STL_FREE_STRING(__buf, 1, __a)) + } + + rope(size_t __n, _CharT __c, + const allocator_type& __a = allocator_type()); + + rope(const allocator_type& __a = allocator_type()) + : _Base(0, __a) {} + + // Construct a rope from a function that can compute its members + rope(char_producer<_CharT> *__fn, size_t __len, bool __delete_fn, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { + _M_tree_ptr = (0 == __len) ? + 0 : _S_new_RopeFunction(__fn, __len, __delete_fn, __a); + } + + rope(const rope& __x, const allocator_type& __a = allocator_type()) + : _Base(__x._M_tree_ptr, __a) + { + _S_ref(_M_tree_ptr); + } + + ~rope() + { + _S_unref(_M_tree_ptr); + } + + rope& operator=(const rope& __x) + { + _RopeRep* __old = _M_tree_ptr; +# ifdef __STL_USE_STD_ALLOCATORS + __stl_assert(get_allocator() == __x.get_allocator()); +# endif + _M_tree_ptr = __x._M_tree_ptr; + _S_ref(_M_tree_ptr); + _S_unref(__old); + return(*this); + } + + void push_back(_CharT __x) + { + _RopeRep* __old = _M_tree_ptr; + _M_tree_ptr = _S_concat_char_iter(_M_tree_ptr, &__x, 1); + _S_unref(__old); + } + + void pop_back() + { + _RopeRep* __old = _M_tree_ptr; + _M_tree_ptr = + _S_substring(_M_tree_ptr, 0, _M_tree_ptr->_M_size - 1); + _S_unref(__old); + } + + _CharT back() const + { + return _S_fetch(_M_tree_ptr, _M_tree_ptr->_M_size - 1); + } + + void push_front(_CharT __x) + { + _RopeRep* __old = _M_tree_ptr; + _RopeRep* __left = + __STL_ROPE_FROM_UNOWNED_CHAR_PTR(&__x, 1, get_allocator()); + __STL_TRY { + _M_tree_ptr = _S_concat(__left, _M_tree_ptr); + _S_unref(__old); + _S_unref(__left); + } + __STL_UNWIND(_S_unref(__left)) + } + + void pop_front() + { + _RopeRep* __old = _M_tree_ptr; + _M_tree_ptr = _S_substring(_M_tree_ptr, 1, _M_tree_ptr->_M_size); + _S_unref(__old); + } + + _CharT front() const + { + return _S_fetch(_M_tree_ptr, 0); + } + + void balance() + { + _RopeRep* __old = _M_tree_ptr; + _M_tree_ptr = _S_balance(_M_tree_ptr); + _S_unref(__old); + } + + void copy(_CharT* __buffer) const { + destroy(__buffer, __buffer + size()); + _S_flatten(_M_tree_ptr, __buffer); + } + + // This is the copy function from the standard, but + // with the arguments reordered to make it consistent with the + // rest of the interface. + // Note that this guaranteed not to compile if the draft standard + // order is assumed. + size_type copy(size_type __pos, size_type __n, _CharT* __buffer) const + { + size_t __size = size(); + size_t __len = (__pos + __n > __size? __size - __pos : __n); + + destroy(__buffer, __buffer + __len); + _S_flatten(_M_tree_ptr, __pos, __len, __buffer); + return __len; + } + + // Print to stdout, exposing structure. May be useful for + // performance debugging. + void dump() { + _S_dump(_M_tree_ptr); + } + + // Convert to 0 terminated string in new allocated memory. + // Embedded 0s in the input do not terminate the copy. + const _CharT* c_str() const; + + // As above, but lso use the flattened representation as the + // the new rope representation. + const _CharT* replace_with_c_str(); + + // Reclaim memory for the c_str generated flattened string. + // Intentionally undocumented, since it's hard to say when this + // is safe for multiple threads. + void delete_c_str () { + if (0 == _M_tree_ptr) return; + if (_RopeRep::_S_leaf == _M_tree_ptr->_M_tag && + ((_RopeLeaf*)_M_tree_ptr)->_M_data == + _M_tree_ptr->_M_c_string) { + // Representation shared + return; + } +# ifndef __GC + _M_tree_ptr->_M_free_c_string(); +# endif + _M_tree_ptr->_M_c_string = 0; + } + + _CharT operator[] (size_type __pos) const { + return _S_fetch(_M_tree_ptr, __pos); + } + + _CharT at(size_type __pos) const { + // if (__pos >= size()) throw out_of_range; // XXX + return (*this)[__pos]; + } + + const_iterator begin() const { + return(const_iterator(_M_tree_ptr, 0)); + } + + // An easy way to get a const iterator from a non-const container. + const_iterator const_begin() const { + return(const_iterator(_M_tree_ptr, 0)); + } + + const_iterator end() const { + return(const_iterator(_M_tree_ptr, size())); + } + + const_iterator const_end() const { + return(const_iterator(_M_tree_ptr, size())); + } + + size_type size() const { + return(0 == _M_tree_ptr? 0 : _M_tree_ptr->_M_size); + } + + size_type length() const { + return size(); + } + + size_type max_size() const { + return _S_min_len[_RopeRep::_S_max_rope_depth-1] - 1; + // Guarantees that the result can be sufficirntly + // balanced. Longer ropes will probably still work, + // but it's harder to make guarantees. + } + +# ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + typedef reverse_iterator const_reverse_iterator; +# else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + typedef reverse_iterator const_reverse_iterator; +# endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + + const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } + + const_reverse_iterator const_rbegin() const { + return const_reverse_iterator(end()); + } + + const_reverse_iterator rend() const { + return const_reverse_iterator(begin()); + } + + const_reverse_iterator const_rend() const { + return const_reverse_iterator(begin()); + } + + friend rope<_CharT,_Alloc> + operator+ __STL_NULL_TMPL_ARGS (const rope<_CharT,_Alloc>& __left, + const rope<_CharT,_Alloc>& __right); + + friend rope<_CharT,_Alloc> + operator+ __STL_NULL_TMPL_ARGS (const rope<_CharT,_Alloc>& __left, + const _CharT* __right); + + friend rope<_CharT,_Alloc> + operator+ __STL_NULL_TMPL_ARGS (const rope<_CharT,_Alloc>& __left, + _CharT __right); + + // The symmetric cases are intentionally omitted, since they're presumed + // to be less common, and we don't handle them as well. + + // The following should really be templatized. + // The first argument should be an input iterator or + // forward iterator with value_type _CharT. + rope& append(const _CharT* __iter, size_t __n) { + _RopeRep* __result = + _S_destr_concat_char_iter(_M_tree_ptr, __iter, __n); + _S_unref(_M_tree_ptr); + _M_tree_ptr = __result; + return *this; + } + + rope& append(const _CharT* __c_string) { + size_t __len = _S_char_ptr_len(__c_string); + append(__c_string, __len); + return(*this); + } + + rope& append(const _CharT* __s, const _CharT* __e) { + _RopeRep* __result = + _S_destr_concat_char_iter(_M_tree_ptr, __s, __e - __s); + _S_unref(_M_tree_ptr); + _M_tree_ptr = __result; + return *this; + } + + rope& append(const_iterator __s, const_iterator __e) { + __stl_assert(__s._M_root == __e._M_root); +# ifdef __STL_USE_STD_ALLOCATORS + __stl_assert(get_allocator() == __s._M_root->get_allocator()); +# endif + _Self_destruct_ptr __appendee(_S_substring( + __s._M_root, __s._M_current_pos, __e._M_current_pos)); + _RopeRep* __result = + _S_concat(_M_tree_ptr, (_RopeRep*)__appendee); + _S_unref(_M_tree_ptr); + _M_tree_ptr = __result; + return *this; + } + + rope& append(_CharT __c) { + _RopeRep* __result = + _S_destr_concat_char_iter(_M_tree_ptr, &__c, 1); + _S_unref(_M_tree_ptr); + _M_tree_ptr = __result; + return *this; + } + + rope& append() { return append(_CharT()); } // XXX why? + + rope& append(const rope& __y) { +# ifdef __STL_USE_STD_ALLOCATORS + __stl_assert(__y.get_allocator() == get_allocator()); +# endif + _RopeRep* __result = _S_concat(_M_tree_ptr, __y._M_tree_ptr); + _S_unref(_M_tree_ptr); + _M_tree_ptr = __result; + return *this; + } + + rope& append(size_t __n, _CharT __c) { + rope<_CharT,_Alloc> __last(__n, __c); + return append(__last); + } + + void swap(rope& __b) { +# ifdef __STL_USE_STD_ALLOCATORS + __stl_assert(get_allocator() == __b.get_allocator()); +# endif + _RopeRep* __tmp = _M_tree_ptr; + _M_tree_ptr = __b._M_tree_ptr; + __b._M_tree_ptr = __tmp; + } + + + protected: + // Result is included in refcount. + static _RopeRep* replace(_RopeRep* __old, size_t __pos1, + size_t __pos2, _RopeRep* __r) { + if (0 == __old) { _S_ref(__r); return __r; } + _Self_destruct_ptr __left( + _S_substring(__old, 0, __pos1)); + _Self_destruct_ptr __right( + _S_substring(__old, __pos2, __old->_M_size)); + _RopeRep* __result; + +# ifdef __STL_USE_STD_ALLOCATORS + __stl_assert(__old->get_allocator() == __r->get_allocator()); +# endif + if (0 == __r) { + __result = _S_concat(__left, __right); + } else { + _Self_destruct_ptr __left_result(_S_concat(__left, __r)); + __result = _S_concat(__left_result, __right); + } + return __result; + } + + public: + void insert(size_t __p, const rope& __r) { + _RopeRep* __result = + replace(_M_tree_ptr, __p, __p, __r._M_tree_ptr); +# ifdef __STL_USE_STD_ALLOCATORS + __stl_assert(get_allocator() == __r.get_allocator()); +# endif + _S_unref(_M_tree_ptr); + _M_tree_ptr = __result; + } + + void insert(size_t __p, size_t __n, _CharT __c) { + rope<_CharT,_Alloc> __r(__n,__c); + insert(__p, __r); + } + + void insert(size_t __p, const _CharT* __i, size_t __n) { + _Self_destruct_ptr __left(_S_substring(_M_tree_ptr, 0, __p)); + _Self_destruct_ptr __right(_S_substring(_M_tree_ptr, __p, size())); + _Self_destruct_ptr __left_result( + _S_concat_char_iter(__left, __i, __n)); + _RopeRep* __result = _S_concat(__left_result, __right); + _S_unref(_M_tree_ptr); + _M_tree_ptr = __result; + } + + void insert(size_t __p, const _CharT* __c_string) { + insert(__p, __c_string, _S_char_ptr_len(__c_string)); + } + + void insert(size_t __p, _CharT __c) { + insert(__p, &__c, 1); + } + + void insert(size_t __p) { + _CharT __c = _CharT(); + insert(__p, &__c, 1); + } + + void insert(size_t __p, const _CharT* __i, const _CharT* __j) { + rope __r(__i, __j); + insert(__p, __r); + } + + void insert(size_t __p, const const_iterator& __i, + const const_iterator& __j) { + rope __r(__i, __j); + insert(__p, __r); + } + + void insert(size_t __p, const iterator& __i, + const iterator& __j) { + rope __r(__i, __j); + insert(__p, __r); + } + + // (position, length) versions of replace operations: + + void replace(size_t __p, size_t __n, const rope& __r) { + _RopeRep* __result = + replace(_M_tree_ptr, __p, __p + __n, __r._M_tree_ptr); + _S_unref(_M_tree_ptr); + _M_tree_ptr = __result; + } + + void replace(size_t __p, size_t __n, + const _CharT* __i, size_t __i_len) { + rope __r(__i, __i_len); + replace(__p, __n, __r); + } + + void replace(size_t __p, size_t __n, _CharT __c) { + rope __r(__c); + replace(__p, __n, __r); + } + + void replace(size_t __p, size_t __n, const _CharT* __c_string) { + rope __r(__c_string); + replace(__p, __n, __r); + } + + void replace(size_t __p, size_t __n, + const _CharT* __i, const _CharT* __j) { + rope __r(__i, __j); + replace(__p, __n, __r); + } + + void replace(size_t __p, size_t __n, + const const_iterator& __i, const const_iterator& __j) { + rope __r(__i, __j); + replace(__p, __n, __r); + } + + void replace(size_t __p, size_t __n, + const iterator& __i, const iterator& __j) { + rope __r(__i, __j); + replace(__p, __n, __r); + } + + // Single character variants: + void replace(size_t __p, _CharT __c) { + iterator __i(this, __p); + *__i = __c; + } + + void replace(size_t __p, const rope& __r) { + replace(__p, 1, __r); + } + + void replace(size_t __p, const _CharT* __i, size_t __i_len) { + replace(__p, 1, __i, __i_len); + } + + void replace(size_t __p, const _CharT* __c_string) { + replace(__p, 1, __c_string); + } + + void replace(size_t __p, const _CharT* __i, const _CharT* __j) { + replace(__p, 1, __i, __j); + } + + void replace(size_t __p, const const_iterator& __i, + const const_iterator& __j) { + replace(__p, 1, __i, __j); + } + + void replace(size_t __p, const iterator& __i, + const iterator& __j) { + replace(__p, 1, __i, __j); + } + + // Erase, (position, size) variant. + void erase(size_t __p, size_t __n) { + _RopeRep* __result = replace(_M_tree_ptr, __p, __p + __n, 0); + _S_unref(_M_tree_ptr); + _M_tree_ptr = __result; + } + + // Erase, single character + void erase(size_t __p) { + erase(__p, __p + 1); + } + + // Insert, iterator variants. + iterator insert(const iterator& __p, const rope& __r) + { insert(__p.index(), __r); return __p; } + iterator insert(const iterator& __p, size_t __n, _CharT __c) + { insert(__p.index(), __n, __c); return __p; } + iterator insert(const iterator& __p, _CharT __c) + { insert(__p.index(), __c); return __p; } + iterator insert(const iterator& __p ) + { insert(__p.index()); return __p; } + iterator insert(const iterator& __p, const _CharT* c_string) + { insert(__p.index(), c_string); return __p; } + iterator insert(const iterator& __p, const _CharT* __i, size_t __n) + { insert(__p.index(), __i, __n); return __p; } + iterator insert(const iterator& __p, const _CharT* __i, + const _CharT* __j) + { insert(__p.index(), __i, __j); return __p; } + iterator insert(const iterator& __p, + const const_iterator& __i, const const_iterator& __j) + { insert(__p.index(), __i, __j); return __p; } + iterator insert(const iterator& __p, + const iterator& __i, const iterator& __j) + { insert(__p.index(), __i, __j); return __p; } + + // Replace, range variants. + void replace(const iterator& __p, const iterator& __q, + const rope& __r) + { replace(__p.index(), __q.index() - __p.index(), __r); } + void replace(const iterator& __p, const iterator& __q, _CharT __c) + { replace(__p.index(), __q.index() - __p.index(), __c); } + void replace(const iterator& __p, const iterator& __q, + const _CharT* __c_string) + { replace(__p.index(), __q.index() - __p.index(), __c_string); } + void replace(const iterator& __p, const iterator& __q, + const _CharT* __i, size_t __n) + { replace(__p.index(), __q.index() - __p.index(), __i, __n); } + void replace(const iterator& __p, const iterator& __q, + const _CharT* __i, const _CharT* __j) + { replace(__p.index(), __q.index() - __p.index(), __i, __j); } + void replace(const iterator& __p, const iterator& __q, + const const_iterator& __i, const const_iterator& __j) + { replace(__p.index(), __q.index() - __p.index(), __i, __j); } + void replace(const iterator& __p, const iterator& __q, + const iterator& __i, const iterator& __j) + { replace(__p.index(), __q.index() - __p.index(), __i, __j); } + + // Replace, iterator variants. + void replace(const iterator& __p, const rope& __r) + { replace(__p.index(), __r); } + void replace(const iterator& __p, _CharT __c) + { replace(__p.index(), __c); } + void replace(const iterator& __p, const _CharT* __c_string) + { replace(__p.index(), __c_string); } + void replace(const iterator& __p, const _CharT* __i, size_t __n) + { replace(__p.index(), __i, __n); } + void replace(const iterator& __p, const _CharT* __i, const _CharT* __j) + { replace(__p.index(), __i, __j); } + void replace(const iterator& __p, const_iterator __i, + const_iterator __j) + { replace(__p.index(), __i, __j); } + void replace(const iterator& __p, iterator __i, iterator __j) + { replace(__p.index(), __i, __j); } + + // Iterator and range variants of erase + iterator erase(const iterator& __p, const iterator& __q) { + size_t __p_index = __p.index(); + erase(__p_index, __q.index() - __p_index); + return iterator(this, __p_index); + } + iterator erase(const iterator& __p) { + size_t __p_index = __p.index(); + erase(__p_index, 1); + return iterator(this, __p_index); + } + + rope substr(size_t __start, size_t __len = 1) const { + return rope<_CharT,_Alloc>( + _S_substring(_M_tree_ptr, __start, __start + __len)); + } + + rope substr(iterator __start, iterator __end) const { + return rope<_CharT,_Alloc>( + _S_substring(_M_tree_ptr, __start.index(), __end.index())); + } + + rope substr(iterator __start) const { + size_t __pos = __start.index(); + return rope<_CharT,_Alloc>( + _S_substring(_M_tree_ptr, __pos, __pos + 1)); + } + + rope substr(const_iterator __start, const_iterator __end) const { + // This might eventually take advantage of the cache in the + // iterator. + return rope<_CharT,_Alloc>( + _S_substring(_M_tree_ptr, __start.index(), __end.index())); + } + + rope<_CharT,_Alloc> substr(const_iterator __start) { + size_t __pos = __start.index(); + return rope<_CharT,_Alloc>( + _S_substring(_M_tree_ptr, __pos, __pos + 1)); + } + + static const size_type npos; + + size_type find(_CharT __c, size_type __pos = 0) const; + size_type find(_CharT* __s, size_type __pos = 0) const { + size_type __result_pos; + const_iterator __result = search(const_begin() + __pos, const_end(), + __s, __s + _S_char_ptr_len(__s)); + __result_pos = __result.index(); +# ifndef __STL_OLD_ROPE_SEMANTICS + if (__result_pos == size()) __result_pos = npos; +# endif + return __result_pos; + } + + iterator mutable_begin() { + return(iterator(this, 0)); + } + + iterator mutable_end() { + return(iterator(this, size())); + } + +# ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + typedef reverse_iterator reverse_iterator; +# else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + typedef reverse_iterator reverse_iterator; +# endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + + reverse_iterator mutable_rbegin() { + return reverse_iterator(mutable_end()); + } + + reverse_iterator mutable_rend() { + return reverse_iterator(mutable_begin()); + } + + reference mutable_reference_at(size_type __pos) { + return reference(this, __pos); + } + +# ifdef __STD_STUFF + reference operator[] (size_type __pos) { + return _char_ref_proxy(this, __pos); + } + + reference at(size_type __pos) { + // if (__pos >= size()) throw out_of_range; // XXX + return (*this)[__pos]; + } + + void resize(size_type __n, _CharT __c) {} + void resize(size_type __n) {} + void reserve(size_type __res_arg = 0) {} + size_type capacity() const { + return max_size(); + } + + // Stuff below this line is dangerous because it's error prone. + // I would really like to get rid of it. + // copy function with funny arg ordering. + size_type copy(_CharT* __buffer, size_type __n, + size_type __pos = 0) const { + return copy(__pos, __n, __buffer); + } + + iterator end() { return mutable_end(); } + + iterator begin() { return mutable_begin(); } + + reverse_iterator rend() { return mutable_rend(); } + + reverse_iterator rbegin() { return mutable_rbegin(); } + +# else + + const_iterator end() { return const_end(); } + + const_iterator begin() { return const_begin(); } + + const_reverse_iterator rend() { return const_rend(); } + + const_reverse_iterator rbegin() { return const_rbegin(); } + +# endif + +}; + +template +const rope<_CharT, _Alloc>::size_type rope<_CharT, _Alloc>::npos = + (size_type)(-1); + +template +inline bool operator== (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y) { + return (__x._M_current_pos == __y._M_current_pos && + __x._M_root == __y._M_root); +} + +template +inline bool operator< (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y) { + return (__x._M_current_pos < __y._M_current_pos); +} + +template +inline ptrdiff_t operator-(const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y) { + return (ptrdiff_t)__x._M_current_pos - (ptrdiff_t)__y._M_current_pos; +} + +template +inline _Rope_const_iterator<_CharT,_Alloc> +operator-(const _Rope_const_iterator<_CharT,_Alloc>& __x, ptrdiff_t __n) { + return _Rope_const_iterator<_CharT,_Alloc>( + __x._M_root, __x._M_current_pos - __n); +} + +template +inline _Rope_const_iterator<_CharT,_Alloc> +operator+(const _Rope_const_iterator<_CharT,_Alloc>& __x, ptrdiff_t __n) { + return _Rope_const_iterator<_CharT,_Alloc>( + __x._M_root, __x._M_current_pos + __n); +} + +template +inline _Rope_const_iterator<_CharT,_Alloc> +operator+(ptrdiff_t __n, const _Rope_const_iterator<_CharT,_Alloc>& __x) { + return _Rope_const_iterator<_CharT,_Alloc>( + __x._M_root, __x._M_current_pos + __n); +} + +template +inline bool operator== (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y) { + return (__x._M_current_pos == __y._M_current_pos && + __x._M_root_rope == __y._M_root_rope); +} + +template +inline bool operator< (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y) { + return (__x._M_current_pos < __y._M_current_pos); +} + +template +inline ptrdiff_t operator-(const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y) { + return (ptrdiff_t)__x._M_current_pos - (ptrdiff_t)__y._M_current_pos; +} + +template +inline _Rope_iterator<_CharT,_Alloc> +operator-(const _Rope_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n) { + return _Rope_iterator<_CharT,_Alloc>( + __x._M_root_rope, __x._M_current_pos - __n); +} + +template +inline _Rope_iterator<_CharT,_Alloc> +operator+(const _Rope_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n) { + return _Rope_iterator<_CharT,_Alloc>( + __x._M_root_rope, __x._M_current_pos + __n); +} + +template +inline _Rope_iterator<_CharT,_Alloc> +operator+(ptrdiff_t __n, const _Rope_iterator<_CharT,_Alloc>& __x) { + return _Rope_iterator<_CharT,_Alloc>( + __x._M_root_rope, __x._M_current_pos + __n); +} + +template +inline +rope<_CharT,_Alloc> +operator+ (const rope<_CharT,_Alloc>& __left, + const rope<_CharT,_Alloc>& __right) +{ +# ifdef __STL_USE_STD_ALLOCATORS + __stl_assert(__left.get_allocator() == __right.get_allocator()); +# endif + return rope<_CharT,_Alloc>( + rope<_CharT,_Alloc>::_S_concat(__left._M_tree_ptr, __right._M_tree_ptr)); + // Inlining this should make it possible to keep __left and + // __right in registers. +} + +template +inline +rope<_CharT,_Alloc>& +operator+= (rope<_CharT,_Alloc>& __left, + const rope<_CharT,_Alloc>& __right) +{ + __left.append(__right); + return __left; +} + +template +inline +rope<_CharT,_Alloc> +operator+ (const rope<_CharT,_Alloc>& __left, + const _CharT* __right) { + size_t __rlen = rope<_CharT,_Alloc>::_S_char_ptr_len(__right); + return rope<_CharT,_Alloc>( + rope<_CharT,_Alloc>::_S_concat_char_iter( + __left._M_tree_ptr, __right, __rlen)); +} + +template +inline +rope<_CharT,_Alloc>& +operator+= (rope<_CharT,_Alloc>& __left, + const _CharT* __right) { + __left.append(__right); + return __left; +} + +template +inline +rope<_CharT,_Alloc> +operator+ (const rope<_CharT,_Alloc>& __left, _CharT __right) { + return rope<_CharT,_Alloc>( + rope<_CharT,_Alloc>::_S_concat_char_iter( + __left._M_tree_ptr, &__right, 1)); +} + +template +inline +rope<_CharT,_Alloc>& +operator+= (rope<_CharT,_Alloc>& __left, _CharT __right) { + __left.append(__right); + return __left; +} + +template +bool +operator< (const rope<_CharT,_Alloc>& __left, + const rope<_CharT,_Alloc>& __right) { + return __left.compare(__right) < 0; +} + +template +bool +operator== (const rope<_CharT,_Alloc>& __left, + const rope<_CharT,_Alloc>& __right) { + return __left.compare(__right) == 0; +} + +template +inline bool operator== (const _Rope_char_ptr_proxy<_CharT,_Alloc>& __x, + const _Rope_char_ptr_proxy<_CharT,_Alloc>& __y) { + return (__x._M_pos == __y._M_pos && __x._M_root == __y._M_root); +} + +template +ostream& operator<< (ostream& __o, const rope<_CharT,_Alloc>& __r); + +typedef rope crope; +typedef rope wrope; + +inline crope::reference __mutable_reference_at(crope& __c, size_t __i) +{ + return __c.mutable_reference_at(__i); +} + +inline wrope::reference __mutable_reference_at(wrope& __c, size_t __i) +{ + return __c.mutable_reference_at(__i); +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline void swap(rope<_CharT,_Alloc>& __x, rope<_CharT,_Alloc>& __y) { + __x.swap(__y); +} + +#else + +inline void swap(crope __x, crope __y) { __x.swap(__y); } +inline void swap(wrope __x, wrope __y) { __x.swap(__y); } + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +// Hash functions should probably be revisited later: +__STL_TEMPLATE_NULL struct hash +{ + size_t operator()(const crope& __str) const + { + size_t __size = __str.size(); + + if (0 == __size) return 0; + return 13*__str[0] + 5*__str[__size - 1] + __size; + } +}; + + +__STL_TEMPLATE_NULL struct hash +{ + size_t operator()(const wrope& __str) const + { + size_t __size = __str.size(); + + if (0 == __size) return 0; + return 13*__str[0] + 5*__str[__size - 1] + __size; + } +}; + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#endif + +__STL_END_NAMESPACE + +# include + +# endif /* __SGI_STL_INTERNAL_ROPE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/stl_set.h b/headers/cpp/stl_set.h new file mode 100644 index 0000000000..003069cb07 --- /dev/null +++ b/headers/cpp/stl_set.h @@ -0,0 +1,216 @@ +/* + * + * 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,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. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_SET_H +#define __SGI_STL_INTERNAL_SET_H + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1174 +#pragma set woff 1375 +#endif + +#ifndef __STL_LIMITED_DEFAULT_TEMPLATES +template , + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Key) > +#else +template +#endif +class set { +public: + // typedefs: + + typedef _Key key_type; + typedef _Key value_type; + typedef _Compare key_compare; + typedef _Compare value_compare; +private: + typedef _Rb_tree, key_compare, _Alloc> _Rep_type; + _Rep_type _M_t; // red-black tree representing set +public: + typedef typename _Rep_type::const_pointer pointer; + typedef typename _Rep_type::const_pointer const_pointer; + typedef typename _Rep_type::const_reference reference; + typedef typename _Rep_type::const_reference const_reference; + typedef typename _Rep_type::const_iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::const_reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + typedef typename _Rep_type::allocator_type allocator_type; + + // allocation/deallocation + + set() : _M_t(_Compare(), allocator_type()) {} + explicit set(const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) {} + +#ifdef __STL_MEMBER_TEMPLATES + template + set(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_unique(__first, __last); } + + template + set(_InputIterator __first, _InputIterator __last, const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); } +#else + set(const value_type* __first, const value_type* __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_unique(__first, __last); } + + set(const value_type* __first, + const value_type* __last, const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); } + + set(const_iterator __first, const_iterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_unique(__first, __last); } + + set(const_iterator __first, const_iterator __last, const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); } +#endif /* __STL_MEMBER_TEMPLATES */ + + set(const set<_Key,_Compare,_Alloc>& __x) : _M_t(__x._M_t) {} + set<_Key,_Compare,_Alloc>& operator=(const set<_Key, _Compare, _Alloc>& __x) + { + _M_t = __x._M_t; + return *this; + } + + // accessors: + + key_compare key_comp() const { return _M_t.key_comp(); } + value_compare value_comp() const { return _M_t.key_comp(); } + allocator_type get_allocator() const { return _M_t.get_allocator(); } + + iterator begin() const { return _M_t.begin(); } + iterator end() const { return _M_t.end(); } + reverse_iterator rbegin() const { return _M_t.rbegin(); } + reverse_iterator rend() const { return _M_t.rend(); } + bool empty() const { return _M_t.empty(); } + size_type size() const { return _M_t.size(); } + size_type max_size() const { return _M_t.max_size(); } + void swap(set<_Key,_Compare,_Alloc>& __x) { _M_t.swap(__x._M_t); } + + // insert/erase + pair insert(const value_type& __x) { + pair __p = _M_t.insert_unique(__x); + return pair(__p.first, __p.second); + } + iterator insert(iterator __position, const value_type& __x) { + typedef typename _Rep_type::iterator _Rep_iterator; + return _M_t.insert_unique((_Rep_iterator&)__position, __x); + } +#ifdef __STL_MEMBER_TEMPLATES + template + void insert(_InputIterator __first, _InputIterator __last) { + _M_t.insert_unique(__first, __last); + } +#else + void insert(const_iterator __first, const_iterator __last) { + _M_t.insert_unique(__first, __last); + } + void insert(const value_type* __first, const value_type* __last) { + _M_t.insert_unique(__first, __last); + } +#endif /* __STL_MEMBER_TEMPLATES */ + void erase(iterator __position) { + typedef typename _Rep_type::iterator _Rep_iterator; + _M_t.erase((_Rep_iterator&)__position); + } + size_type erase(const key_type& __x) { + return _M_t.erase(__x); + } + void erase(iterator __first, iterator __last) { + typedef typename _Rep_type::iterator _Rep_iterator; + _M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last); + } + void clear() { _M_t.clear(); } + + // set operations: + + iterator find(const key_type& __x) const { return _M_t.find(__x); } + size_type count(const key_type& __x) const { return _M_t.count(__x); } + iterator lower_bound(const key_type& __x) const { + return _M_t.lower_bound(__x); + } + iterator upper_bound(const key_type& __x) const { + return _M_t.upper_bound(__x); + } + pair equal_range(const key_type& __x) const { + return _M_t.equal_range(__x); + } + friend bool operator== __STL_NULL_TMPL_ARGS (const set&, const set&); + friend bool operator< __STL_NULL_TMPL_ARGS (const set&, const set&); +}; + +template +inline bool operator==(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y) { + return __x._M_t == __y._M_t; +} + +template +inline bool operator<(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y) { + return __x._M_t < __y._M_t; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline void swap(set<_Key,_Compare,_Alloc>& __x, + set<_Key,_Compare,_Alloc>& __y) { + __x.swap(__y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#pragma reset woff 1375 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_SET_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/stl_slist.h b/headers/cpp/stl_slist.h new file mode 100644 index 0000000000..6da234d92c --- /dev/null +++ b/headers/cpp/stl_slist.h @@ -0,0 +1,945 @@ +/* + * 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. + * + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_SLIST_H +#define __SGI_STL_INTERNAL_SLIST_H + + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1174 +#pragma set woff 1375 +#endif + +struct _Slist_node_base +{ + _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 _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 +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 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 +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; } +#ifndef __SGI_STL_NO_ARROW_OPERATOR + pointer operator->() const { return &(operator*()); } +#endif /* __SGI_STL_NO_ARROW_OPERATOR */ + + _Self& operator++() + { + _M_incr(); + return *this; + } + _Self operator++(int) + { + _Self __tmp = *this; + _M_incr(); + return __tmp; + } +}; + +#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION + +inline ptrdiff_t* distance_type(const _Slist_iterator_base&) { + return 0; +} + +inline forward_iterator_tag iterator_category(const _Slist_iterator_base&) { + return forward_iterator_tag(); +} + +template +inline _Tp* value_type(const _Slist_iterator<_Tp, _Ref, _Ptr>&) { + return 0; +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +// Base class that encapsulates details of allocators. Three cases: +// an ordinary standard-conforming allocator, a standard-conforming +// allocator with no non-static data, and an SGI-style allocator. +// This complexity is necessary only because we're worrying about backward +// compatibility and because we want to avoid wasting storage on an +// allocator instance if it isn't necessary. + +#ifdef __STL_USE_STD_ALLOCATORS + +// Base for general standard-conforming allocators. +template +class _Slist_alloc_base { +public: + typedef typename _Alloc_traits<_Tp,_Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return _M_node_allocator; } + + _Slist_alloc_base(const allocator_type& __a) : _M_node_allocator(__a) {} + +protected: + _Slist_node<_Tp>* _M_get_node() + { return _M_node_allocator.allocate(1); } + void _M_put_node(_Slist_node<_Tp>* __p) + { _M_node_allocator.deallocate(__p, 1); } + +protected: + typename _Alloc_traits<_Slist_node<_Tp>,_Allocator>::allocator_type + _M_node_allocator; + _Slist_node_base _M_head; +}; + +// Specialization for instanceless allocators. +template +class _Slist_alloc_base<_Tp,_Allocator, true> { +public: + typedef typename _Alloc_traits<_Tp,_Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Slist_alloc_base(const allocator_type&) {} + +protected: + typedef typename _Alloc_traits<_Slist_node<_Tp>, _Allocator>::_Alloc_type + _Alloc_type; + _Slist_node<_Tp>* _M_get_node() { return _Alloc_type::allocate(1); } + void _M_put_node(_Slist_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); } + +protected: + _Slist_node_base _M_head; +}; + + +template +struct _Slist_base + : public _Slist_alloc_base<_Tp, _Alloc, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> +{ + typedef _Slist_alloc_base<_Tp, _Alloc, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> + _Base; + typedef typename _Base::allocator_type allocator_type; + + _Slist_base(const allocator_type& __a) : _Base(__a) { _M_head._M_next = 0; } + ~_Slist_base() { _M_erase_after(&_M_head, 0); } + +protected: + + _Slist_node_base* _M_erase_after(_Slist_node_base* __pos) + { + _Slist_node<_Tp>* __next = (_Slist_node<_Tp>*) (__pos->_M_next); + _Slist_node_base* __next_next = __next->_M_next; + __pos->_M_next = __next_next; + destroy(&__next->_M_data); + _M_put_node(__next); + return __next_next; + } + _Slist_node_base* _M_erase_after(_Slist_node_base*, _Slist_node_base*); +}; + +#else /* __STL_USE_STD_ALLOCATORS */ + +template +struct _Slist_base { + typedef _Alloc allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Slist_base(const allocator_type&) { _M_head._M_next = 0; } + ~_Slist_base() { _M_erase_after(&_M_head, 0); } + +protected: + typedef simple_alloc<_Slist_node<_Tp>, _Alloc> _Alloc_type; + _Slist_node<_Tp>* _M_get_node() { return _Alloc_type::allocate(1); } + void _M_put_node(_Slist_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); } + + _Slist_node_base* _M_erase_after(_Slist_node_base* __pos) + { + _Slist_node<_Tp>* __next = (_Slist_node<_Tp>*) (__pos->_M_next); + _Slist_node_base* __next_next = __next->_M_next; + __pos->_M_next = __next_next; + destroy(&__next->_M_data); + _M_put_node(__next); + return __next_next; + } + _Slist_node_base* _M_erase_after(_Slist_node_base*, _Slist_node_base*); + +protected: + _Slist_node_base _M_head; +}; + +#endif /* __STL_USE_STD_ALLOCATORS */ + +template +_Slist_node_base* +_Slist_base<_Tp,_Alloc>::_M_erase_after(_Slist_node_base* __before_first, + _Slist_node_base* __last_node) { + _Slist_node<_Tp>* __cur = (_Slist_node<_Tp>*) (__before_first->_M_next); + while (__cur != __last_node) { + _Slist_node<_Tp>* __tmp = __cur; + __cur = (_Slist_node<_Tp>*) __cur->_M_next; + destroy(&__tmp->_M_data); + _M_put_node(__tmp); + } + __before_first->_M_next = __last_node; + return __last_node; +} + +template +class slist : private _Slist_base<_Tp,_Alloc> +{ +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 = _M_get_node(); + __STL_TRY { + construct(&__node->_M_data, __x); + __node->_M_next = 0; + } + __STL_UNWIND(_M_put_node(__node)); + return __node; + } + + _Node* _M_create_node() { + _Node* __node = _M_get_node(); + __STL_TRY { + construct(&__node->_M_data); + __node->_M_next = 0; + } + __STL_UNWIND(_M_put_node(__node)); + return __node; + } + +private: +#ifdef __STL_USE_NAMESPACES + using _Base::_M_get_node; + using _Base::_M_put_node; + using _Base::_M_erase_after; + using _Base::_M_head; +#endif /* __STL_USE_NAMESPACES */ + +public: + explicit slist(const allocator_type& __a = allocator_type()) : _Base(__a) {} + + slist(size_type __n, const value_type& __x, + const allocator_type& __a = allocator_type()) : _Base(__a) + { _M_insert_after_fill(&_M_head, __n, __x); } + + explicit slist(size_type __n) : _Base(allocator_type()) + { _M_insert_after_fill(&_M_head, __n, value_type()); } + +#ifdef __STL_MEMBER_TEMPLATES + // We don't need any dispatching tricks here, because _M_insert_after_range + // already does them. + template + slist(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) : _Base(__a) + { _M_insert_after_range(&_M_head, __first, __last); } + +#else /* __STL_MEMBER_TEMPLATES */ + slist(const_iterator __first, const_iterator __last, + const allocator_type& __a = allocator_type()) : _Base(__a) + { _M_insert_after_range(&_M_head, __first, __last); } + slist(const value_type* __first, const value_type* __last, + const allocator_type& __a = allocator_type()) : _Base(__a) + { _M_insert_after_range(&_M_head, __first, __last); } +#endif /* __STL_MEMBER_TEMPLATES */ + + slist(const slist& __x) : _Base(__x.get_allocator()) + { _M_insert_after_range(&_M_head, __x.begin(), __x.end()); } + + slist& operator= (const slist& __x); + + ~slist() {} + +public: + // assign(), a generalized assignment member function. Two + // versions: one that takes a count, and one that takes a range. + // The range version is a member template, so we dispatch on whether + // or not the type is an integer. + + void assign(size_type __n, const _Tp& __val); + +#ifdef __STL_MEMBER_TEMPLATES + + template + void assign(_InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } + + template + void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { assign((size_type) __n, (_Tp) __val); } + + template + void _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type); + +#endif /* __STL_MEMBER_TEMPLATES */ + +public: + + iterator begin() { return iterator((_Node*)_M_head._M_next); } + const_iterator begin() const + { return const_iterator((_Node*)_M_head._M_next);} + + iterator end() { return iterator(0); } + const_iterator end() const { return const_iterator(0); } + + size_type size() const { return __slist_size(_M_head._M_next); } + + size_type max_size() const { return size_type(-1); } + + bool empty() const { return _M_head._M_next == 0; } + + void swap(slist& __x) { __STD::swap(_M_head._M_next, __x._M_head._M_next); } + +public: + friend bool operator== __STL_NULL_TMPL_ARGS (const slist<_Tp,_Alloc>& _SL1, + const slist<_Tp,_Alloc>& _SL2); + +public: + + reference front() { return ((_Node*) _M_head._M_next)->_M_data; } + const_reference front() const + { return ((_Node*) _M_head._M_next)->_M_data; } + void push_front(const value_type& __x) { + __slist_make_link(&_M_head, _M_create_node(__x)); + } + void push_front() { __slist_make_link(&_M_head, _M_create_node());} + void pop_front() { + _Node* __node = (_Node*) _M_head._M_next; + _M_head._M_next = __node->_M_next; + destroy(&__node->_M_data); + _M_put_node(__node); + } + + iterator previous(const_iterator __pos) { + return iterator((_Node*) __slist_previous(&_M_head, __pos._M_node)); + } + const_iterator previous(const_iterator __pos) const { + return const_iterator((_Node*) __slist_previous(&_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)); + } + +#ifdef __STL_MEMBER_TEMPLATES + + // Check whether it's an integral type. If so, it's not an iterator. + template + void _M_insert_after_range(_Node_base* __pos, + _InIter __first, _InIter __last) { + typedef typename _Is_integer<_InIter>::_Integral _Integral; + _M_insert_after_range(__pos, __first, __last, _Integral()); + } + + template + void _M_insert_after_range(_Node_base* __pos, _Integer __n, _Integer __x, + __true_type) { + _M_insert_after_fill(__pos, __n, __x); + } + + template + void _M_insert_after_range(_Node_base* __pos, + _InIter __first, _InIter __last, + __false_type) { + while (__first != __last) { + __pos = __slist_make_link(__pos, _M_create_node(*__first)); + ++__first; + } + } + +#else /* __STL_MEMBER_TEMPLATES */ + + void _M_insert_after_range(_Node_base* __pos, + const_iterator __first, const_iterator __last) { + while (__first != __last) { + __pos = __slist_make_link(__pos, _M_create_node(*__first)); + ++__first; + } + } + void _M_insert_after_range(_Node_base* __pos, + const value_type* __first, + const value_type* __last) { + while (__first != __last) { + __pos = __slist_make_link(__pos, _M_create_node(*__first)); + ++__first; + } + } + +#endif /* __STL_MEMBER_TEMPLATES */ + +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); + } + +#ifdef __STL_MEMBER_TEMPLATES + + // We don't need any dispatching tricks here, because _M_insert_after_range + // already does them. + template + void insert_after(iterator __pos, _InIter __first, _InIter __last) { + _M_insert_after_range(__pos._M_node, __first, __last); + } + +#else /* __STL_MEMBER_TEMPLATES */ + + void insert_after(iterator __pos, + const_iterator __first, const_iterator __last) { + _M_insert_after_range(__pos._M_node, __first, __last); + } + void insert_after(iterator __pos, + const value_type* __first, const value_type* __last) { + _M_insert_after_range(__pos._M_node, __first, __last); + } + +#endif /* __STL_MEMBER_TEMPLATES */ + + iterator insert(iterator __pos, const value_type& __x) { + return iterator(_M_insert_after(__slist_previous(&_M_head, __pos._M_node), + __x)); + } + + iterator insert(iterator __pos) { + return iterator(_M_insert_after(__slist_previous(&_M_head, __pos._M_node), + value_type())); + } + + void insert(iterator __pos, size_type __n, const value_type& __x) { + _M_insert_after_fill(__slist_previous(&_M_head, __pos._M_node), __n, __x); + } + +#ifdef __STL_MEMBER_TEMPLATES + + // We don't need any dispatching tricks here, because _M_insert_after_range + // already does them. + template + void insert(iterator __pos, _InIter __first, _InIter __last) { + _M_insert_after_range(__slist_previous(&_M_head, __pos._M_node), + __first, __last); + } + +#else /* __STL_MEMBER_TEMPLATES */ + + void insert(iterator __pos, const_iterator __first, const_iterator __last) { + _M_insert_after_range(__slist_previous(&_M_head, __pos._M_node), + __first, __last); + } + void insert(iterator __pos, const value_type* __first, + const value_type* __last) { + _M_insert_after_range(__slist_previous(&_M_head, __pos._M_node), + __first, __last); + } + +#endif /* __STL_MEMBER_TEMPLATES */ + + +public: + iterator erase_after(iterator __pos) { + return iterator((_Node*) _M_erase_after(__pos._M_node)); + } + iterator erase_after(iterator __before_first, iterator __last) { + return iterator((_Node*) _M_erase_after(__before_first._M_node, + __last._M_node)); + } + + iterator erase(iterator __pos) { + return (_Node*) _M_erase_after(__slist_previous(&_M_head, + __pos._M_node)); + } + iterator erase(iterator __first, iterator __last) { + return (_Node*) _M_erase_after( + __slist_previous(&_M_head, __first._M_node), __last._M_node); + } + + void resize(size_type new_size, const _Tp& __x); + void resize(size_type new_size) { resize(new_size, _Tp()); } + void clear() { _M_erase_after(&_M_head, 0); } + +public: + // Moves the range [__before_first + 1, __before_last + 1) to *this, + // inserting it immediately after __pos. This is constant time. + void splice_after(iterator __pos, + iterator __before_first, iterator __before_last) + { + 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); + } + + + // Linear in distance(begin(), __pos), and linear in __x.size(). + void splice(iterator __pos, slist& __x) { + if (__x._M_head._M_next) + __slist_splice_after(__slist_previous(&_M_head, __pos._M_node), + &__x._M_head, __slist_previous(&__x._M_head, 0)); + } + + // Linear in distance(begin(), __pos), and in distance(__x.begin(), __i). + void splice(iterator __pos, slist& __x, iterator __i) { + __slist_splice_after(__slist_previous(&_M_head, __pos._M_node), + __slist_previous(&__x._M_head, __i._M_node), + __i._M_node); + } + + // Linear in distance(begin(), __pos), in distance(__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(&_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 (_M_head._M_next) + _M_head._M_next = __slist_reverse(_M_head._M_next); + } + + void remove(const _Tp& __val); + void unique(); + void merge(slist& __x); + void sort(); + +#ifdef __STL_MEMBER_TEMPLATES + template + void remove_if(_Predicate __pred); + + template + void unique(_BinaryPredicate __pred); + + template + void merge(slist&, _StrictWeakOrdering); + + template + void sort(_StrictWeakOrdering __comp); +#endif /* __STL_MEMBER_TEMPLATES */ +}; + +template +slist<_Tp,_Alloc>& slist<_Tp,_Alloc>::operator=(const slist<_Tp,_Alloc>& __x) +{ + if (&__x != this) { + _Node_base* __p1 = &_M_head; + _Node* __n1 = (_Node*) _M_head._M_next; + const _Node* __n2 = (const _Node*) __x._M_head._M_next; + while (__n1 && __n2) { + __n1->_M_data = __n2->_M_data; + __p1 = __n1; + __n1 = (_Node*) __n1->_M_next; + __n2 = (const _Node*) __n2->_M_next; + } + if (__n2 == 0) + _M_erase_after(__p1, 0); + else + _M_insert_after_range(__p1, const_iterator((_Node*)__n2), + const_iterator(0)); + } + return *this; +} + +template +void slist<_Tp, _Alloc>::assign(size_type __n, const _Tp& __val) { + _Node_base* __prev = &_M_head; + _Node* __node = (_Node*) _M_head._M_next; + for ( ; __node != 0 && __n > 0 ; --__n) { + __node->_M_data = __val; + __prev = __node; + __node = (_Node*) __node->_M_next; + } + if (__n > 0) + _M_insert_after_fill(__prev, __n, __val); + else + _M_erase_after(__prev, 0); +} + +#ifdef __STL_MEMBER_TEMPLATES + +template template +void +slist<_Tp, _Alloc>::_M_assign_dispatch(_InputIter __first, _InputIter __last, + __false_type) +{ + _Node_base* __prev = &_M_head; + _Node* __node = (_Node*) _M_head._M_next; + while (__node != 0 && __first != __last) { + __node->_M_data = *__first; + __prev = __node; + __node = (_Node*) __node->_M_next; + ++__first; + } + if (__first != __last) + _M_insert_after_range(__prev, __first, __last); + else + _M_erase_after(__prev, 0); +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +template +inline bool +operator==(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) +{ + typedef typename slist<_Tp,_Alloc>::_Node _Node; + _Node* __n1 = (_Node*) _SL1._M_head._M_next; + _Node* __n2 = (_Node*) _SL2._M_head._M_next; + while (__n1 && __n2 && __n1->_M_data == __n2->_M_data) { + __n1 = (_Node*) __n1->_M_next; + __n2 = (_Node*) __n2->_M_next; + } + return __n1 == 0 && __n2 == 0; +} + +template +inline bool operator<(const slist<_Tp,_Alloc>& _SL1, + const slist<_Tp,_Alloc>& _SL2) +{ + return lexicographical_compare(_SL1.begin(), _SL1.end(), + _SL2.begin(), _SL2.end()); +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline void swap(slist<_Tp,_Alloc>& __x, slist<_Tp,_Alloc>& __y) { + __x.swap(__y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + + +template +void slist<_Tp,_Alloc>::resize(size_type __len, const _Tp& __x) +{ + _Node_base* __cur = &_M_head; + while (__cur->_M_next != 0 && __len > 0) { + --__len; + __cur = __cur->_M_next; + } + if (__cur->_M_next) + _M_erase_after(__cur, 0); + else + _M_insert_after_fill(__cur, __len, __x); +} + +template +void slist<_Tp,_Alloc>::remove(const _Tp& __val) +{ + _Node_base* __cur = &_M_head; + while (__cur && __cur->_M_next) { + if (((_Node*) __cur->_M_next)->_M_data == __val) + _M_erase_after(__cur); + else + __cur = __cur->_M_next; + } +} + +template +void slist<_Tp,_Alloc>::unique() +{ + _Node_base* __cur = _M_head._M_next; + if (__cur) { + while (__cur->_M_next) { + if (((_Node*)__cur)->_M_data == + ((_Node*)(__cur->_M_next))->_M_data) + _M_erase_after(__cur); + else + __cur = __cur->_M_next; + } + } +} + +template +void slist<_Tp,_Alloc>::merge(slist<_Tp,_Alloc>& __x) +{ + _Node_base* __n1 = &_M_head; + while (__n1->_M_next && __x._M_head._M_next) { + if (((_Node*) __x._M_head._M_next)->_M_data < + ((_Node*) __n1->_M_next)->_M_data) + __slist_splice_after(__n1, &__x._M_head, __x._M_head._M_next); + __n1 = __n1->_M_next; + } + if (__x._M_head._M_next) { + __n1->_M_next = __x._M_head._M_next; + __x._M_head._M_next = 0; + } +} + +template +void slist<_Tp,_Alloc>::sort() +{ + if (_M_head._M_next && _M_head._M_next->_M_next) { + slist __carry; + slist __counter[64]; + int __fill = 0; + while (!empty()) { + __slist_splice_after(&__carry._M_head, &_M_head, _M_head._M_next); + int __i = 0; + while (__i < __fill && !__counter[__i].empty()) { + __counter[__i].merge(__carry); + __carry.swap(__counter[__i]); + ++__i; + } + __carry.swap(__counter[__i]); + if (__i == __fill) + ++__fill; + } + + for (int __i = 1; __i < __fill; ++__i) + __counter[__i].merge(__counter[__i-1]); + this->swap(__counter[__fill-1]); + } +} + +#ifdef __STL_MEMBER_TEMPLATES + +template +template +void slist<_Tp,_Alloc>::remove_if(_Predicate __pred) +{ + _Node_base* __cur = &_M_head; + while (__cur->_M_next) { + if (__pred(((_Node*) __cur->_M_next)->_M_data)) + _M_erase_after(__cur); + else + __cur = __cur->_M_next; + } +} + +template template +void slist<_Tp,_Alloc>::unique(_BinaryPredicate __pred) +{ + _Node* __cur = (_Node*) _M_head._M_next; + if (__cur) { + while (__cur->_M_next) { + if (__pred(((_Node*)__cur)->_M_data, + ((_Node*)(__cur->_M_next))->_M_data)) + _M_erase_after(__cur); + else + __cur = (_Node*) __cur->_M_next; + } + } +} + +template template +void slist<_Tp,_Alloc>::merge(slist<_Tp,_Alloc>& __x, + _StrictWeakOrdering __comp) +{ + _Node_base* __n1 = &_M_head; + while (__n1->_M_next && __x._M_head._M_next) { + if (__comp(((_Node*) __x._M_head._M_next)->_M_data, + ((_Node*) __n1->_M_next)->_M_data)) + __slist_splice_after(__n1, &__x._M_head, __x._M_head._M_next); + __n1 = __n1->_M_next; + } + if (__x._M_head._M_next) { + __n1->_M_next = __x._M_head._M_next; + __x._M_head._M_next = 0; + } +} + +template template +void slist<_Tp,_Alloc>::sort(_StrictWeakOrdering __comp) +{ + if (_M_head._M_next && _M_head._M_next->_M_next) { + slist __carry; + slist __counter[64]; + int __fill = 0; + while (!empty()) { + __slist_splice_after(&__carry._M_head, &_M_head, _M_head._M_next); + int __i = 0; + while (__i < __fill && !__counter[__i].empty()) { + __counter[__i].merge(__carry, __comp); + __carry.swap(__counter[__i]); + ++__i; + } + __carry.swap(__counter[__i]); + if (__i == __fill) + ++__fill; + } + + for (int __i = 1; __i < __fill; ++__i) + __counter[__i].merge(__counter[__i-1], __comp); + this->swap(__counter[__fill-1]); + } +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#pragma reset woff 1375 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_SLIST_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/stl_stack.h b/headers/cpp/stl_stack.h new file mode 100644 index 0000000000..2a04b21e50 --- /dev/null +++ b/headers/cpp/stl_stack.h @@ -0,0 +1,111 @@ +/* + * + * 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,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. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_STACK_H +#define __SGI_STL_INTERNAL_STACK_H + +__STL_BEGIN_NAMESPACE + +#ifndef __STL_LIMITED_DEFAULT_TEMPLATES +template > +#else +template +#endif +class stack { + friend bool operator== __STL_NULL_TMPL_ARGS (const stack&, const stack&); + friend bool operator< __STL_NULL_TMPL_ARGS (const stack&, const stack&); +public: + typedef typename _Sequence::value_type value_type; + typedef typename _Sequence::size_type size_type; + typedef _Sequence container_type; + + typedef typename _Sequence::reference reference; + typedef typename _Sequence::const_reference const_reference; +protected: + _Sequence _M_c; +public: + stack() : _M_c() {} + explicit stack(const _Sequence& __s) : _M_c(__s) {} + + bool empty() const { return _M_c.empty(); } + size_type size() const { return _M_c.size(); } + reference top() { return _M_c.back(); } + const_reference top() const { return _M_c.back(); } + void push(const value_type& __x) { _M_c.push_back(__x); } + void pop() { _M_c.pop_back(); } +}; + +template +bool operator==(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) +{ + return __x._M_c == __y._M_c; +} + +template +bool operator<(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) +{ + return __x._M_c < __y._M_c; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +bool operator!=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) +{ + return !(__x == __y); +} + +template +bool operator>(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) +{ + return __y < __x; +} + +template +bool operator<=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) +{ + return !(__y < __x); +} + +template +bool operator>=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) +{ + return !(__x < __y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_STACK_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/stl_tempbuf.h b/headers/cpp/stl_tempbuf.h new file mode 100644 index 0000000000..e1b2eadafc --- /dev/null +++ b/headers/cpp/stl_tempbuf.h @@ -0,0 +1,156 @@ +/* + * + * 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,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. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_TEMPBUF_H +#define __SGI_STL_INTERNAL_TEMPBUF_H + + +__STL_BEGIN_NAMESPACE + +template +pair<_Tp*, ptrdiff_t> +__get_temporary_buffer(ptrdiff_t __len, _Tp*) +{ + if (__len > ptrdiff_t(INT_MAX / sizeof(_Tp))) + __len = INT_MAX / sizeof(_Tp); + + while (__len > 0) { + _Tp* __tmp = (_Tp*) malloc((size_t)__len * sizeof(_Tp)); + if (__tmp != 0) + return pair<_Tp*, ptrdiff_t>(__tmp, __len); + __len /= 2; + } + + return pair<_Tp*, ptrdiff_t>((_Tp*)0, 0); +} + +#ifdef __STL_EXPLICIT_FUNCTION_TMPL_ARGS + +template +inline pair<_Tp*, ptrdiff_t> get_temporary_buffer(ptrdiff_t __len) { + return __get_temporary_buffer(__len, (_Tp*) 0); +} + +#endif /* __STL_EXPLICIT_FUNCTION_TMPL_ARGS */ + +// This overload is not required by the standard; it is an extension. +// It is supported for backward compatibility with the HP STL, and +// because not all compilers support the language feature (explicit +// function template arguments) that is required for the standard +// version of get_temporary_buffer. +template +inline pair<_Tp*, ptrdiff_t> get_temporary_buffer(ptrdiff_t __len, _Tp*) { + return __get_temporary_buffer(__len, (_Tp*) 0); +} + +template +void return_temporary_buffer(_Tp* __p) { + free(__p); +} + +template +class _Temporary_buffer { +private: + ptrdiff_t _M_original_len; + ptrdiff_t _M_len; + _Tp* _M_buffer; + + void _M_allocate_buffer() { + _M_original_len = _M_len; + _M_buffer = 0; + + if (_M_len > (ptrdiff_t)(INT_MAX / sizeof(_Tp))) + _M_len = INT_MAX / sizeof(_Tp); + + while (_M_len > 0) { + _M_buffer = (_Tp*) malloc(_M_len * sizeof(_Tp)); + if (_M_buffer) + break; + _M_len /= 2; + } + } + + void _M_initialize_buffer(const _Tp&, __true_type) {} + void _M_initialize_buffer(const _Tp& val, __false_type) { + uninitialized_fill_n(_M_buffer, _M_len, val); + } + +public: + ptrdiff_t size() const { return _M_len; } + ptrdiff_t requested_size() const { return _M_original_len; } + _Tp* begin() { return _M_buffer; } + _Tp* end() { return _M_buffer + _M_len; } + + _Temporary_buffer(_ForwardIterator __first, _ForwardIterator __last) { + typedef typename __type_traits<_Tp>::has_trivial_default_constructor + _Trivial; + __STL_TRY { + _M_len = 0; + distance(__first, __last, _M_len); + _M_allocate_buffer(); + if (_M_len > 0) + _M_initialize_buffer(*__first, _Trivial()); + } + __STL_UNWIND(free(_M_buffer); _M_buffer = 0; _M_len = 0); + } + + ~_Temporary_buffer() { + destroy(_M_buffer, _M_buffer + _M_len); + free(_M_buffer); + } + +private: + // Disable copy constructor and assignment operator. + _Temporary_buffer(const _Temporary_buffer&) {} + void operator=(const _Temporary_buffer&) {} +}; + +// Class temporary_buffer is not part of the standard. It is an extension. + +template ::value_type +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + > +struct temporary_buffer : public _Temporary_buffer<_ForwardIterator, _Tp> +{ + temporary_buffer(_ForwardIterator __first, _ForwardIterator __last) + : _Temporary_buffer<_ForwardIterator, _Tp>(__first, __last) {} + ~temporary_buffer() {} +}; + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_TEMPBUF_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/stl_tree.h b/headers/cpp/stl_tree.h new file mode 100644 index 0000000000..c82943f568 --- /dev/null +++ b/headers/cpp/stl_tree.h @@ -0,0 +1,1333 @@ +/* + * + * 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. + * + * + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_TREE_H +#define __SGI_STL_INTERNAL_TREE_H + +/* + +Red-black tree class, designed for use in implementing STL +associative containers (set, multiset, map, and multimap). The +insertion and deletion algorithms are based on those in Cormen, +Leiserson, and Rivest, Introduction to Algorithms (MIT Press, 1990), +except that + +(1) the header cell is maintained with links not only to the root +but also to the leftmost node of the tree, to enable constant time +begin(), and to the rightmost node of the tree, to enable linear time +performance when used with the generic set algorithms (set_union, +etc.); + +(2) when a node being deleted has two children its successor node is +relinked into its place, rather than copied, so that the only +iterators invalidated are those referring to the deleted node. + +*/ + +#include +#include +#include +#include + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1375 +#endif + +typedef bool _Rb_tree_Color_type; +const _Rb_tree_Color_type _S_rb_tree_red = false; +const _Rb_tree_Color_type _S_rb_tree_black = true; + +struct _Rb_tree_node_base +{ + typedef _Rb_tree_Color_type _Color_type; + typedef _Rb_tree_node_base* _Base_ptr; + + _Color_type _M_color; + _Base_ptr _M_parent; + _Base_ptr _M_left; + _Base_ptr _M_right; + + static _Base_ptr _S_minimum(_Base_ptr __x) + { + while (__x->_M_left != 0) __x = __x->_M_left; + return __x; + } + + static _Base_ptr _S_maximum(_Base_ptr __x) + { + while (__x->_M_right != 0) __x = __x->_M_right; + return __x; + } +}; + +template +struct _Rb_tree_node : public _Rb_tree_node_base +{ + typedef _Rb_tree_node<_Value>* _Link_type; + _Value _M_value_field; +}; + + +struct _Rb_tree_base_iterator +{ + typedef _Rb_tree_node_base::_Base_ptr _Base_ptr; + typedef bidirectional_iterator_tag iterator_category; + typedef ptrdiff_t difference_type; + _Base_ptr _M_node; + + void _M_increment() + { + if (_M_node->_M_right != 0) { + _M_node = _M_node->_M_right; + while (_M_node->_M_left != 0) + _M_node = _M_node->_M_left; + } + else { + _Base_ptr __y = _M_node->_M_parent; + while (_M_node == __y->_M_right) { + _M_node = __y; + __y = __y->_M_parent; + } + if (_M_node->_M_right != __y) + _M_node = __y; + } + } + + void _M_decrement() + { + if (_M_node->_M_color == _S_rb_tree_red && + _M_node->_M_parent->_M_parent == _M_node) + _M_node = _M_node->_M_right; + else if (_M_node->_M_left != 0) { + _Base_ptr __y = _M_node->_M_left; + while (__y->_M_right != 0) + __y = __y->_M_right; + _M_node = __y; + } + else { + _Base_ptr __y = _M_node->_M_parent; + while (_M_node == __y->_M_left) { + _M_node = __y; + __y = __y->_M_parent; + } + _M_node = __y; + } + } +}; + +template +struct _Rb_tree_iterator : public _Rb_tree_base_iterator +{ + typedef _Value value_type; + typedef _Ref reference; + typedef _Ptr pointer; + typedef _Rb_tree_iterator<_Value, _Value&, _Value*> + iterator; + typedef _Rb_tree_iterator<_Value, const _Value&, const _Value*> + const_iterator; + typedef _Rb_tree_iterator<_Value, _Ref, _Ptr> + _Self; + typedef _Rb_tree_node<_Value>* _Link_type; + + _Rb_tree_iterator() {} + _Rb_tree_iterator(_Link_type __x) { _M_node = __x; } + _Rb_tree_iterator(const iterator& __it) { _M_node = __it._M_node; } + + reference operator*() const { return _Link_type(_M_node)->_M_value_field; } +#ifndef __SGI_STL_NO_ARROW_OPERATOR + pointer operator->() const { return &(operator*()); } +#endif /* __SGI_STL_NO_ARROW_OPERATOR */ + + _Self& operator++() { _M_increment(); return *this; } + _Self operator++(int) { + _Self __tmp = *this; + _M_increment(); + return __tmp; + } + + _Self& operator--() { _M_decrement(); return *this; } + _Self operator--(int) { + _Self __tmp = *this; + _M_decrement(); + return __tmp; + } +}; + +inline bool operator==(const _Rb_tree_base_iterator& __x, + const _Rb_tree_base_iterator& __y) { + return __x._M_node == __y._M_node; +} + +inline bool operator!=(const _Rb_tree_base_iterator& __x, + const _Rb_tree_base_iterator& __y) { + return __x._M_node != __y._M_node; +} + +#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION + +inline bidirectional_iterator_tag +iterator_category(const _Rb_tree_base_iterator&) { + return bidirectional_iterator_tag(); +} + +inline _Rb_tree_base_iterator::difference_type* +distance_type(const _Rb_tree_base_iterator&) { + return (_Rb_tree_base_iterator::difference_type*) 0; +} + +template +inline _Value* value_type(const _Rb_tree_iterator<_Value, _Ref, _Ptr>&) { + return (_Value*) 0; +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +inline void +_Rb_tree_rotate_left(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root) +{ + _Rb_tree_node_base* __y = __x->_M_right; + __x->_M_right = __y->_M_left; + if (__y->_M_left !=0) + __y->_M_left->_M_parent = __x; + __y->_M_parent = __x->_M_parent; + + if (__x == __root) + __root = __y; + else if (__x == __x->_M_parent->_M_left) + __x->_M_parent->_M_left = __y; + else + __x->_M_parent->_M_right = __y; + __y->_M_left = __x; + __x->_M_parent = __y; +} + +inline void +_Rb_tree_rotate_right(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root) +{ + _Rb_tree_node_base* __y = __x->_M_left; + __x->_M_left = __y->_M_right; + if (__y->_M_right != 0) + __y->_M_right->_M_parent = __x; + __y->_M_parent = __x->_M_parent; + + if (__x == __root) + __root = __y; + else if (__x == __x->_M_parent->_M_right) + __x->_M_parent->_M_right = __y; + else + __x->_M_parent->_M_left = __y; + __y->_M_right = __x; + __x->_M_parent = __y; +} + +inline void +_Rb_tree_rebalance(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root) +{ + __x->_M_color = _S_rb_tree_red; + while (__x != __root && __x->_M_parent->_M_color == _S_rb_tree_red) { + if (__x->_M_parent == __x->_M_parent->_M_parent->_M_left) { + _Rb_tree_node_base* __y = __x->_M_parent->_M_parent->_M_right; + if (__y && __y->_M_color == _S_rb_tree_red) { + __x->_M_parent->_M_color = _S_rb_tree_black; + __y->_M_color = _S_rb_tree_black; + __x->_M_parent->_M_parent->_M_color = _S_rb_tree_red; + __x = __x->_M_parent->_M_parent; + } + else { + if (__x == __x->_M_parent->_M_right) { + __x = __x->_M_parent; + _Rb_tree_rotate_left(__x, __root); + } + __x->_M_parent->_M_color = _S_rb_tree_black; + __x->_M_parent->_M_parent->_M_color = _S_rb_tree_red; + _Rb_tree_rotate_right(__x->_M_parent->_M_parent, __root); + } + } + else { + _Rb_tree_node_base* __y = __x->_M_parent->_M_parent->_M_left; + if (__y && __y->_M_color == _S_rb_tree_red) { + __x->_M_parent->_M_color = _S_rb_tree_black; + __y->_M_color = _S_rb_tree_black; + __x->_M_parent->_M_parent->_M_color = _S_rb_tree_red; + __x = __x->_M_parent->_M_parent; + } + else { + if (__x == __x->_M_parent->_M_left) { + __x = __x->_M_parent; + _Rb_tree_rotate_right(__x, __root); + } + __x->_M_parent->_M_color = _S_rb_tree_black; + __x->_M_parent->_M_parent->_M_color = _S_rb_tree_red; + _Rb_tree_rotate_left(__x->_M_parent->_M_parent, __root); + } + } + } + __root->_M_color = _S_rb_tree_black; +} + +inline _Rb_tree_node_base* +_Rb_tree_rebalance_for_erase(_Rb_tree_node_base* __z, + _Rb_tree_node_base*& __root, + _Rb_tree_node_base*& __leftmost, + _Rb_tree_node_base*& __rightmost) +{ + _Rb_tree_node_base* __y = __z; + _Rb_tree_node_base* __x = 0; + _Rb_tree_node_base* __x_parent = 0; + if (__y->_M_left == 0) // __z has at most one non-null child. y == z. + __x = __y->_M_right; // __x might be null. + else + if (__y->_M_right == 0) // __z has exactly one non-null child. y == z. + __x = __y->_M_left; // __x is not null. + else { // __z has two non-null children. Set __y to + __y = __y->_M_right; // __z's successor. __x might be null. + while (__y->_M_left != 0) + __y = __y->_M_left; + __x = __y->_M_right; + } + if (__y != __z) { // relink y in place of z. y is z's successor + __z->_M_left->_M_parent = __y; + __y->_M_left = __z->_M_left; + if (__y != __z->_M_right) { + __x_parent = __y->_M_parent; + if (__x) __x->_M_parent = __y->_M_parent; + __y->_M_parent->_M_left = __x; // __y must be a child of _M_left + __y->_M_right = __z->_M_right; + __z->_M_right->_M_parent = __y; + } + else + __x_parent = __y; + if (__root == __z) + __root = __y; + else if (__z->_M_parent->_M_left == __z) + __z->_M_parent->_M_left = __y; + else + __z->_M_parent->_M_right = __y; + __y->_M_parent = __z->_M_parent; + __STD::swap(__y->_M_color, __z->_M_color); + __y = __z; + // __y now points to node to be actually deleted + } + else { // __y == __z + __x_parent = __y->_M_parent; + if (__x) __x->_M_parent = __y->_M_parent; + if (__root == __z) + __root = __x; + else + if (__z->_M_parent->_M_left == __z) + __z->_M_parent->_M_left = __x; + else + __z->_M_parent->_M_right = __x; + if (__leftmost == __z) + if (__z->_M_right == 0) // __z->_M_left must be null also + __leftmost = __z->_M_parent; + // makes __leftmost == _M_header if __z == __root + else + __leftmost = _Rb_tree_node_base::_S_minimum(__x); + if (__rightmost == __z) + if (__z->_M_left == 0) // __z->_M_right must be null also + __rightmost = __z->_M_parent; + // makes __rightmost == _M_header if __z == __root + else // __x == __z->_M_left + __rightmost = _Rb_tree_node_base::_S_maximum(__x); + } + if (__y->_M_color != _S_rb_tree_red) { + while (__x != __root && (__x == 0 || __x->_M_color == _S_rb_tree_black)) + if (__x == __x_parent->_M_left) { + _Rb_tree_node_base* __w = __x_parent->_M_right; + if (__w->_M_color == _S_rb_tree_red) { + __w->_M_color = _S_rb_tree_black; + __x_parent->_M_color = _S_rb_tree_red; + _Rb_tree_rotate_left(__x_parent, __root); + __w = __x_parent->_M_right; + } + if ((__w->_M_left == 0 || + __w->_M_left->_M_color == _S_rb_tree_black) && + (__w->_M_right == 0 || + __w->_M_right->_M_color == _S_rb_tree_black)) { + __w->_M_color = _S_rb_tree_red; + __x = __x_parent; + __x_parent = __x_parent->_M_parent; + } else { + if (__w->_M_right == 0 || + __w->_M_right->_M_color == _S_rb_tree_black) { + if (__w->_M_left) __w->_M_left->_M_color = _S_rb_tree_black; + __w->_M_color = _S_rb_tree_red; + _Rb_tree_rotate_right(__w, __root); + __w = __x_parent->_M_right; + } + __w->_M_color = __x_parent->_M_color; + __x_parent->_M_color = _S_rb_tree_black; + if (__w->_M_right) __w->_M_right->_M_color = _S_rb_tree_black; + _Rb_tree_rotate_left(__x_parent, __root); + break; + } + } else { // same as above, with _M_right <-> _M_left. + _Rb_tree_node_base* __w = __x_parent->_M_left; + if (__w->_M_color == _S_rb_tree_red) { + __w->_M_color = _S_rb_tree_black; + __x_parent->_M_color = _S_rb_tree_red; + _Rb_tree_rotate_right(__x_parent, __root); + __w = __x_parent->_M_left; + } + if ((__w->_M_right == 0 || + __w->_M_right->_M_color == _S_rb_tree_black) && + (__w->_M_left == 0 || + __w->_M_left->_M_color == _S_rb_tree_black)) { + __w->_M_color = _S_rb_tree_red; + __x = __x_parent; + __x_parent = __x_parent->_M_parent; + } else { + if (__w->_M_left == 0 || + __w->_M_left->_M_color == _S_rb_tree_black) { + if (__w->_M_right) __w->_M_right->_M_color = _S_rb_tree_black; + __w->_M_color = _S_rb_tree_red; + _Rb_tree_rotate_left(__w, __root); + __w = __x_parent->_M_left; + } + __w->_M_color = __x_parent->_M_color; + __x_parent->_M_color = _S_rb_tree_black; + if (__w->_M_left) __w->_M_left->_M_color = _S_rb_tree_black; + _Rb_tree_rotate_right(__x_parent, __root); + break; + } + } + if (__x) __x->_M_color = _S_rb_tree_black; + } + return __y; +} + +// Base class to encapsulate the differences between old SGI-style +// allocators and standard-conforming allocators. In order to avoid +// having an empty base class, we arbitrarily move one of rb_tree's +// data members into the base class. + +#ifdef __STL_USE_STD_ALLOCATORS + +// _Base for general standard-conforming allocators. +template +class _Rb_tree_alloc_base { +public: + typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type; + allocator_type get_allocator() const { return _M_node_allocator; } + + _Rb_tree_alloc_base(const allocator_type& __a) + : _M_node_allocator(__a), _M_header(0) {} + +protected: + typename _Alloc_traits<_Rb_tree_node<_Tp>, _Alloc>::allocator_type + _M_node_allocator; + _Rb_tree_node<_Tp>* _M_header; + + _Rb_tree_node<_Tp>* _M_get_node() + { return _M_node_allocator.allocate(1); } + void _M_put_node(_Rb_tree_node<_Tp>* __p) + { _M_node_allocator.deallocate(__p, 1); } +}; + +// Specialization for instanceless allocators. +template +class _Rb_tree_alloc_base<_Tp, _Alloc, true> { +public: + typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Rb_tree_alloc_base(const allocator_type&) : _M_header(0) {} + +protected: + _Rb_tree_node<_Tp>* _M_header; + + typedef typename _Alloc_traits<_Rb_tree_node<_Tp>, _Alloc>::_Alloc_type + _Alloc_type; + + _Rb_tree_node<_Tp>* _M_get_node() + { return _Alloc_type::allocate(1); } + void _M_put_node(_Rb_tree_node<_Tp>* __p) + { _Alloc_type::deallocate(__p, 1); } +}; + +template +struct _Rb_tree_base + : public _Rb_tree_alloc_base<_Tp, _Alloc, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> +{ + typedef _Rb_tree_alloc_base<_Tp, _Alloc, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> + _Base; + typedef typename _Base::allocator_type allocator_type; + + _Rb_tree_base(const allocator_type& __a) + : _Base(__a) { _M_header = _M_get_node(); } + ~_Rb_tree_base() { _M_put_node(_M_header); } + +}; + +#else /* __STL_USE_STD_ALLOCATORS */ + +template +struct _Rb_tree_base +{ + typedef _Alloc allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Rb_tree_base(const allocator_type&) + : _M_header(0) { _M_header = _M_get_node(); } + ~_Rb_tree_base() { _M_put_node(_M_header); } + +protected: + _Rb_tree_node<_Tp>* _M_header; + + typedef simple_alloc<_Rb_tree_node<_Tp>, _Alloc> _Alloc_type; + + _Rb_tree_node<_Tp>* _M_get_node() + { return _Alloc_type::allocate(1); } + void _M_put_node(_Rb_tree_node<_Tp>* __p) + { _Alloc_type::deallocate(__p, 1); } +}; + +#endif /* __STL_USE_STD_ALLOCATORS */ + +template +class _Rb_tree : protected _Rb_tree_base<_Value, _Alloc> { + typedef _Rb_tree_base<_Value, _Alloc> _Base; +protected: + typedef _Rb_tree_node_base* _Base_ptr; + typedef _Rb_tree_node<_Value> _Rb_tree_node; + typedef _Rb_tree_Color_type _Color_type; +public: + typedef _Key key_type; + typedef _Value value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef _Rb_tree_node* _Link_type; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + + typedef typename _Base::allocator_type allocator_type; + allocator_type get_allocator() const { return _Base::get_allocator(); } + +protected: +#ifdef __STL_USE_NAMESPACES + using _Base::_M_get_node; + using _Base::_M_put_node; + using _Base::_M_header; +#endif /* __STL_USE_NAMESPACES */ + +protected: + + _Link_type _M_create_node(const value_type& __x) + { + _Link_type __tmp = _M_get_node(); + __STL_TRY { + construct(&__tmp->_M_value_field, __x); + } + __STL_UNWIND(_M_put_node(__tmp)); + return __tmp; + } + + _Link_type _M_clone_node(_Link_type __x) + { + _Link_type __tmp = _M_create_node(__x->_M_value_field); + __tmp->_M_color = __x->_M_color; + __tmp->_M_left = 0; + __tmp->_M_right = 0; + return __tmp; + } + + void destroy_node(_Link_type __p) + { + destroy(&__p->_M_value_field); + _M_put_node(__p); + } + +protected: + size_type _M_node_count; // keeps track of size of tree + _Compare _M_key_compare; + + _Link_type& _M_root() const + { return (_Link_type&) _M_header->_M_parent; } + _Link_type& _M_leftmost() const + { return (_Link_type&) _M_header->_M_left; } + _Link_type& _M_rightmost() const + { return (_Link_type&) _M_header->_M_right; } + + static _Link_type& _S_left(_Link_type __x) + { return (_Link_type&)(__x->_M_left); } + static _Link_type& _S_right(_Link_type __x) + { return (_Link_type&)(__x->_M_right); } + static _Link_type& _S_parent(_Link_type __x) + { return (_Link_type&)(__x->_M_parent); } + static reference _S_value(_Link_type __x) + { return __x->_M_value_field; } + static const _Key& _S_key(_Link_type __x) + { return _KeyOfValue()(_S_value(__x)); } + static _Color_type& _S_color(_Link_type __x) + { return (_Color_type&)(__x->_M_color); } + + static _Link_type& _S_left(_Base_ptr __x) + { return (_Link_type&)(__x->_M_left); } + static _Link_type& _S_right(_Base_ptr __x) + { return (_Link_type&)(__x->_M_right); } + static _Link_type& _S_parent(_Base_ptr __x) + { return (_Link_type&)(__x->_M_parent); } + static reference _S_value(_Base_ptr __x) + { return ((_Link_type)__x)->_M_value_field; } + static const _Key& _S_key(_Base_ptr __x) + { return _KeyOfValue()(_S_value(_Link_type(__x)));} + static _Color_type& _S_color(_Base_ptr __x) + { return (_Color_type&)(_Link_type(__x)->_M_color); } + + static _Link_type _S_minimum(_Link_type __x) + { return (_Link_type) _Rb_tree_node_base::_S_minimum(__x); } + + static _Link_type _S_maximum(_Link_type __x) + { return (_Link_type) _Rb_tree_node_base::_S_maximum(__x); } + +public: + typedef _Rb_tree_iterator iterator; + typedef _Rb_tree_iterator + const_iterator; + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + typedef reverse_iterator const_reverse_iterator; + typedef reverse_iterator reverse_iterator; +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + typedef reverse_bidirectional_iterator + reverse_iterator; + typedef reverse_bidirectional_iterator + const_reverse_iterator; +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +private: + iterator _M_insert(_Base_ptr __x, _Base_ptr __y, const value_type& __v); + _Link_type _M_copy(_Link_type __x, _Link_type __p); + void _M_erase(_Link_type __x); + +public: + // allocation/deallocation + _Rb_tree() + : _Base(allocator_type()), _M_node_count(0), _M_key_compare() + { _M_empty_initialize(); } + + _Rb_tree(const _Compare& __comp) + : _Base(allocator_type()), _M_node_count(0), _M_key_compare(__comp) + { _M_empty_initialize(); } + + _Rb_tree(const _Compare& __comp, const allocator_type& __a) + : _Base(__a), _M_node_count(0), _M_key_compare(__comp) + { _M_empty_initialize(); } + + _Rb_tree(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x) + : _Base(__x.get_allocator()), + _M_node_count(0), _M_key_compare(__x._M_key_compare) + { + if (__x._M_root() == 0) + _M_empty_initialize(); + else { + _S_color(_M_header) = _S_rb_tree_red; + _M_root() = _M_copy(__x._M_root(), _M_header); + _M_leftmost() = _S_minimum(_M_root()); + _M_rightmost() = _S_maximum(_M_root()); + } + _M_node_count = __x._M_node_count; + } + ~_Rb_tree() { clear(); } + _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& + operator=(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x); + +private: + void _M_empty_initialize() { + _S_color(_M_header) = _S_rb_tree_red; // used to distinguish header from + // __root, in iterator.operator++ + _M_root() = 0; + _M_leftmost() = _M_header; + _M_rightmost() = _M_header; + } + +public: + // accessors: + _Compare key_comp() const { return _M_key_compare; } + iterator begin() { return _M_leftmost(); } + const_iterator begin() const { return _M_leftmost(); } + iterator end() { return _M_header; } + const_iterator end() const { return _M_header; } + reverse_iterator rbegin() { return reverse_iterator(end()); } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } + reverse_iterator rend() { return reverse_iterator(begin()); } + const_reverse_iterator rend() const { + return const_reverse_iterator(begin()); + } + bool empty() const { return _M_node_count == 0; } + size_type size() const { return _M_node_count; } + size_type max_size() const { return size_type(-1); } + + void swap(_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __t) { + __STD::swap(_M_header, __t._M_header); + __STD::swap(_M_node_count, __t._M_node_count); + __STD::swap(_M_key_compare, __t._M_key_compare); + } + +public: + // insert/erase + pair insert_unique(const value_type& __x); + iterator insert_equal(const value_type& __x); + + iterator insert_unique(iterator __position, const value_type& __x); + iterator insert_equal(iterator __position, const value_type& __x); + +#ifdef __STL_MEMBER_TEMPLATES + template + void insert_unique(_InputIterator __first, _InputIterator __last); + template + void insert_equal(_InputIterator __first, _InputIterator __last); +#else /* __STL_MEMBER_TEMPLATES */ + void insert_unique(const_iterator __first, const_iterator __last); + void insert_unique(const value_type* __first, const value_type* __last); + void insert_equal(const_iterator __first, const_iterator __last); + void insert_equal(const value_type* __first, const value_type* __last); +#endif /* __STL_MEMBER_TEMPLATES */ + + void erase(iterator __position); + size_type erase(const key_type& __x); + void erase(iterator __first, iterator __last); + void erase(const key_type* __first, const key_type* __last); + void clear() { + if (_M_node_count != 0) { + _M_erase(_M_root()); + _M_leftmost() = _M_header; + _M_root() = 0; + _M_rightmost() = _M_header; + _M_node_count = 0; + } + } + +public: + // set operations: + iterator find(const key_type& __x); + const_iterator find(const key_type& __x) const; + size_type count(const key_type& __x) const; + iterator lower_bound(const key_type& __x); + const_iterator lower_bound(const key_type& __x) const; + iterator upper_bound(const key_type& __x); + const_iterator upper_bound(const key_type& __x) const; + pair equal_range(const key_type& __x); + pair equal_range(const key_type& __x) const; + +public: + // Debugging. + bool __rb_verify() const; +}; + +template +inline bool +operator==(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x, + const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __y) +{ + return __x.size() == __y.size() && + equal(__x.begin(), __x.end(), __y.begin()); +} + +template +inline bool +operator<(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x, + const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __y) +{ + return lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline void +swap(_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x, + _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __y) +{ + __x.swap(__y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + + +template +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::operator=(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x) +{ + if (this != &__x) { + // Note that _Key may be a constant type. + clear(); + _M_node_count = 0; + _M_key_compare = __x._M_key_compare; + if (__x._M_root() == 0) { + _M_root() = 0; + _M_leftmost() = _M_header; + _M_rightmost() = _M_header; + } + else { + _M_root() = _M_copy(__x._M_root(), _M_header); + _M_leftmost() = _S_minimum(_M_root()); + _M_rightmost() = _S_maximum(_M_root()); + _M_node_count = __x._M_node_count; + } + } + return *this; +} + +template +typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::_M_insert(_Base_ptr __x_, _Base_ptr __y_, const _Value& __v) +{ + _Link_type __x = (_Link_type) __x_; + _Link_type __y = (_Link_type) __y_; + _Link_type __z; + + if (__y == _M_header || __x != 0 || + _M_key_compare(_KeyOfValue()(__v), _S_key(__y))) { + __z = _M_create_node(__v); + _S_left(__y) = __z; // also makes _M_leftmost() = __z + // when __y == _M_header + if (__y == _M_header) { + _M_root() = __z; + _M_rightmost() = __z; + } + else if (__y == _M_leftmost()) + _M_leftmost() = __z; // maintain _M_leftmost() pointing to min node + } + else { + __z = _M_create_node(__v); + _S_right(__y) = __z; + if (__y == _M_rightmost()) + _M_rightmost() = __z; // maintain _M_rightmost() pointing to max node + } + _S_parent(__z) = __y; + _S_left(__z) = 0; + _S_right(__z) = 0; + _Rb_tree_rebalance(__z, _M_header->_M_parent); + ++_M_node_count; + return iterator(__z); +} + +template +typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::insert_equal(const _Value& __v) +{ + _Link_type __y = _M_header; + _Link_type __x = _M_root(); + while (__x != 0) { + __y = __x; + __x = _M_key_compare(_KeyOfValue()(__v), _S_key(__x)) ? + _S_left(__x) : _S_right(__x); + } + return _M_insert(__x, __y, __v); +} + + +template +pair::iterator, + bool> +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::insert_unique(const _Value& __v) +{ + _Link_type __y = _M_header; + _Link_type __x = _M_root(); + bool __comp = true; + while (__x != 0) { + __y = __x; + __comp = _M_key_compare(_KeyOfValue()(__v), _S_key(__x)); + __x = __comp ? _S_left(__x) : _S_right(__x); + } + iterator __j = iterator(__y); + if (__comp) + if (__j == begin()) + return pair(_M_insert(__x, __y, __v), true); + else + --__j; + if (_M_key_compare(_S_key(__j._M_node), _KeyOfValue()(__v))) + return pair(_M_insert(__x, __y, __v), true); + return pair(__j, false); +} + + +template +typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator +_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc> + ::insert_unique(iterator __position, const _Val& __v) +{ + if (__position._M_node == _M_header->_M_left) { // begin() + if (size() > 0 && + _M_key_compare(_KeyOfValue()(__v), _S_key(__position._M_node))) + return _M_insert(__position._M_node, __position._M_node, __v); + // first argument just needs to be non-null + else + return insert_unique(__v).first; + } else if (__position._M_node == _M_header) { // end() + if (_M_key_compare(_S_key(_M_rightmost()), _KeyOfValue()(__v))) + return _M_insert(0, _M_rightmost(), __v); + else + return insert_unique(__v).first; + } else { + iterator __before = __position; + --__before; + if (_M_key_compare(_S_key(__before._M_node), _KeyOfValue()(__v)) + && _M_key_compare(_KeyOfValue()(__v), _S_key(__position._M_node))) { + if (_S_right(__before._M_node) == 0) + return _M_insert(0, __before._M_node, __v); + else + return _M_insert(__position._M_node, __position._M_node, __v); + // first argument just needs to be non-null + } else + return insert_unique(__v).first; + } +} + +template +typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator +_Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc> + ::insert_equal(iterator __position, const _Val& __v) +{ + if (__position._M_node == _M_header->_M_left) { // begin() + if (size() > 0 && + _M_key_compare(_KeyOfValue()(__v), _S_key(__position._M_node))) + return _M_insert(__position._M_node, __position._M_node, __v); + // first argument just needs to be non-null + else + return insert_equal(__v); + } else if (__position._M_node == _M_header) {// end() + if (!_M_key_compare(_KeyOfValue()(__v), _S_key(_M_rightmost()))) + return _M_insert(0, _M_rightmost(), __v); + else + return insert_equal(__v); + } else { + iterator __before = __position; + --__before; + if (!_M_key_compare(_KeyOfValue()(__v), _S_key(__before._M_node)) + && !_M_key_compare(_S_key(__position._M_node), _KeyOfValue()(__v))) { + if (_S_right(__before._M_node) == 0) + return _M_insert(0, __before._M_node, __v); + else + return _M_insert(__position._M_node, __position._M_node, __v); + // first argument just needs to be non-null + } else + return insert_equal(__v); + } +} + +#ifdef __STL_MEMBER_TEMPLATES + +template + template +void _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc> + ::insert_equal(_II __first, _II __last) +{ + for ( ; __first != __last; ++__first) + insert_equal(*__first); +} + +template + template +void _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc> + ::insert_unique(_II __first, _II __last) { + for ( ; __first != __last; ++__first) + insert_unique(*__first); +} + +#else /* __STL_MEMBER_TEMPLATES */ + +template +void +_Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc> + ::insert_equal(const _Val* __first, const _Val* __last) +{ + for ( ; __first != __last; ++__first) + insert_equal(*__first); +} + +template +void +_Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc> + ::insert_equal(const_iterator __first, const_iterator __last) +{ + for ( ; __first != __last; ++__first) + insert_equal(*__first); +} + +template +void +_Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc> + ::insert_unique(const _Val* __first, const _Val* __last) +{ + for ( ; __first != __last; ++__first) + insert_unique(*__first); +} + +template +void _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc> + ::insert_unique(const_iterator __first, const_iterator __last) +{ + for ( ; __first != __last; ++__first) + insert_unique(*__first); +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +template +inline void _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::erase(iterator __position) +{ + _Link_type __y = + (_Link_type) _Rb_tree_rebalance_for_erase(__position._M_node, + _M_header->_M_parent, + _M_header->_M_left, + _M_header->_M_right); + destroy_node(__y); + --_M_node_count; +} + +template +typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::size_type +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::erase(const _Key& __x) +{ + pair __p = equal_range(__x); + size_type __n = 0; + distance(__p.first, __p.second, __n); + erase(__p.first, __p.second); + return __n; +} + +template +typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::_Link_type +_Rb_tree<_Key,_Val,_KoV,_Compare,_Alloc> + ::_M_copy(_Link_type __x, _Link_type __p) +{ + // structural copy. __x and __p must be non-null. + _Link_type __top = _M_clone_node(__x); + __top->_M_parent = __p; + + __STL_TRY { + if (__x->_M_right) + __top->_M_right = _M_copy(_S_right(__x), __top); + __p = __top; + __x = _S_left(__x); + + while (__x != 0) { + _Link_type __y = _M_clone_node(__x); + __p->_M_left = __y; + __y->_M_parent = __p; + if (__x->_M_right) + __y->_M_right = _M_copy(_S_right(__x), __y); + __p = __y; + __x = _S_left(__x); + } + } + __STL_UNWIND(_M_erase(__top)); + + return __top; +} + +template +void _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::_M_erase(_Link_type __x) +{ + // erase without rebalancing + while (__x != 0) { + _M_erase(_S_right(__x)); + _Link_type __y = _S_left(__x); + destroy_node(__x); + __x = __y; + } +} + +template +void _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::erase(iterator __first, iterator __last) +{ + if (__first == begin() && __last == end()) + clear(); + else + while (__first != __last) erase(__first++); +} + +template +void _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::erase(const _Key* __first, const _Key* __last) +{ + while (__first != __last) erase(*__first++); +} + +template +typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::find(const _Key& __k) +{ + _Link_type __y = _M_header; // Last node which is not less than __k. + _Link_type __x = _M_root(); // Current node. + + while (__x != 0) + if (!_M_key_compare(_S_key(__x), __k)) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + + iterator __j = iterator(__y); + return (__j == end() || _M_key_compare(__k, _S_key(__j._M_node))) ? + end() : __j; +} + +template +typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::const_iterator +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::find(const _Key& __k) const +{ + _Link_type __y = _M_header; /* Last node which is not less than __k. */ + _Link_type __x = _M_root(); /* Current node. */ + + while (__x != 0) { + if (!_M_key_compare(_S_key(__x), __k)) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + } + const_iterator __j = const_iterator(__y); + return (__j == end() || _M_key_compare(__k, _S_key(__j._M_node))) ? + end() : __j; +} + +template +typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::size_type +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::count(const _Key& __k) const +{ + pair __p = equal_range(__k); + size_type __n = 0; + distance(__p.first, __p.second, __n); + return __n; +} + +template +typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::lower_bound(const _Key& __k) +{ + _Link_type __y = _M_header; /* Last node which is not less than __k. */ + _Link_type __x = _M_root(); /* Current node. */ + + while (__x != 0) + if (!_M_key_compare(_S_key(__x), __k)) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + + return iterator(__y); +} + +template +typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::const_iterator +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::lower_bound(const _Key& __k) const +{ + _Link_type __y = _M_header; /* Last node which is not less than __k. */ + _Link_type __x = _M_root(); /* Current node. */ + + while (__x != 0) + if (!_M_key_compare(_S_key(__x), __k)) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + + return const_iterator(__y); +} + +template +typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::upper_bound(const _Key& __k) +{ + _Link_type __y = _M_header; /* Last node which is greater than __k. */ + _Link_type __x = _M_root(); /* Current node. */ + + while (__x != 0) + if (_M_key_compare(__k, _S_key(__x))) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + + return iterator(__y); +} + +template +typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::const_iterator +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::upper_bound(const _Key& __k) const +{ + _Link_type __y = _M_header; /* Last node which is greater than __k. */ + _Link_type __x = _M_root(); /* Current node. */ + + while (__x != 0) + if (_M_key_compare(__k, _S_key(__x))) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + + return const_iterator(__y); +} + +template +inline +pair::iterator, + typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator> +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::equal_range(const _Key& __k) +{ + return pair(lower_bound(__k), upper_bound(__k)); +} + +template +inline +pair::const_iterator, + typename _Rb_tree<_Key, _Value, _KoV, _Compare, _Alloc>::const_iterator> +_Rb_tree<_Key, _Value, _KoV, _Compare, _Alloc> + ::equal_range(const _Key& __k) const +{ + return pair(lower_bound(__k), + upper_bound(__k)); +} + +inline int +__black_count(_Rb_tree_node_base* __node, _Rb_tree_node_base* __root) +{ + if (__node == 0) + return 0; + else { + int __bc = __node->_M_color == _S_rb_tree_black ? 1 : 0; + if (__node == __root) + return __bc; + else + return __bc + __black_count(__node->_M_parent, __root); + } +} + +template +bool _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::__rb_verify() const +{ + if (_M_node_count == 0 || begin() == end()) + return _M_node_count == 0 && begin() == end() && + _M_header->_M_left == _M_header && _M_header->_M_right == _M_header; + + int __len = __black_count(_M_leftmost(), _M_root()); + for (const_iterator __it = begin(); __it != end(); ++__it) { + _Link_type __x = (_Link_type) __it._M_node; + _Link_type __L = _S_left(__x); + _Link_type __R = _S_right(__x); + + if (__x->_M_color == _S_rb_tree_red) + if ((__L && __L->_M_color == _S_rb_tree_red) || + (__R && __R->_M_color == _S_rb_tree_red)) + return false; + + if (__L && _M_key_compare(_S_key(__x), _S_key(__L))) + return false; + if (__R && _M_key_compare(_S_key(__R), _S_key(__x))) + return false; + + if (!__L && !__R && __black_count(__x, _M_root()) != __len) + return false; + } + + if (_M_leftmost() != _Rb_tree_node_base::_S_minimum(_M_root())) + return false; + if (_M_rightmost() != _Rb_tree_node_base::_S_maximum(_M_root())) + return false; + + return true; +} + +// Class rb_tree is not part of the C++ standard. It is provided for +// compatibility with the HP STL. + +template +struct rb_tree : public _Rb_tree<_Key, _Value, _KeyOfValue, _Compare, _Alloc> +{ + typedef _Rb_tree<_Key, _Value, _KeyOfValue, _Compare, _Alloc> _Base; + typedef typename _Base::allocator_type allocator_type; + + rb_tree(const _Compare& __comp = _Compare(), + const allocator_type& __a = allocator_type()) + : _Base(__comp, __a) {} + + ~rb_tree() {} +}; + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1375 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_TREE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/stl_uninitialized.h b/headers/cpp/stl_uninitialized.h new file mode 100644 index 0000000000..3146c82a71 --- /dev/null +++ b/headers/cpp/stl_uninitialized.h @@ -0,0 +1,279 @@ +/* + * + * 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,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. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_UNINITIALIZED_H +#define __SGI_STL_INTERNAL_UNINITIALIZED_H + +__STL_BEGIN_NAMESPACE + +// uninitialized_copy + +// Valid if copy construction is equivalent to assignment, and if the +// destructor is trivial. +template +inline _ForwardIter +__uninitialized_copy_aux(_InputIter __first, _InputIter __last, + _ForwardIter __result, + __true_type) +{ + return copy(__first, __last, __result); +} + +template +_ForwardIter +__uninitialized_copy_aux(_InputIter __first, _InputIter __last, + _ForwardIter __result, + __false_type) +{ + _ForwardIter __cur = __result; + __STL_TRY { + for ( ; __first != __last; ++__first, ++__cur) + construct(&*__cur, *__first); + return __cur; + } + __STL_UNWIND(destroy(__result, __cur)); +} + + +template +inline _ForwardIter +__uninitialized_copy(_InputIter __first, _InputIter __last, + _ForwardIter __result, _Tp*) +{ + typedef typename __type_traits<_Tp>::is_POD_type _Is_POD; + return __uninitialized_copy_aux(__first, __last, __result, _Is_POD()); +} + +template +inline _ForwardIter + uninitialized_copy(_InputIter __first, _InputIter __last, + _ForwardIter __result) +{ + return __uninitialized_copy(__first, __last, __result, + __VALUE_TYPE(__result)); +} + +inline char* uninitialized_copy(const char* __first, const char* __last, + char* __result) { + memmove(__result, __first, __last - __first); + return __result + (__last - __first); +} + +inline wchar_t* +uninitialized_copy(const wchar_t* __first, const wchar_t* __last, + wchar_t* __result) +{ + memmove(__result, __first, sizeof(wchar_t) * (__last - __first)); + return __result + (__last - __first); +} + +// uninitialized_copy_n (not part of the C++ standard) + +template +pair<_InputIter, _ForwardIter> +__uninitialized_copy_n(_InputIter __first, _Size __count, + _ForwardIter __result, + input_iterator_tag) +{ + _ForwardIter __cur = __result; + __STL_TRY { + for ( ; __count > 0 ; --__count, ++__first, ++__cur) + construct(&*__cur, *__first); + return pair<_InputIter, _ForwardIter>(__first, __cur); + } + __STL_UNWIND(destroy(__result, __cur)); +} + +template +inline pair<_RandomAccessIter, _ForwardIter> +__uninitialized_copy_n(_RandomAccessIter __first, _Size __count, + _ForwardIter __result, + random_access_iterator_tag) { + _RandomAccessIter __last = __first + __count; + return pair<_RandomAccessIter, _ForwardIter>( + __last, + uninitialized_copy(__first, __last, __result)); +} + +template +inline pair<_InputIter, _ForwardIter> +__uninitialized_copy_n(_InputIter __first, _Size __count, + _ForwardIter __result) { + return __uninitialized_copy_n(__first, __count, __result, + __ITERATOR_CATEGORY(__first)); +} + +template +inline pair<_InputIter, _ForwardIter> +uninitialized_copy_n(_InputIter __first, _Size __count, + _ForwardIter __result) { + return __uninitialized_copy_n(__first, __count, __result, + __ITERATOR_CATEGORY(__first)); +} + +// Valid if copy construction is equivalent to assignment, and if the +// destructor is trivial. +template +inline void +__uninitialized_fill_aux(_ForwardIter __first, _ForwardIter __last, + const _Tp& __x, __true_type) +{ + fill(__first, __last, __x); +} + +template +void +__uninitialized_fill_aux(_ForwardIter __first, _ForwardIter __last, + const _Tp& __x, __false_type) +{ + _ForwardIter __cur = __first; + __STL_TRY { + for ( ; __cur != __last; ++__cur) + construct(&*__cur, __x); + } + __STL_UNWIND(destroy(__first, __cur)); +} + +template +inline void __uninitialized_fill(_ForwardIter __first, + _ForwardIter __last, const _Tp& __x, _Tp1*) +{ + typedef typename __type_traits<_Tp1>::is_POD_type _Is_POD; + __uninitialized_fill_aux(__first, __last, __x, _Is_POD()); + +} + +template +inline void uninitialized_fill(_ForwardIter __first, + _ForwardIter __last, + const _Tp& __x) +{ + __uninitialized_fill(__first, __last, __x, __VALUE_TYPE(__first)); +} + +// Valid if copy construction is equivalent to assignment, and if the +// destructor is trivial. +template +inline _ForwardIter +__uninitialized_fill_n_aux(_ForwardIter __first, _Size __n, + const _Tp& __x, __true_type) +{ + return fill_n(__first, __n, __x); +} + +template +_ForwardIter +__uninitialized_fill_n_aux(_ForwardIter __first, _Size __n, + const _Tp& __x, __false_type) +{ + _ForwardIter __cur = __first; + __STL_TRY { + for ( ; __n > 0; --__n, ++__cur) + construct(&*__cur, __x); + return __cur; + } + __STL_UNWIND(destroy(__first, __cur)); +} + +template +inline _ForwardIter +__uninitialized_fill_n(_ForwardIter __first, _Size __n, const _Tp& __x, _Tp1*) +{ + typedef typename __type_traits<_Tp1>::is_POD_type _Is_POD; + return __uninitialized_fill_n_aux(__first, __n, __x, _Is_POD()); +} + +template +inline _ForwardIter +uninitialized_fill_n(_ForwardIter __first, _Size __n, const _Tp& __x) +{ + return __uninitialized_fill_n(__first, __n, __x, __VALUE_TYPE(__first)); +} + +// Extensions: __uninitialized_copy_copy, __uninitialized_copy_fill, +// __uninitialized_fill_copy. + +// __uninitialized_copy_copy +// Copies [first1, last1) into [result, result + (last1 - first1)), and +// copies [first2, last2) into +// [result, result + (last1 - first1) + (last2 - first2)). + +template +inline _ForwardIter +__uninitialized_copy_copy(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _ForwardIter __result) +{ + _ForwardIter __mid = uninitialized_copy(__first1, __last1, __result); + __STL_TRY { + return uninitialized_copy(__first2, __last2, __mid); + } + __STL_UNWIND(destroy(__result, __mid)); +} + +// __uninitialized_fill_copy +// Fills [result, mid) with x, and copies [first, last) into +// [mid, mid + (last - first)). +template +inline _ForwardIter +__uninitialized_fill_copy(_ForwardIter __result, _ForwardIter __mid, + const _Tp& __x, + _InputIter __first, _InputIter __last) +{ + uninitialized_fill(__result, __mid, __x); + __STL_TRY { + return uninitialized_copy(__first, __last, __mid); + } + __STL_UNWIND(destroy(__result, __mid)); +} + +// __uninitialized_copy_fill +// Copies [first1, last1) into [first2, first2 + (last1 - first1)), and +// fills [first2 + (last1 - first1), last2) with x. +template +inline void +__uninitialized_copy_fill(_InputIter __first1, _InputIter __last1, + _ForwardIter __first2, _ForwardIter __last2, + const _Tp& __x) +{ + _ForwardIter __mid2 = uninitialized_copy(__first1, __last1, __first2); + __STL_TRY { + uninitialized_fill(__mid2, __last2, __x); + } + __STL_UNWIND(destroy(__first2, __mid2)); +} + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_UNINITIALIZED_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/stl_vector.h b/headers/cpp/stl_vector.h new file mode 100644 index 0000000000..d1149e9af6 --- /dev/null +++ b/headers/cpp/stl_vector.h @@ -0,0 +1,823 @@ +/* + * + * 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. + */ + +/* NOTE: This is an internal header file, included by other STL headers. + * You should not attempt to use it directly. + */ + +#ifndef __SGI_STL_INTERNAL_VECTOR_H +#define __SGI_STL_INTERNAL_VECTOR_H + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1174 +#pragma set woff 1375 +#endif + +// The vector base class serves two purposes. First, its constructor +// and destructor allocate (but don't initialize) storage. This makes +// exception safety easier. Second, the base class encapsulates all of +// the differences between SGI-style allocators and standard-conforming +// allocators. + +#ifdef __STL_USE_STD_ALLOCATORS + +// Base class for ordinary allocators. +template +class _Vector_alloc_base { +public: + typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return _M_data_allocator; } + + _Vector_alloc_base(const allocator_type& __a) + : _M_data_allocator(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0) + {} + +protected: + allocator_type _M_data_allocator; + _Tp* _M_start; + _Tp* _M_finish; + _Tp* _M_end_of_storage; + + _Tp* _M_allocate(size_t __n) + { return _M_data_allocator.allocate(__n); } + void _M_deallocate(_Tp* __p, size_t __n) + { if (__p) _M_data_allocator.deallocate(__p, __n); } +}; + +// Specialization for allocators that have the property that we don't +// actually have to store an allocator object. +template +class _Vector_alloc_base<_Tp, _Allocator, true> { +public: + typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Vector_alloc_base(const allocator_type&) + : _M_start(0), _M_finish(0), _M_end_of_storage(0) + {} + +protected: + _Tp* _M_start; + _Tp* _M_finish; + _Tp* _M_end_of_storage; + + typedef typename _Alloc_traits<_Tp, _Allocator>::_Alloc_type _Alloc_type; + _Tp* _M_allocate(size_t __n) + { return _Alloc_type::allocate(__n); } + void _M_deallocate(_Tp* __p, size_t __n) + { _Alloc_type::deallocate(__p, __n);} +}; + +template +struct _Vector_base + : public _Vector_alloc_base<_Tp, _Alloc, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> +{ + typedef _Vector_alloc_base<_Tp, _Alloc, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> + _Base; + typedef typename _Base::allocator_type allocator_type; + + _Vector_base(const allocator_type& __a) : _Base(__a) {} + _Vector_base(size_t __n, const allocator_type& __a) : _Base(__a) { + _M_start = _M_allocate(__n); + _M_finish = _M_start; + _M_end_of_storage = _M_start + __n; + } + + ~_Vector_base() { _M_deallocate(_M_start, _M_end_of_storage - _M_start); } +}; + +#else /* __STL_USE_STD_ALLOCATORS */ + +template +class _Vector_base { +public: + typedef _Alloc allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Vector_base(const _Alloc&) + : _M_start(0), _M_finish(0), _M_end_of_storage(0) {} + _Vector_base(size_t __n, const _Alloc&) + : _M_start(0), _M_finish(0), _M_end_of_storage(0) + { + _M_start = _M_allocate(__n); + _M_finish = _M_start; + _M_end_of_storage = _M_start + __n; + } + + ~_Vector_base() { _M_deallocate(_M_start, _M_end_of_storage - _M_start); } + +protected: + _Tp* _M_start; + _Tp* _M_finish; + _Tp* _M_end_of_storage; + + typedef simple_alloc<_Tp, _Alloc> _M_data_allocator; + _Tp* _M_allocate(size_t __n) + { return _M_data_allocator::allocate(__n); } + void _M_deallocate(_Tp* __p, size_t __n) + { _M_data_allocator::deallocate(__p, __n); } +}; + +#endif /* __STL_USE_STD_ALLOCATORS */ + +template +class vector : protected _Vector_base<_Tp, _Alloc> +{ +private: + typedef _Vector_base<_Tp, _Alloc> _Base; +public: + typedef _Tp value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type* iterator; + typedef const value_type* const_iterator; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + + typedef typename _Base::allocator_type allocator_type; + allocator_type get_allocator() const { return _Base::get_allocator(); } + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + typedef reverse_iterator const_reverse_iterator; + typedef reverse_iterator reverse_iterator; +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + typedef reverse_iterator const_reverse_iterator; + typedef reverse_iterator + reverse_iterator; +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +protected: +#ifdef __STL_HAS_NAMESPACES + using _Base::_M_allocate; + using _Base::_M_deallocate; + using _Base::_M_start; + using _Base::_M_finish; + using _Base::_M_end_of_storage; +#endif /* __STL_HAS_NAMESPACES */ + +protected: + void _M_insert_aux(iterator __position, const _Tp& __x); + void _M_insert_aux(iterator __position); + +public: + iterator begin() { return _M_start; } + const_iterator begin() const { return _M_start; } + iterator end() { return _M_finish; } + const_iterator end() const { return _M_finish; } + + reverse_iterator rbegin() + { return reverse_iterator(end()); } + const_reverse_iterator rbegin() const + { return const_reverse_iterator(end()); } + reverse_iterator rend() + { return reverse_iterator(begin()); } + const_reverse_iterator rend() const + { return const_reverse_iterator(begin()); } + + size_type size() const + { return size_type(end() - begin()); } + size_type max_size() const + { return size_type(-1) / sizeof(_Tp); } + size_type capacity() const + { return size_type(_M_end_of_storage - begin()); } + bool empty() const + { return begin() == end(); } + + reference operator[](size_type __n) { return *(begin() + __n); } + const_reference operator[](size_type __n) const { return *(begin() + __n); } + + explicit vector(const allocator_type& __a = allocator_type()) + : _Base(__a) {} + + vector(size_type __n, const _Tp& __value, + const allocator_type& __a = allocator_type()) + : _Base(__n, __a) + { _M_finish = uninitialized_fill_n(_M_start, __n, __value); } + + explicit vector(size_type __n) + : _Base(__n, allocator_type()) + { _M_finish = uninitialized_fill_n(_M_start, __n, _Tp()); } + + vector(const vector<_Tp, _Alloc>& __x) + : _Base(__x.size(), __x.get_allocator()) + { _M_finish = uninitialized_copy(__x.begin(), __x.end(), _M_start); } + +#ifdef __STL_MEMBER_TEMPLATES + // Check whether it's an integral type. If so, it's not an iterator. + template + vector(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) : _Base(__a) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_initialize_aux(__first, __last, _Integral()); + } + + template + void _M_initialize_aux(_Integer __n, _Integer __value, __true_type) { + _M_start = _M_allocate(__n); + _M_end_of_storage = _M_start + __n; + _M_finish = uninitialized_fill_n(_M_start, __n, __value); + } + + template + void _M_initialize_aux(_InputIterator __first, _InputIterator __last, + __false_type) { + _M_range_initialize(__first, __last, __ITERATOR_CATEGORY(__first)); + } + +#else + vector(const _Tp* __first, const _Tp* __last, + const allocator_type& __a = allocator_type()) + : _Base(__last - __first, __a) + { _M_finish = uninitialized_copy(__first, __last, _M_start); } +#endif /* __STL_MEMBER_TEMPLATES */ + + ~vector() { destroy(_M_start, _M_finish); } + + vector<_Tp, _Alloc>& operator=(const vector<_Tp, _Alloc>& __x); + void reserve(size_type __n) { + if (capacity() < __n) { + const size_type __old_size = size(); + iterator __tmp = _M_allocate_and_copy(__n, _M_start, _M_finish); + destroy(_M_start, _M_finish); + _M_deallocate(_M_start, _M_end_of_storage - _M_start); + _M_start = __tmp; + _M_finish = __tmp + __old_size; + _M_end_of_storage = _M_start + __n; + } + } + + // assign(), a generalized assignment member function. Two + // versions: one that takes a count, and one that takes a range. + // The range version is a member template, so we dispatch on whether + // or not the type is an integer. + + void assign(size_type __n, const _Tp& __val); + +#ifdef __STL_MEMBER_TEMPLATES + + template + void assign(_InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } + + template + void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { assign((size_type) __n, (_Tp) __val); } + + template + void _M_assign_dispatch(_InputIter __first, _InputIter __last, __false_type) + { _M_assign_aux(__first, __last, __ITERATOR_CATEGORY(__first)); } + + template + void _M_assign_aux(_InputIterator __first, _InputIterator __last, + input_iterator_tag); + + template + void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag); + +#endif /* __STL_MEMBER_TEMPLATES */ + + reference front() { return *begin(); } + const_reference front() const { return *begin(); } + reference back() { return *(end() - 1); } + const_reference back() const { return *(end() - 1); } + + void push_back(const _Tp& __x) { + if (_M_finish != _M_end_of_storage) { + construct(_M_finish, __x); + ++_M_finish; + } + else + _M_insert_aux(end(), __x); + } + void push_back() { + if (_M_finish != _M_end_of_storage) { + construct(_M_finish); + ++_M_finish; + } + else + _M_insert_aux(end()); + } + void swap(vector<_Tp, _Alloc>& __x) { + __STD::swap(_M_start, __x._M_start); + __STD::swap(_M_finish, __x._M_finish); + __STD::swap(_M_end_of_storage, __x._M_end_of_storage); + } + + iterator insert(iterator __position, const _Tp& __x) { + size_type __n = __position - begin(); + if (_M_finish != _M_end_of_storage && __position == end()) { + construct(_M_finish, __x); + ++_M_finish; + } + else + _M_insert_aux(__position, __x); + return begin() + __n; + } + iterator insert(iterator __position) { + size_type __n = __position - begin(); + if (_M_finish != _M_end_of_storage && __position == end()) { + construct(_M_finish); + ++_M_finish; + } + else + _M_insert_aux(__position); + return begin() + __n; + } +#ifdef __STL_MEMBER_TEMPLATES + // Check whether it's an integral type. If so, it's not an iterator. + template + void insert(iterator __pos, _InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_insert_dispatch(__pos, __first, __last, _Integral()); + } + + template + void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val, + __true_type) { + insert(__pos, (size_type) __n, (_Tp) __val); + } + + template + void _M_insert_dispatch(iterator __pos, + _InputIterator __first, _InputIterator __last, + __false_type) { + _M_range_insert(__pos, __first, __last, __ITERATOR_CATEGORY(__first)); + } +#else /* __STL_MEMBER_TEMPLATES */ + void insert(iterator __position, + const_iterator __first, const_iterator __last); +#endif /* __STL_MEMBER_TEMPLATES */ + + void insert (iterator __pos, size_type __n, const _Tp& __x); + + void pop_back() { + --_M_finish; + destroy(_M_finish); + } + iterator erase(iterator __position) { + if (__position + 1 != end()) + copy(__position + 1, _M_finish, __position); + --_M_finish; + destroy(_M_finish); + return __position; + } + iterator erase(iterator __first, iterator __last) { + iterator __i = copy(__last, _M_finish, __first); + destroy(__i, _M_finish); + _M_finish = _M_finish - (__last - __first); + return __first; + } + + void resize(size_type __new_size, const _Tp& __x) { + if (__new_size < size()) + erase(begin() + __new_size, end()); + else + insert(end(), __new_size - size(), __x); + } + void resize(size_type __new_size) { resize(__new_size, _Tp()); } + void clear() { erase(begin(), end()); } + +protected: + +#ifdef __STL_MEMBER_TEMPLATES + template + iterator _M_allocate_and_copy(size_type __n, _ForwardIterator __first, + _ForwardIterator __last) +{ + iterator __result = _M_allocate(__n); + __STL_TRY { + uninitialized_copy(__first, __last, __result); + return __result; + } + __STL_UNWIND(_M_deallocate(__result, __n)); + } +#else /* __STL_MEMBER_TEMPLATES */ + iterator _M_allocate_and_copy(size_type __n, const_iterator __first, + const_iterator __last) + { + iterator __result = _M_allocate(__n); + __STL_TRY { + uninitialized_copy(__first, __last, __result); + return __result; + } + __STL_UNWIND(_M_deallocate(__result, __n)); + } +#endif /* __STL_MEMBER_TEMPLATES */ + + +#ifdef __STL_MEMBER_TEMPLATES + template + void _M_range_initialize(_InputIterator __first, + _InputIterator __last, input_iterator_tag) + { + for ( ; __first != __last; ++__first) + push_back(*__first); + } + + // This function is only called by the constructor. + template + void _M_range_initialize(_ForwardIterator __first, + _ForwardIterator __last, forward_iterator_tag) + { + size_type __n = 0; + distance(__first, __last, __n); + _M_start = _M_allocate(__n); + _M_end_of_storage = _M_start + __n; + _M_finish = uninitialized_copy(__first, __last, _M_start); + } + + template + void _M_range_insert(iterator __pos, + _InputIterator __first, _InputIterator __last, + input_iterator_tag); + + template + void _M_range_insert(iterator __pos, + _ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag); + +#endif /* __STL_MEMBER_TEMPLATES */ +}; + +template +inline bool +operator==(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) +{ + return __x.size() == __y.size() && + equal(__x.begin(), __x.end(), __y.begin()); +} + +template +inline bool +operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) +{ + return lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +inline void swap(vector<_Tp, _Alloc>& __x, vector<_Tp, _Alloc>& __y) +{ + __x.swap(__y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +template +vector<_Tp,_Alloc>& +vector<_Tp,_Alloc>::operator=(const vector<_Tp, _Alloc>& __x) +{ + if (&__x != this) { + const size_type __xlen = __x.size(); + if (__xlen > capacity()) { + iterator __tmp = _M_allocate_and_copy(__xlen, __x.begin(), __x.end()); + destroy(_M_start, _M_finish); + _M_deallocate(_M_start, _M_end_of_storage - _M_start); + _M_start = __tmp; + _M_end_of_storage = _M_start + __xlen; + } + else if (size() >= __xlen) { + iterator __i = copy(__x.begin(), __x.end(), begin()); + destroy(__i, _M_finish); + } + else { + copy(__x.begin(), __x.begin() + size(), _M_start); + uninitialized_copy(__x.begin() + size(), __x.end(), _M_finish); + } + _M_finish = _M_start + __xlen; + } + return *this; +} + +template +void vector<_Tp, _Alloc>::assign(size_t __n, const value_type& __val) { + if (__n > capacity()) { + vector<_Tp, _Alloc> __tmp(__n, __val, get_allocator()); + __tmp.swap(*this); + } + else if (__n > size()) { + fill(begin(), end(), __val); + _M_finish = uninitialized_fill_n(_M_finish, __n - size(), __val); + } + else + erase(fill_n(begin(), __n, __val), end()); +} + +#ifdef __STL_MEMBER_TEMPLATES + +template template +void vector<_Tp, _Alloc>::_M_assign_aux(_InputIter __first, _InputIter __last, + input_iterator_tag) { + iterator __cur = begin(); + for ( ; __first != __last && __cur != end(); ++__cur, ++__first) + *__cur = *__first; + if (__first == __last) + erase(__cur, end()); + else + insert(end(), __first, __last); +} + +template template +void +vector<_Tp, _Alloc>::_M_assign_aux(_ForwardIter __first, _ForwardIter __last, + forward_iterator_tag) { + size_type __len = 0; + distance(__first, __last, __len); + + if (__len > capacity()) { + iterator __tmp = _M_allocate_and_copy(__len, __first, __last); + destroy(_M_start, _M_finish); + _M_deallocate(_M_start, _M_end_of_storage - _M_start); + _M_start = __tmp; + _M_end_of_storage = _M_finish = _M_start + __len; + } + else if (size() >= __len) { + iterator __new_finish = copy(__first, __last, _M_start); + destroy(__new_finish, _M_finish); + _M_finish = __new_finish; + } + else { + _ForwardIter __mid = __first; + advance(__mid, size()); + copy(__first, __mid, _M_start); + _M_finish = uninitialized_copy(__mid, __last, _M_finish); + } +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +template +void +vector<_Tp, _Alloc>::_M_insert_aux(iterator __position, const _Tp& __x) +{ + if (_M_finish != _M_end_of_storage) { + construct(_M_finish, *(_M_finish - 1)); + ++_M_finish; + _Tp __x_copy = __x; + copy_backward(__position, _M_finish - 2, _M_finish - 1); + *__position = __x_copy; + } + else { + const size_type __old_size = size(); + const size_type __len = __old_size != 0 ? 2 * __old_size : 1; + iterator __new_start = _M_allocate(__len); + iterator __new_finish = __new_start; + __STL_TRY { + __new_finish = uninitialized_copy(_M_start, __position, __new_start); + construct(__new_finish, __x); + ++__new_finish; + __new_finish = uninitialized_copy(__position, _M_finish, __new_finish); + } + __STL_UNWIND((destroy(__new_start,__new_finish), + _M_deallocate(__new_start,__len))); + destroy(begin(), end()); + _M_deallocate(_M_start, _M_end_of_storage - _M_start); + _M_start = __new_start; + _M_finish = __new_finish; + _M_end_of_storage = __new_start + __len; + } +} + +template +void +vector<_Tp, _Alloc>::_M_insert_aux(iterator __position) +{ + if (_M_finish != _M_end_of_storage) { + construct(_M_finish, *(_M_finish - 1)); + ++_M_finish; + copy_backward(__position, _M_finish - 2, _M_finish - 1); + *__position = _Tp(); + } + else { + const size_type __old_size = size(); + const size_type __len = __old_size != 0 ? 2 * __old_size : 1; + iterator __new_start = _M_allocate(__len); + iterator __new_finish = __new_start; + __STL_TRY { + __new_finish = uninitialized_copy(_M_start, __position, __new_start); + construct(__new_finish); + ++__new_finish; + __new_finish = uninitialized_copy(__position, _M_finish, __new_finish); + } + __STL_UNWIND((destroy(__new_start,__new_finish), + _M_deallocate(__new_start,__len))); + destroy(begin(), end()); + _M_deallocate(_M_start, _M_end_of_storage - _M_start); + _M_start = __new_start; + _M_finish = __new_finish; + _M_end_of_storage = __new_start + __len; + } +} + +template +void vector<_Tp, _Alloc>::insert(iterator __position, size_type __n, + const _Tp& __x) +{ + if (__n != 0) { + if (size_type(_M_end_of_storage - _M_finish) >= __n) { + _Tp __x_copy = __x; + const size_type __elems_after = _M_finish - __position; + iterator __old_finish = _M_finish; + if (__elems_after > __n) { + uninitialized_copy(_M_finish - __n, _M_finish, _M_finish); + _M_finish += __n; + copy_backward(__position, __old_finish - __n, __old_finish); + fill(__position, __position + __n, __x_copy); + } + else { + uninitialized_fill_n(_M_finish, __n - __elems_after, __x_copy); + _M_finish += __n - __elems_after; + uninitialized_copy(__position, __old_finish, _M_finish); + _M_finish += __elems_after; + fill(__position, __old_finish, __x_copy); + } + } + else { + const size_type __old_size = size(); + const size_type __len = __old_size + max(__old_size, __n); + iterator __new_start = _M_allocate(__len); + iterator __new_finish = __new_start; + __STL_TRY { + __new_finish = uninitialized_copy(_M_start, __position, __new_start); + __new_finish = uninitialized_fill_n(__new_finish, __n, __x); + __new_finish + = uninitialized_copy(__position, _M_finish, __new_finish); + } + __STL_UNWIND((destroy(__new_start,__new_finish), + _M_deallocate(__new_start,__len))); + destroy(_M_start, _M_finish); + _M_deallocate(_M_start, _M_end_of_storage - _M_start); + _M_start = __new_start; + _M_finish = __new_finish; + _M_end_of_storage = __new_start + __len; + } + } +} + +#ifdef __STL_MEMBER_TEMPLATES + +template template +void +vector<_Tp, _Alloc>::_M_range_insert(iterator __pos, + _InputIterator __first, + _InputIterator __last, + input_iterator_tag) +{ + for ( ; __first != __last; ++__first) { + __pos = insert(__pos, *__first); + ++__pos; + } +} + +template template +void +vector<_Tp, _Alloc>::_M_range_insert(iterator __position, + _ForwardIterator __first, + _ForwardIterator __last, + forward_iterator_tag) +{ + if (__first != __last) { + size_type __n = 0; + distance(__first, __last, __n); + if (size_type(_M_end_of_storage - _M_finish) >= __n) { + const size_type __elems_after = _M_finish - __position; + iterator __old_finish = _M_finish; + if (__elems_after > __n) { + uninitialized_copy(_M_finish - __n, _M_finish, _M_finish); + _M_finish += __n; + copy_backward(__position, __old_finish - __n, __old_finish); + copy(__first, __last, __position); + } + else { + _ForwardIterator __mid = __first; + advance(__mid, __elems_after); + uninitialized_copy(__mid, __last, _M_finish); + _M_finish += __n - __elems_after; + uninitialized_copy(__position, __old_finish, _M_finish); + _M_finish += __elems_after; + copy(__first, __mid, __position); + } + } + else { + const size_type __old_size = size(); + const size_type __len = __old_size + max(__old_size, __n); + iterator __new_start = _M_allocate(__len); + iterator __new_finish = __new_start; + __STL_TRY { + __new_finish = uninitialized_copy(_M_start, __position, __new_start); + __new_finish = uninitialized_copy(__first, __last, __new_finish); + __new_finish + = uninitialized_copy(__position, _M_finish, __new_finish); + } + __STL_UNWIND((destroy(__new_start,__new_finish), + _M_deallocate(__new_start,__len))); + destroy(_M_start, _M_finish); + _M_deallocate(_M_start, _M_end_of_storage - _M_start); + _M_start = __new_start; + _M_finish = __new_finish; + _M_end_of_storage = __new_start + __len; + } + } +} + +#else /* __STL_MEMBER_TEMPLATES */ + +template +void +vector<_Tp, _Alloc>::insert(iterator __position, + const_iterator __first, + const_iterator __last) +{ + if (__first != __last) { + size_type __n = 0; + distance(__first, __last, __n); + if (size_type(_M_end_of_storage - _M_finish) >= __n) { + const size_type __elems_after = _M_finish - __position; + iterator __old_finish = _M_finish; + if (__elems_after > __n) { + uninitialized_copy(_M_finish - __n, _M_finish, _M_finish); + _M_finish += __n; + copy_backward(__position, __old_finish - __n, __old_finish); + copy(__first, __last, __position); + } + else { + uninitialized_copy(__first + __elems_after, __last, _M_finish); + _M_finish += __n - __elems_after; + uninitialized_copy(__position, __old_finish, _M_finish); + _M_finish += __elems_after; + copy(__first, __first + __elems_after, __position); + } + } + else { + const size_type __old_size = size(); + const size_type __len = __old_size + max(__old_size, __n); + iterator __new_start = _M_allocate(__len); + iterator __new_finish = __new_start; + __STL_TRY { + __new_finish = uninitialized_copy(_M_start, __position, __new_start); + __new_finish = uninitialized_copy(__first, __last, __new_finish); + __new_finish + = uninitialized_copy(__position, _M_finish, __new_finish); + } + __STL_UNWIND((destroy(__new_start,__new_finish), + _M_deallocate(__new_start,__len))); + destroy(_M_start, _M_finish); + _M_deallocate(_M_start, _M_end_of_storage - _M_start); + _M_start = __new_start; + _M_finish = __new_finish; + _M_end_of_storage = __new_start + __len; + } + } +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#pragma reset woff 1375 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_VECTOR_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/stream.h b/headers/cpp/stream.h new file mode 100644 index 0000000000..90f8c1f278 --- /dev/null +++ b/headers/cpp/stream.h @@ -0,0 +1,59 @@ +/* +Copyright (C) 1993, 1999 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + +#ifndef _COMPAT_STREAM_H +#define _COMPAT_STREAM_H + +// Compatibility with old library. +// DO NOT USE THESE FUNCTIONS IN NEW CODE! +// They are obsolete, non-standard, and non-reentrant. + +#define _STREAM_COMPAT +#include + +extern "C++" { +extern char* form(const char*, ...); + +extern char* dec(long, int=0); +extern char* dec(int, int=0); +extern char* dec(unsigned long, int=0); +extern char* dec(unsigned int, int=0); + +extern char* hex(long, int=0); +extern char* hex(int, int=0); +extern char* hex(unsigned long, int=0); +extern char* hex(unsigned int, int=0); + +extern char* oct(long, int=0); +extern char* oct(int, int=0); +extern char* oct(unsigned long, int=0); +extern char* oct(unsigned int, int=0); + +char* chr(char ch, int width = 0); +char* str(const char* s, int width = 0); + +inline istream& WS(istream& __str) { return ws(__str); } +} // extern "C++" + +#endif /* !_COMPAT_STREAM_H */ diff --git a/headers/cpp/streambuf.h b/headers/cpp/streambuf.h new file mode 100644 index 0000000000..193c499382 --- /dev/null +++ b/headers/cpp/streambuf.h @@ -0,0 +1,490 @@ +/* This is part of libio/iostream, providing -*- C++ -*- input/output. +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + +#ifndef _STREAMBUF_H +#define _STREAMBUF_H +#ifdef __GNUG__ +#pragma interface +#endif + +/* #define _G_IO_THROW */ /* Not implemented: ios::failure */ + +#define _IO_NEW_STREAMS // new optimizated stream representation + +extern "C" { +#include +} +//#include <_G_config.h> +#ifdef _G_NEED_STDARG_H +#include +#endif +#ifndef _IO_va_list +#define _IO_va_list char * +#endif + +#ifndef EOF +#define EOF (-1) +#endif +#ifndef NULL +#ifdef __GNUG__ +#define NULL (__null) +#else +#define NULL (0) +#endif +#endif + +#ifndef _IO_wchar_t +#if _G_IO_IO_FILE_VERSION == 0x20001 +#define _IO_wchar_t _G_wchar_t +#else +#define _IO_wchar_t short +#endif +#endif + +extern "C++" { +class istream; /* Work-around for a g++ name mangling bug. Fixed in 2.6. */ +class ostream; class streambuf; + +// In case some header files defines these as macros. +#undef open +#undef close + +#if defined(_G_IO_IO_FILE_VERSION) && _G_IO_IO_FILE_VERSION == 0x20001 +typedef _IO_off64_t streamoff; +typedef _IO_off64_t streampos; +#else +typedef _IO_off_t streamoff; +typedef _IO_off_t streampos; +#endif +typedef _IO_ssize_t streamsize; + +typedef unsigned long __fmtflags; +typedef unsigned char __iostate; + +struct _ios_fields +{ // The data members of an ios. + streambuf *_strbuf; + ostream* _tie; + int _width; + __fmtflags _flags; + _IO_wchar_t _fill; + __iostate _state; + __iostate _exceptions; + int _precision; + + void *_arrays; /* Support for ios::iword and ios::pword. */ +}; + +#define _IOS_GOOD 0 +#define _IOS_EOF 1 +#define _IOS_FAIL 2 +#define _IOS_BAD 4 + +#define _IO_INPUT 1 +#define _IO_OUTPUT 2 +#define _IO_ATEND 4 +#define _IO_APPEND 8 +#define _IO_TRUNC 16 +#define _IO_NOCREATE 32 +#define _IO_NOREPLACE 64 +#define _IO_BIN 128 + +#ifdef _STREAM_COMPAT +enum state_value { + _good = _IOS_GOOD, + _eof = _IOS_EOF, + _fail = _IOS_FAIL, + _bad = _IOS_BAD }; +enum open_mode { + input = _IO_INPUT, + output = _IO_OUTPUT, + atend = _IO_ATEND, + append = _IO_APPEND }; +#endif + +class ios : public _ios_fields { + ios& operator=(ios&); /* Not allowed! */ + ios (const ios&); /* Not allowed! */ + public: + typedef __fmtflags fmtflags; + typedef int iostate; + typedef int openmode; + typedef _IO_ssize_t streamsize; + enum io_state { + goodbit = _IOS_GOOD, + eofbit = _IOS_EOF, + failbit = _IOS_FAIL, + badbit = _IOS_BAD }; + enum open_mode { + in = _IO_INPUT, + out = _IO_OUTPUT, + ate = _IO_ATEND, + app = _IO_APPEND, + trunc = _IO_TRUNC, + nocreate = _IO_NOCREATE, + noreplace = _IO_NOREPLACE, + bin = _IOS_BIN, // Deprecated - ANSI uses ios::binary. + binary = _IOS_BIN }; + enum seek_dir { beg, cur, end}; + typedef enum seek_dir seekdir; + // NOTE: If adding flags here, before to update ios::bitalloc(). + enum { skipws=_IO_SKIPWS, + left=_IO_LEFT, right=_IO_RIGHT, internal=_IO_INTERNAL, + dec=_IO_DEC, oct=_IO_OCT, hex=_IO_HEX, + showbase=_IO_SHOWBASE, showpoint=_IO_SHOWPOINT, + uppercase=_IO_UPPERCASE, showpos=_IO_SHOWPOS, + scientific=_IO_SCIENTIFIC, fixed=_IO_FIXED, + unitbuf=_IO_UNITBUF, stdio=_IO_STDIO +#ifndef _IO_NEW_STREAMS + , dont_close=_IO_DONT_CLOSE // Don't delete streambuf on stream destruction +#endif + }; + enum { // Masks. + basefield=dec+oct+hex, + floatfield = scientific+fixed, + adjustfield = left+right+internal + }; + +#ifdef _IO_THROW + class failure : public xmsg { + ios* _stream; + public: + failure(ios* stream) { _stream = stream; } + failure(string cause, ios* stream) { _stream = stream; } + ios* rdios() const { return _stream; } + }; +#endif + + ostream* tie() const { return _tie; } + ostream* tie(ostream* val) { ostream* save=_tie; _tie=val; return save; } + + // Methods to change the format state. + _IO_wchar_t fill() const { return _fill; } + _IO_wchar_t fill(_IO_wchar_t newf) + {_IO_wchar_t oldf = _fill; _fill = newf; return oldf;} + fmtflags flags() const { return _flags; } + fmtflags flags(fmtflags new_val) { + fmtflags old_val = _flags; _flags = new_val; return old_val; } + int precision() const { return _precision; } + int precision(int newp) { + unsigned short oldp = _precision; _precision = (unsigned short)newp; + return oldp; } + fmtflags setf(fmtflags val) { + fmtflags oldbits = _flags; + _flags |= val; return oldbits; } + fmtflags setf(fmtflags val, fmtflags mask) { + fmtflags oldbits = _flags; + _flags = (_flags & ~mask) | (val & mask); return oldbits; } + fmtflags unsetf(fmtflags mask) { + fmtflags oldbits = _flags; + _flags &= ~mask; return oldbits; } + int width() const { return _width; } + int width(int val) { int save = _width; _width = val; return save; } + +#ifdef _IO_THROW + void _throw_failure() const { throw new ios::failure(this); } +#else + void _throw_failure() const { } +#endif + void clear(iostate state = 0) { + _state = _strbuf ? state : state|badbit; + if (_state & _exceptions) _throw_failure(); } + void set(iostate flag) { _state |= flag; + if (_state & _exceptions) _throw_failure(); } + void setstate(iostate flag) { _state |= flag; // ANSI + if (_state & _exceptions) _throw_failure(); } + int good() const { return _state == 0; } + int eof() const { return _state & ios::eofbit; } + int fail() const { return _state & (ios::badbit|ios::failbit); } + int bad() const { return _state & ios::badbit; } + iostate rdstate() const { return _state; } + operator void*() const { return fail() ? (void*)0 : (void*)(-1); } + int operator!() const { return fail(); } + iostate exceptions() const { return _exceptions; } + void exceptions(iostate enable) { + _exceptions = enable; + if (_state & _exceptions) _throw_failure(); } + + streambuf* rdbuf() const { return _strbuf; } + streambuf* rdbuf(streambuf *_s) { + streambuf *_old = _strbuf; _strbuf = _s; clear (); return _old; } + + static int sync_with_stdio(int on); + static void sync_with_stdio() { sync_with_stdio(1); } + static fmtflags bitalloc(); + static int xalloc(); + void*& pword(int); + void* pword(int) const; + long& iword(int); + long iword(int) const; + +#ifdef _STREAM_COMPAT + void unset(state_value flag) { _state &= ~flag; } + void close(); + int is_open(); + int readable(); + int writable(); +#endif + + // Used to initialize standard streams. Not needed in this implementation. + class Init { + public: + Init () { } + }; + + protected: + inline ios(streambuf* sb = 0, ostream* tie_to = 0); + inline virtual ~ios(); + inline void init(streambuf* sb, ostream* tie = 0); +}; + +#if __GNUG__==1 +typedef int _seek_dir; +#else +typedef ios::seek_dir _seek_dir; +#endif + +// Magic numbers and bits for the _flags field. +// The magic numbers use the high-order bits of _flags; +// the remaining bits are abailable for variable flags. +// Note: The magic numbers must all be negative if stdio +// emulation is desired. + +// A streammarker remembers a position in a buffer. +// You are guaranteed to be able to seek back to it if it is saving(). +class streammarker : private _IO_marker { + friend class streambuf; + void set_offset(int offset) { _pos = offset; } + public: + streammarker(streambuf *sb); + ~streammarker(); + int saving() { return 1; } + int delta(streammarker&); + int delta(); +}; + +struct streambuf : public _IO_FILE { // protected?? + friend class ios; + friend class istream; + friend class ostream; + friend class streammarker; + const void *&_vtable() { return *(const void**)((_IO_FILE*)this + 1); } + protected: + static streambuf* _list_all; /* List of open streambufs. */ + _IO_FILE*& xchain() { return _chain; } + void _un_link(); + void _link_in(); + char* gptr() const + { return _IO_file_flags & _IO_IN_BACKUP ? _IO_save_base : _IO_read_ptr; } + char* pptr() const { return _IO_write_ptr; } + char* egptr() const + { return _IO_file_flags & _IO_IN_BACKUP ? _IO_save_end : _IO_read_end; } + char* epptr() const { return _IO_write_end; } + char* pbase() const { return _IO_write_base; } + char* eback() const + { return _IO_file_flags & _IO_IN_BACKUP ? _IO_save_base : _IO_read_base;} + char* base() const { return _IO_buf_base; } + char* ebuf() const { return _IO_buf_end; } + int blen() const { return _IO_buf_end - _IO_buf_base; } + void xput_char(char c) { *_IO_write_ptr++ = c; } + int xflags() { return _IO_file_flags; } + int xflags(int f) {int fl = _IO_file_flags; _IO_file_flags = f; return fl;} + void xsetflags(int f) { _IO_file_flags |= f; } + void xsetflags(int f, int mask) + { _IO_file_flags = (_IO_file_flags & ~mask) | (f & mask); } + void gbump(int n) + { _IO_file_flags & _IO_IN_BACKUP ? (_IO_save_base+=n):(_IO_read_ptr+=n);} + void pbump(int n) { _IO_write_ptr += n; } + void setb(char* b, char* eb, int a=0); + void setp(char* p, char* ep) + { _IO_write_base=_IO_write_ptr=p; _IO_write_end=ep; } + void setg(char* eb, char* g, char *eg) { + if (_IO_file_flags & _IO_IN_BACKUP) _IO_free_backup_area(this); + _IO_read_base = eb; _IO_read_ptr = g; _IO_read_end = eg; } + char *shortbuf() { return _shortbuf; } + + int in_backup() { return _flags & _IO_IN_BACKUP; } + // The start of the main get area: FIXME: wrong for write-mode filebuf? + char *Gbase() { return in_backup() ? _IO_save_base : _IO_read_base; } + // The end of the main get area: + char *eGptr() { return in_backup() ? _IO_save_end : _IO_read_end; } + // The start of the backup area: + char *Bbase() { return in_backup() ? _IO_read_base : _IO_save_base; } + char *Bptr() { return _IO_backup_base; } + // The end of the backup area: + char *eBptr() { return in_backup() ? _IO_read_end : _IO_save_end; } + char *Nbase() { return _IO_save_base; } + char *eNptr() { return _IO_save_end; } + int have_backup() { return _IO_save_base != NULL; } + int have_markers() { return _markers != NULL; } + void free_backup_area(); + void unsave_markers(); // Make all streammarkers !saving(). + int put_mode() { return _flags & _IO_CURRENTLY_PUTTING; } + int switch_to_get_mode(); + + streambuf(int flags=0); + public: + static int flush_all(); + static void flush_all_linebuffered(); // Flush all line buffered files. + virtual ~streambuf(); + virtual int overflow(int c = EOF); // Leave public for now + virtual int underflow(); // Leave public for now + virtual int uflow(); // Leave public for now + virtual int pbackfail(int c); +// virtual int showmany (); + virtual streamsize xsputn(const char* s, streamsize n); + virtual streamsize xsgetn(char* s, streamsize n); + virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out); + virtual streampos seekpos(streampos pos, int mode = ios::in|ios::out); + + streampos pubseekoff(streamoff o, _seek_dir d, int mode=ios::in|ios::out) + { return _IO_seekoff (this, o, d, mode); } + streampos pubseekpos(streampos pos, int mode = ios::in|ios::out) + { return _IO_seekpos (this, pos, mode); } + streampos sseekoff(streamoff, _seek_dir, int mode=ios::in|ios::out); + streampos sseekpos(streampos pos, int mode = ios::in|ios::out); + virtual streambuf* setbuf(char* p, int len); + virtual int sync(); + virtual int doallocate(); + + int seekmark(streammarker& mark, int delta = 0); + int sputbackc(char c); + int sungetc(); + int unbuffered() { return _flags & _IO_UNBUFFERED ? 1 : 0; } + int linebuffered() { return _flags & _IO_LINE_BUF ? 1 : 0; } + void unbuffered(int i) + { if (i) _flags |= _IO_UNBUFFERED; else _flags &= ~_IO_UNBUFFERED; } + void linebuffered(int i) + { if (i) _flags |= _IO_LINE_BUF; else _flags &= ~_IO_LINE_BUF; } + int allocate() { // For AT&T compatibility + if (base() || unbuffered()) return 0; + else return doallocate(); } + // Allocate a buffer if needed; use _shortbuf if appropriate. + void allocbuf() { if (base() == NULL) doallocbuf(); } + void doallocbuf(); + int in_avail() { return _IO_read_end - _IO_read_ptr; } + int out_waiting() { return _IO_write_ptr - _IO_write_base; } + streamsize sputn(const char* s, streamsize n) { return xsputn(s, n); } + streamsize padn(char pad, streamsize n) { return _IO_padn(this, pad, n); } + streamsize sgetn(char* s, streamsize n) { return _IO_sgetn(this, s, n); } + int ignore(int); + int get_column(); + int set_column(int); + long sgetline(char* buf, _IO_size_t n, char delim, int putback_delim); + int sputc(int c) { return _IO_putc(c, this); } + int sbumpc() { return _IO_getc(this); } + int sgetc() { return _IO_peekc(this); } + int snextc() { + if (_IO_read_ptr >= _IO_read_end && __underflow(this) == EOF) + return EOF; + else return _IO_read_ptr++, sgetc(); } + void stossc() { if (_IO_read_ptr < _IO_read_end) _IO_read_ptr++; } + int vscan(char const *fmt0, _IO_va_list ap, ios* stream = NULL); + int scan(char const *fmt0 ...); + int vform(char const *fmt0, _IO_va_list ap); + int form(char const *fmt0 ...); +#if 0 /* Work in progress */ + int column(); // Current column number (of put pointer). -1 is unknown. + void column(int c); // Set column number of put pointer to c. +#endif + virtual streamsize sys_read(char* buf, streamsize size); + virtual streamsize sys_write(const char*, streamsize); + virtual streampos sys_seek(streamoff, _seek_dir); + virtual int sys_close(); + virtual int sys_stat(void*); // Actually, a (struct stat*) +#if _G_IO_IO_FILE_VERSION == 0x20001 + virtual int showmanyc(); + virtual void imbue(void *); +#endif +}; + +// A backupbuf is a streambuf with full backup and savepoints on reading. +// All standard streambufs in the GNU iostream library are backupbufs. + +class filebuf : public streambuf { + protected: + void init(); + public: + static const int openprot; // Non-ANSI AT&T-ism: Default open protection. + filebuf(); + filebuf(int fd); + filebuf(int fd, char* p, int len); +#if !_IO_UNIFIED_JUMPTABLES + static filebuf *__new(); +#endif + ~filebuf(); + filebuf* attach(int fd); + filebuf* open(const char *filename, const char *mode); + filebuf* open(const char *filename, ios::openmode mode, int prot = 0664); + virtual int underflow(); + virtual int overflow(int c = EOF); + int is_open() const { return _fileno >= 0; } + int fd() const { return is_open() ? _fileno : EOF; } + filebuf* close(); + virtual int doallocate(); + virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out); + virtual streambuf* setbuf(char* p, int len); + streamsize xsputn(const char* s, streamsize n); + streamsize xsgetn(char* s, streamsize n); + virtual int sync(); + protected: // See documentation in filebuf.C. +// virtual int pbackfail(int c); + int is_reading() { return eback() != egptr(); } + char* cur_ptr() { return is_reading() ? gptr() : pptr(); } + /* System's idea of pointer */ + char* file_ptr() { return eGptr(); } + // Low-level operations (Usually invoke system calls.) + virtual streamsize sys_read(char* buf, streamsize size); + virtual streampos sys_seek(streamoff, _seek_dir); + virtual streamsize sys_write(const char*, streamsize); + virtual int sys_stat(void*); // Actually, a (struct stat*) + virtual int sys_close(); +#if 0 + virtual uflow; + virtual showmany; +#endif +}; + +inline void ios::init(streambuf* sb, ostream* tie_to) { + _state = sb ? ios::goodbit : ios::badbit; _exceptions=0; + _strbuf=sb; _tie = tie_to; _width=0; _fill=' '; +#ifdef _IO_NEW_STREAMS + _flags=ios::skipws|ios::dec; +#else + _flags=ios::skipws|ios::dec|ios::dont_close; +#endif + _precision=6; _arrays = 0; } + +inline ios::ios(streambuf* sb, ostream* tie_to) { init(sb, tie_to); } + +inline ios::~ios() { +#ifndef _IO_NEW_STREAMS + if (!(_flags & (unsigned int)ios::dont_close)) delete rdbuf(); +#endif + // It is safe to use naked operator delete[] as we know elements have no + // dtor, and g++ does not add a new[] cookie for such cases. + operator delete[] (_arrays); +} +} // extern "C++" +#endif /* _STREAMBUF_H */ diff --git a/headers/cpp/strfile.h b/headers/cpp/strfile.h new file mode 100644 index 0000000000..85e83a95d0 --- /dev/null +++ b/headers/cpp/strfile.h @@ -0,0 +1,71 @@ +/* Copyright (C) 1993, 1997, 1998 Free Software Foundation, Inc. + This file is part of the GNU IO Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this library; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, if you link this library with files + compiled with a GNU compiler to produce an executable, this does + not cause the resulting executable to be covered by the GNU General + 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 +#ifdef TODO +Merge into libio.h ? +#endif + +#ifndef __PMT +# ifdef __STDC__ +# define __PMT(p) p +# else +# define __PMT(p) () +# endif +#endif /*!__P*/ + +typedef void *(*_IO_alloc_type) __PMT ((_IO_size_t)); +typedef void (*_IO_free_type) __PMT ((void*)); + +struct _IO_str_fields +{ + _IO_alloc_type _allocate_buffer; + _IO_free_type _free_buffer; +}; + +/* This is needed for the Irix6 N32 ABI, which has a 64 bit off_t type, + but a 32 bit pointer type. In this case, we get 4 bytes of padding + after the vtable pointer. Putting them in a structure together solves + this problem. */ + +struct _IO_streambuf +{ + struct _IO_FILE _f; + const void *_vtable; +}; + +typedef struct _IO_strfile_ +{ + struct _IO_streambuf _sbf; + struct _IO_str_fields _s; +} _IO_strfile; + +/* dynamic: set when the array object is allocated (or reallocated) as + necessary to hold a character sequence that can change in length. */ +#define _IO_STR_DYNAMIC(FP) ((FP)->_s._allocate_buffer != (_IO_alloc_type)0) + +/* frozen: set when the program has requested that the array object not + be altered, reallocated, or freed. */ +#define _IO_STR_FROZEN(FP) ((FP)->_f._IO_file_flags & _IO_USER_BUF) diff --git a/headers/cpp/string b/headers/cpp/string new file mode 100644 index 0000000000..fa6f1abaa7 --- /dev/null +++ b/headers/cpp/string @@ -0,0 +1,13 @@ +// Main header for the -*- C++ -*- string classes. + +#ifndef __STRING__ +#define __STRING__ + +#include + +extern "C++" { +typedef basic_string string; +// typedef basic_string wstring; +} // extern "C++" + +#endif diff --git a/headers/cpp/strstream b/headers/cpp/strstream new file mode 100644 index 0000000000..ee360e0b7e --- /dev/null +++ b/headers/cpp/strstream @@ -0,0 +1,7 @@ +// -*- C++ -*- forwarding header. +// This file is part of the GNU ANSI C++ Library. + +#ifndef __STRSTREAM__ +#define __STRSTREAM__ +#include +#endif diff --git a/headers/cpp/strstream.h b/headers/cpp/strstream.h new file mode 100644 index 0000000000..967e5b0b76 --- /dev/null +++ b/headers/cpp/strstream.h @@ -0,0 +1,113 @@ +/* This is part of libio/iostream, providing -*- C++ -*- input/output. +Copyright (C) 1993, 1999 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + +/* Written by Per Bothner (bothner@cygnus.com). */ + +#ifndef __STRSTREAM_H +#define __STRSTREAM_H +#ifdef __GNUG__ +#pragma interface +#endif +#include +#include + +extern "C++" { +class strstreambuf : public streambuf +{ + struct _IO_str_fields _s; + friend class istrstream; + + void init_dynamic(_IO_alloc_type alloc, _IO_free_type free, + int initial_size = 0); + void init_static(char *ptr, int size, char *pstart); + void init_readonly(const char *ptr, int size); + protected: + virtual int overflow(int = EOF); + virtual int underflow(); + virtual int pbackfail(int c); + public: + virtual ~strstreambuf(); + strstreambuf() { init_dynamic(0, 0); } + strstreambuf(int initial_size) { init_dynamic(0, 0, initial_size); } + strstreambuf(void *(*__alloc)(_IO_size_t), void (*__free)(void*)) + { init_dynamic(__alloc, __free); } + strstreambuf(char *ptr, int size, char *pstart = NULL) + { init_static(ptr, size, pstart); } + strstreambuf(unsigned char *ptr, int size, unsigned char *pstart = NULL) + { init_static((char*)ptr, size, (char*)pstart); } + strstreambuf(const char *ptr, int size) + { init_readonly(ptr, size); } + strstreambuf(const unsigned char *ptr, int size) + { init_readonly((const char*)ptr, size); } + strstreambuf(signed char *ptr, int size, signed char *pstart = NULL) + { init_static((char*)ptr, size, (char*)pstart); } + strstreambuf(const signed char *ptr, int size) + { init_readonly((const char*)ptr, size); } + // Note: frozen() is always true if !_IO_STR_DYNAMIC(this). + int frozen() { return _flags & _IO_USER_BUF ? 1 : 0; } + void freeze(int n=1) + { if (_IO_STR_DYNAMIC(this)) + { if (n) _flags |= _IO_USER_BUF; else _flags &= ~_IO_USER_BUF; } } + _IO_ssize_t pcount(); + char *str(); + virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out); +}; + +class strstreambase : virtual public ios { + protected: + strstreambuf __my_sb; + public: + strstreambuf* rdbuf() { return &__my_sb; } + protected: + strstreambase() { init (&__my_sb); } + strstreambase(char *cp, int n, int mode=ios::out); +}; + +class istrstream : public strstreambase, public istream { + public: + istrstream(const char*, int=0); +}; + +class ostrstream : public strstreambase, public ostream { + public: + ostrstream() { } + ostrstream(char *cp, int n, int mode=ios::out) :strstreambase(cp,n,mode){} + _IO_ssize_t pcount() { return ((strstreambuf*)_strbuf)->pcount(); } + char *str() { return ((strstreambuf*)_strbuf)->str(); } + void freeze(int n = 1) { ((strstreambuf*)_strbuf)->freeze(n); } + int frozen() { return ((strstreambuf*)_strbuf)->frozen(); } +}; + +class strstream : public strstreambase, public iostream { + public: + strstream() { } + strstream(char *cp, int n, int mode=ios::out) :strstreambase(cp,n,mode){} + _IO_ssize_t pcount() { return ((strstreambuf*)_strbuf)->pcount(); } + char *str() { return ((strstreambuf*)_strbuf)->str(); } + void freeze(int n = 1) { ((strstreambuf*)_strbuf)->freeze(n); } + int frozen() { return ((strstreambuf*)_strbuf)->frozen(); } +}; +} // extern "C++" + +#endif /*!__STRSTREAM_H*/ diff --git a/headers/cpp/tempbuf.h b/headers/cpp/tempbuf.h new file mode 100644 index 0000000000..aa4f289c58 --- /dev/null +++ b/headers/cpp/tempbuf.h @@ -0,0 +1,61 @@ +/* + * + * 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. + */ + +#ifndef __SGI_STL_TEMPBUF_H +#define __SGI_STL_TEMPBUF_H + +#ifndef __SGI_STL_PAIR_H +#include +#endif +#include /* XXX should use */ +#include /* XXX should use */ +#include /* XXX should use */ +#ifndef __TYPE_TRAITS_H +#include +#endif +#ifndef __SGI_STL_INTERNAL_CONSTRUCT_H +#include +#endif +#ifndef __SGI_STL_INTERNAL_UNINITIALIZED_H +#include +#endif +#ifndef __SGI_STL_INTERNAL_TEMPBUF_H +#include +#endif + +#ifdef __STL_USE_NAMESPACES + +using __STD::get_temporary_buffer; +using __STD::return_temporary_buffer; +using __STD::temporary_buffer; + +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_TEMPBUF_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/tree.h b/headers/cpp/tree.h new file mode 100644 index 0000000000..77c57cbbba --- /dev/null +++ b/headers/cpp/tree.h @@ -0,0 +1,46 @@ +/* + * + * 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. + * + * + */ + +#ifndef __SGI_STL_TREE_H +#define __SGI_STL_TREE_H + +#ifndef __SGI_STL_INTERNAL_TREE_H +#include +#endif +#include +#include + +#ifdef __STL_USE_NAMESPACES +using __STD::rb_tree; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_TREE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/type_traits.h b/headers/cpp/type_traits.h new file mode 100644 index 0000000000..b6a7dfc6de --- /dev/null +++ b/headers/cpp/type_traits.h @@ -0,0 +1,373 @@ +/* + * + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __TYPE_TRAITS_H +#define __TYPE_TRAITS_H + +#ifndef __STL_CONFIG_H +#include +#endif + +/* +This header file provides a framework for allowing compile time dispatch +based on type attributes. This is useful when writing template code. +For example, when making a copy of an array of an unknown type, it helps +to know if the type has a trivial copy constructor or not, to help decide +if a memcpy can be used. + +The class template __type_traits provides a series of typedefs each of +which is either __true_type or __false_type. The argument to +__type_traits can be any type. The typedefs within this template will +attain their correct values by one of these means: + 1. The general instantiation contain conservative values which work + for all types. + 2. Specializations may be declared to make distinctions between types. + 3. Some compilers (such as the Silicon Graphics N32 and N64 compilers) + will automatically provide the appropriate specializations for all + types. + +EXAMPLE: + +//Copy an array of elements which have non-trivial copy constructors +template void copy(T* source, T* destination, int n, __false_type); +//Copy an array of elements which have trivial copy constructors. Use memcpy. +template void copy(T* source, T* destination, int n, __true_type); + +//Copy an array of any type by using the most efficient copy mechanism +template inline void copy(T* source,T* destination,int n) { + copy(source, destination, n, + typename __type_traits::has_trivial_copy_constructor()); +} +*/ + + +struct __true_type { +}; + +struct __false_type { +}; + +template +struct __type_traits { + typedef __true_type this_dummy_member_must_be_first; + /* Do not remove this member. It informs a compiler which + automatically specializes __type_traits that this + __type_traits template is special. It just makes sure that + things work if an implementation is using a template + called __type_traits for something unrelated. */ + + /* The following restrictions should be observed for the sake of + compilers which automatically produce type specific specializations + of this class: + - You may reorder the members below if you wish + - You may remove any of the members below if you wish + - You must not rename members without making the corresponding + name change in the compiler + - Members you add will be treated like regular members unless + you add the appropriate support in the compiler. */ + + + typedef __false_type has_trivial_default_constructor; + typedef __false_type has_trivial_copy_constructor; + typedef __false_type has_trivial_assignment_operator; + typedef __false_type has_trivial_destructor; + typedef __false_type is_POD_type; +}; + + + +// Provide some specializations. This is harmless for compilers that +// have built-in __types_traits support, and essential for compilers +// that don't. + +#ifndef __STL_NO_BOOL + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +#endif /* __STL_NO_BOOL */ + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +#ifdef __STL_HAS_WCHAR_T + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +#endif /* __STL_HAS_WCHAR_T */ + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +#ifdef __STL_LONG_LONG + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +#endif /* __STL_LONG_LONG */ + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +struct __type_traits<_Tp*> { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + + +// The following could be written in terms of numeric_limits. +// We're doing it separately to reduce the number of dependencies. + +template struct _Is_integer { + typedef __false_type _Integral; +}; + +#ifndef __STL_NO_BOOL + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +#endif /* __STL_NO_BOOL */ + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +#ifdef __STL_HAS_WCHAR_T + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +#endif /* __STL_HAS_WCHAR_T */ + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +#ifdef __STL_LONG_LONG + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +#endif /* __STL_LONG_LONG */ + +#endif /* __TYPE_TRAITS_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/utility b/headers/cpp/utility new file mode 100644 index 0000000000..df8c224388 --- /dev/null +++ b/headers/cpp/utility @@ -0,0 +1,38 @@ +/* + * + * 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,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_UTILITY +#define __SGI_STL_UTILITY + +#include +#include +#include + +#endif /* __SGI_STL_UTILITY */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/valarray b/headers/cpp/valarray new file mode 100644 index 0000000000..a938b6a686 --- /dev/null +++ b/headers/cpp/valarray @@ -0,0 +1,8 @@ +// Main header for -*- C++ -*- valarray classes. + +#ifndef __VALARRAY__ +#define __VALARRAY__ + +#include + +#endif diff --git a/headers/cpp/vector b/headers/cpp/vector new file mode 100644 index 0000000000..4bcdebcc18 --- /dev/null +++ b/headers/cpp/vector @@ -0,0 +1,41 @@ +/* + * + * 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. + */ + +#ifndef __SGI_STL_VECTOR +#define __SGI_STL_VECTOR + +#include +#include +#include +#include +#include +#include + +#endif /* __SGI_STL_VECTOR */ + +// Local Variables: +// mode:C++ +// End: diff --git a/headers/cpp/vector.h b/headers/cpp/vector.h new file mode 100644 index 0000000000..231a227b7e --- /dev/null +++ b/headers/cpp/vector.h @@ -0,0 +1,42 @@ +/* + * + * 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. + */ + +#ifndef __SGI_STL_VECTOR_H +#define __SGI_STL_VECTOR_H + +#include +#include +#include + +#ifdef __STL_USE_NAMESPACES +using __STD::vector; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_VECTOR_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/src/libs/Jamfile b/src/libs/Jamfile index 5c971d9926..17b90226f5 100644 --- a/src/libs/Jamfile +++ b/src/libs/Jamfile @@ -4,4 +4,5 @@ SubInclude OBOS_TOP src libs freetype2 ; SubInclude OBOS_TOP src libs zlib ; SubInclude OBOS_TOP src libs png ; SubInclude OBOS_TOP src libs termcap ; +SubInclude OBOS_TOP src libs stdc++ ; SubInclude OBOS_TOP src libs pdflib ; diff --git a/src/libs/stdc++/Jamfile b/src/libs/stdc++/Jamfile new file mode 100644 index 0000000000..51070f6aeb --- /dev/null +++ b/src/libs/stdc++/Jamfile @@ -0,0 +1,194 @@ +SubDir OBOS_TOP src libs stdc++ ; + +local savedCcFlags = $(CCFLAGS) ; +CCFLAGS = ; +local savedC++Flags = $(C++FLAGS) ; +C++FLAGS = ; + +# define header-searchpaths all by ourselves, as including system headers +# messes things up: +# use the following paths to make use of the headers contained in glibc, +# but this doesn't work yet, as the libio we are using here and the one +# contained in our libroot are different versions. +HDRS = + [ FDirName $(OBOS_TOP) src kernel libroot posix glibc libio ] + [ FDirName $(OBOS_TOP) src kernel libroot posix glibc stdlib ] + [ FDirName $(OBOS_TOP) src kernel libroot posix glibc stdio-common ] + [ FDirName $(OBOS_TOP) src kernel libroot posix glibc include ] + [ FDirName $(OBOS_TOP) src kernel libroot posix glibc include arch x86 ] + [ FDirName $(OBOS_TOP) headers cpp ] + [ FDirName $(OBOS_TOP) src kernel libroot posix glibc ] + [ FDirName $(OBOS_TOP) headers posix ] + [ FDirName $(OBOS_TOP) headers os ] + [ FDirName $(OBOS_TOP) headers os kernel ] + [ FDirName $(OBOS_TOP) headers os storage ] + [ FDirName $(OBOS_TOP) headers os support ] + $(LIBGCC_DIR)/include ; # such that include_next will work + +# some source-files generate several different objects, depending on +# the defines that are used during the compilation call. +# So we explicitly state each of these (with their respective defines): +rule GenerateStdC++Object +{ + # GenerateStdC++Object : : ; + local object = [ FGristFiles $(1) ] ; + local sources = $(2) ; + local defines = $(3) ; + + local source ; + + for source in [ FGristFiles $(sources) ] { + CCFLAGS on $(source:S=$(SUFOBJ)) = $(savedCcFlags) -Wno-missing-prototypes ; + C++FLAGS on $(source:S=$(SUFOBJ)) = $(savedC++Flags) -nostdinc++ -fno-implicit-templates + -Wno-sign-compare -fpic ; + } + + SetupObjectsDir ; + MakeLocateObjects $(object) ; + if $(object) { + Object $(object) : $(sources) ; + } else { + Objects $(sources) ; + } + if $(defines) { + if $(object) { + ObjectDefines $(object) : $(defines) ; + } else { + ObjectDefines $(sources) : $(defines) ; + } + } +} + +GenerateStdC++Object cstrio.o + : sinst.cc + : C EXTRACT INSERT GETLINE + ; + +GenerateStdC++Object cstrmain.o + : sinst.cc + : C REP MAIN TRAITS ADDSS ADDPS ADDCS ADDSP ADDSC EQSS EQPS EQSP NESS NEPS + NESP LTSS LTPS LTSP GTSS GTPS GTSP LESS LEPS LESP GESS GEPS GESP ; + +GenerateStdC++Object dcomio.o + : cinst.cc + : D EXTRACT INSERT ; + +GenerateStdC++Object dcomplex.o + : cinst.cc + : D MAIN ADDCC ADDCF ADDFC SUBCC SUBCF SUBFC MULCC MULCF MULFC DIVCC DIVCF + DIVFC PLUS MINUS EQCC EQCF EQFC NECC NECF NEFC ABS ARG POLAR CONJ NORM COS + COSH EXP LOG POWCC POWCF POWCI POWFC SIN SINH SQRT ; + +GenerateStdC++Object fcomio.o + : cinst.cc + : F EXTRACT INSERT ; + +GenerateStdC++Object fcomplex.o + : cinst.cc + : F MAIN ADDCC ADDCF ADDFC SUBCC SUBCF SUBFC MULCC MULCF MULFC DIVCC DIVCF + DIVFC PLUS MINUS EQCC EQCF EQFC NECC NECF NEFC ABS ARG POLAR CONJ NORM COS + COSH EXP LOG POWCC POWCF POWCI POWFC SIN SINH SQRT ; + +GenerateStdC++Object ldcomio.o + : cinst.cc + : LD EXTRACT INSERT ; + +GenerateStdC++Object ldcomplex.o + : cinst.cc + : LD MAIN ADDCC ADDCF ADDFC SUBCC SUBCF SUBFC MULCC MULCF MULFC DIVCC DIVCF + DIVFC PLUS MINUS EQCC EQCF EQFC NECC NECF NEFC ABS ARG POLAR CONJ NORM COS + COSH EXP LOG POWCC POWCF POWCI POWFC SIN SINH SQRT ; + +# generate standard objects through our new rule, too: +GenerateStdC++Object + : cmathi.cc + cstdlibi.cc + cstringi.cc + stdexcepti.cc ; + +# c++ parts from libio: +GenerateStdC++Object + : builtinbuf.cc + editbuf.cc + filebuf.cc + fstream.cc + indstream.cc + ioassign.cc + ioextend.cc + iomanip.cc + iostream.cc + isgetline.cc + isgetsb.cc + isscan.cc + osform.cc + parsestream.cc + pfstream.cc + PlotFile.cc + procbuf.cc + sbform.cc + sbgetline.cc + sbscan.cc + SFile.cc + stdexcepti.cc + stdiostream.cc + stdstrbufs.cc + stdstreams.cc + stlinst.cc + stream.cc + streambuf.cc + strstream.cc ; + +# stuff imported from libiberty: +GenerateStdC++Object + : basename.c getpagesize.c insque.c sigsetmask.c strerror.c vfork.c ; + +SharedLibraryFromObjects stdc++.r4.so : + basename.o + builtinbuf.o + cmathi.o + cstdlibi.o + cstringi.o + cstrio.o + cstrmain.o + dcomio.o + dcomplex.o + editbuf.o + fcomio.o + fcomplex.o + filebuf.o + fstream.o + getpagesize.o + indstream.o + insque.o + ioassign.o + ioextend.o + iomanip.o + iostream.o + isgetline.o + isgetsb.o + isscan.o + ldcomio.o + ldcomplex.o + osform.o + parsestream.o + pfstream.o + PlotFile.o + procbuf.o + sbform.o + sbgetline.o + sbscan.o + SFile.o + sigsetmask.o + stdexcepti.o + stdiostream.o + stdstrbufs.o + stdstreams.o + stlinst.o + stream.o + streambuf.o + strerror.o + strstream.o + vfork.o ; + +CCFLAGS = $(savedCcFlags) ; +C++FLAGS = $(savedC++Flags) ; diff --git a/src/libs/stdc++/PlotFile.cc b/src/libs/stdc++/PlotFile.cc new file mode 100644 index 0000000000..98b2d83955 --- /dev/null +++ b/src/libs/stdc++/PlotFile.cc @@ -0,0 +1,157 @@ +/* +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + +// This may look like C code, but it is really -*- C++ -*- +/* +Copyright (C) 1988, 1992, 1993 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + converted to use iostream library by Per Bothner (bothner@cygnus.com) + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with GCC to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include + +/* + PlotFile implementation module +*/ + + +PlotFile& PlotFile:: cmd(char c) +{ + ofstream::put(c); + return *this; +} + +PlotFile& PlotFile:: operator<<(const int x) +{ +#if defined(convex) + ofstream::put((char)(x>>8)); + ofstream::put((char)(x&0377)); +#else + ofstream::put((char)(x&0377)); + ofstream::put((char)(x>>8)); +#endif + return *this; +} + +PlotFile& PlotFile:: operator<<(const char *s) +{ + *(ofstream*)this << s; + return *this; +} + + +PlotFile& PlotFile:: arc(const int xi, const int yi, + const int x0, const int y0, + const int x1, const int y1) +{ + return cmd('a') << xi << yi << x0 << y0 << x1 << y1; +} + + +PlotFile& PlotFile:: box(const int x0, const int y0, + const int x1, const int y1) +{ + line(x0, y0, x0, y1); + line(x0, y1, x1, y1); + line(x1, y1, x1, y0); + return line(x1, y0, x0, y0); +} + +PlotFile& PlotFile:: circle(const int x, const int y, const int r) +{ + return cmd('c') << x << y << r; +} + +PlotFile& PlotFile:: cont(const int xi, const int yi) +{ + return cmd('n') << xi << yi; +} + +PlotFile& PlotFile:: dot(const int xi, const int yi, const int dx, + int n, const int* pat) +{ + cmd('d') << xi << yi << dx << n; + while (n-- > 0) *this << *pat++; + return *this; +} + +PlotFile& PlotFile:: erase() +{ + return cmd('e'); +} + +PlotFile& PlotFile:: label(const char* s) +{ + return cmd('t') << s << "\n"; +} + +PlotFile& PlotFile:: line(const int x0, const int y0, + const int x1, const int y1) +{ + return cmd('l') << x0 << y0 << x1 << y1; +} + +PlotFile& PlotFile:: linemod(const char* s) +{ + return cmd('f') << s << "\n"; +} + +PlotFile& PlotFile:: move(const int xi, const int yi) +{ + return cmd('m') << xi << yi; +} + +PlotFile& PlotFile:: point(const int xi, const int yi) +{ + return cmd('p') << xi << yi; +} + +PlotFile& PlotFile:: space(const int x0, const int y0, + const int x1, const int y1) +{ + return cmd('s') << x0 << y0 << x1 << y1; +} diff --git a/src/libs/stdc++/SFile.cc b/src/libs/stdc++/SFile.cc new file mode 100644 index 0000000000..e5daa64569 --- /dev/null +++ b/src/libs/stdc++/SFile.cc @@ -0,0 +1,82 @@ +/* +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + +/* +Copyright (C) 1988 Free Software Foundation + written by Doug Lea (dl@rocky.oswego.edu) + +This file is part of the GNU C++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include + +SFile::SFile(const char *filename, int size, int mode, int prot) +: fstream(filename, mode, prot) +{ + sz = size; +} + +SFile::SFile(int fd, int size) +: fstream(fd) +{ + sz = size; +} + +void SFile::open(const char *name, int size, int mode, int prot) +{ + fstream::open(name, mode, prot); + sz = size; +} + +SFile& SFile::get(void* x) +{ + read(x, sz); + return *this; +} + +SFile& SFile::put(void* x) +{ + write(x, sz); + return *this; +} + +SFile& SFile::operator[](long i) +{ + if (rdbuf()->pubseekoff(i * sz, ios::beg) == EOF) + set(ios::badbit); + return *this; +} diff --git a/src/libs/stdc++/ansidecl.h b/src/libs/stdc++/ansidecl.h new file mode 100644 index 0000000000..cdb9fb7196 --- /dev/null +++ b/src/libs/stdc++/ansidecl.h @@ -0,0 +1,163 @@ +/* ANSI and traditional C compatability macros + Copyright 1991, 1992, 1996 Free Software Foundation, Inc. + This file is part of the GNU C Library. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* ANSI and traditional C compatibility macros + + ANSI C is assumed if __STDC__ is #defined. + + Macro ANSI C definition Traditional C definition + ----- ---- - ---------- ----------- - ---------- + PTR `void *' `char *' + LONG_DOUBLE `long double' `double' + VOLATILE `volatile' `' + SIGNED `signed' `' + PTRCONST `void *const' `char *' + ANSI_PROTOTYPES 1 not defined + + CONST is also defined, but is obsolete. Just use const. + + obsolete -- DEFUN (name, arglist, args) + + Defines function NAME. + + ARGLIST lists the arguments, separated by commas and enclosed in + parentheses. ARGLIST becomes the argument list in traditional C. + + ARGS list the arguments with their types. It becomes a prototype in + ANSI C, and the type declarations in traditional C. Arguments should + be separated with `AND'. For functions with a variable number of + arguments, the last thing listed should be `DOTS'. + + obsolete -- DEFUN_VOID (name) + + Defines a function NAME, which takes no arguments. + + obsolete -- EXFUN (name, (prototype)) -- obsolete. + + Replaced by PARAMS. Do not use; will disappear someday soon. + Was used in external function declarations. + In ANSI C it is `NAME PROTOTYPE' (so PROTOTYPE should be enclosed in + parentheses). In traditional C it is `NAME()'. + For a function that takes no arguments, PROTOTYPE should be `(void)'. + + obsolete -- PROTO (type, name, (prototype) -- obsolete. + + This one has also been replaced by PARAMS. Do not use. + + PARAMS ((args)) + + We could use the EXFUN macro to handle prototype declarations, but + the name is misleading and the result is ugly. So we just define a + simple macro to handle the parameter lists, as in: + + static int foo PARAMS ((int, char)); + + This produces: `static int foo();' or `static int foo (int, char);' + + EXFUN would have done it like this: + + static int EXFUN (foo, (int, char)); + + but the function is not external...and it's hard to visually parse + the function name out of the mess. EXFUN should be considered + obsolete; new code should be written to use PARAMS. + + DOTS is also obsolete. + + Examples: + + extern int printf PARAMS ((const char *format, ...)); +*/ + +#ifndef _ANSIDECL_H + +#define _ANSIDECL_H 1 + + +/* Every source file includes this file, + so they will all get the switch for lint. */ +/* LINTLIBRARY */ + + +#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(_WIN32) +/* All known AIX compilers implement these things (but don't always + define __STDC__). The RISC/OS MIPS compiler defines these things + in SVR4 mode, but does not define __STDC__. */ + +#define PTR void * +#define PTRCONST void *CONST +#define LONG_DOUBLE long double + +#ifndef IN_GCC +#define AND , +#define NOARGS void +#define VOLATILE volatile +#define SIGNED signed +#endif /* ! IN_GCC */ + +#define PARAMS(paramlist) paramlist +#define ANSI_PROTOTYPES 1 + +#define VPARAMS(ARGS) ARGS +#define VA_START(va_list,var) va_start(va_list,var) + +/* These are obsolete. Do not use. */ +#ifndef IN_GCC +#define CONST const +#define DOTS , ... +#define PROTO(type, name, arglist) type name arglist +#define EXFUN(name, proto) name proto +#define DEFUN(name, arglist, args) name(args) +#define DEFUN_VOID(name) name(void) +#endif /* ! IN_GCC */ + +#else /* Not ANSI C. */ + +#define PTR char * +#define PTRCONST PTR +#define LONG_DOUBLE double + +#ifndef IN_GCC +#define AND ; +#define NOARGS +#define VOLATILE +#define SIGNED +#endif /* !IN_GCC */ + +#ifndef const /* some systems define it in header files for non-ansi mode */ +#define const +#endif + +#define PARAMS(paramlist) () + +#define VPARAMS(ARGS) (va_alist) va_dcl +#define VA_START(va_list,var) va_start(va_list) + +/* These are obsolete. Do not use. */ +#ifndef IN_GCC +#define CONST +#define DOTS +#define PROTO(type, name, arglist) type name () +#define EXFUN(name, proto) name() +#define DEFUN(name, arglist, args) name arglist args; +#define DEFUN_VOID(name) name() +#endif /* ! IN_GCC */ + +#endif /* ANSI C. */ + +#endif /* ansidecl.h */ diff --git a/src/libs/stdc++/basename.c b/src/libs/stdc++/basename.c new file mode 100644 index 0000000000..f544c85391 --- /dev/null +++ b/src/libs/stdc++/basename.c @@ -0,0 +1,37 @@ +/* Return the basename of a pathname. + This file is in the public domain. */ + +/* +NAME + basename -- return pointer to last component of a pathname + +SYNOPSIS + char *basename (const char *name) + +DESCRIPTION + Given a pointer to a string containing a typical pathname + (/usr/src/cmd/ls/ls.c for example), returns a pointer to the + last component of the pathname ("ls.c" in this case). + +BUGS + Presumes a UNIX style path with UNIX style separators. +*/ + +#include "ansidecl.h" +#include "libiberty.h" + +char * +basename (name) + const char *name; +{ + const char *base = name; + + while (*name) + { + if (*name++ == '/') + { + base = name; + } + } + return (char *) base; +} diff --git a/src/libs/stdc++/builtinbuf.cc b/src/libs/stdc++/builtinbuf.cc new file mode 100644 index 0000000000..05e65a5c37 --- /dev/null +++ b/src/libs/stdc++/builtinbuf.cc @@ -0,0 +1,78 @@ +/* +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + +#ifdef __GNUC__ +#pragma implementation +#endif +#define _STREAM_COMPAT +#include "builtinbuf.h" +#include "iostreamP.h" +#if !_IO_UNIFIED_JUMPTABLES +int builtinbuf::overflow(int ch) { return _IO_OVERFLOW (this, ch); } + +int builtinbuf::underflow() { return _IO_UNDERFLOW (this); } + +streamsize builtinbuf::xsgetn(char* buf, streamsize n) +{ return _IO_XSGETN (this, buf, n); } + +streamsize builtinbuf::xsputn(const char* buf, streamsize n) +{ return _IO_XSPUTN (this, buf, n); } + +int builtinbuf::doallocate() { return _IO_DOALLOCATE (this); } + +builtinbuf::~builtinbuf() { _IO_FINISH (this); } + +int builtinbuf::sync() { return _IO_SYNC (this); } + +streambuf* builtinbuf::setbuf(char *buf, int n) +{ return (streambuf*)_IO_SETBUF (this, buf, n); } + +streampos builtinbuf::seekoff(streamoff off, _seek_dir dir, int mode) +{ + return _IO_SEEKOFF (this, off, dir, mode); +} + +streampos builtinbuf::seekpos(streampos pos, int mode) +{ + return _IO_SEEKPOS (this, pos, mode); +} + +int builtinbuf::pbackfail(int c) +{ return _IO_PBACKFAIL (this, c); } + +streamsize builtinbuf::sys_read(char* buf, streamsize size) +{ return _IO_SYSREAD (this, buf, size); } + +streampos builtinbuf::sys_seek(streamoff off, _seek_dir dir) +{ return _IO_SYSSEEK (this, off, dir); } + +streamsize builtinbuf::sys_write(const char* buf, streamsize size) +{ return _IO_SYSWRITE (this, buf, size); } + +int builtinbuf::sys_stat(void* buf) // Actually, a (struct stat*) +{ return _IO_SYSSTAT (this, buf); } + +int builtinbuf::sys_close() +{ return _IO_SYSCLOSE (this); } +#endif diff --git a/src/libs/stdc++/cinst.cc b/src/libs/stdc++/cinst.cc new file mode 100644 index 0000000000..983e8a9caa --- /dev/null +++ b/src/libs/stdc++/cinst.cc @@ -0,0 +1,154 @@ +// Instantiation file for the -*- C++ -*- complex number classes. +// Copyright (C) 1994 Free Software Foundation + +#ifdef F +typedef float f; +#endif +#ifdef D +typedef double f; +#endif +#ifdef LD +typedef long double f; +#endif + +#if defined (MAIN) && defined (__GNUG__) +#ifdef F +#pragma implementation "fcomplex" +#endif +#ifdef D +#pragma implementation "dcomplex" +#endif +#ifdef LD +#pragma implementation "ldcomplex" +#endif +#endif + +#if 0 +#define _G_NO_EXTERN_TEMPLATES +#endif +#include + +typedef complex c; +typedef const c& ccr; + +#ifdef MAIN +template c& __doapl (c*, ccr); +template c& __doaml (c*, ccr); +template c& __doami (c*, ccr); +template c& __doadv (c*, ccr); +#endif + +#ifdef ADDCC +template c operator+ (ccr, ccr); +#endif +#ifdef ADDCF +template c operator+ (ccr, f); +#endif +#ifdef ADDFC +template c operator+ (f, ccr); +#endif +#ifdef SUBCC +template c operator- (ccr, ccr); +#endif +#ifdef SUBCF +template c operator- (ccr, f); +#endif +#ifdef SUBFC +template c operator- (f, ccr); +#endif +#ifdef MULCC +template c operator* (ccr, ccr); +#endif +#ifdef MULCF +template c operator* (ccr, f); +#endif +#ifdef MULFC +template c operator* (f, ccr); +#endif +#ifdef DIVCC +template c operator/ (ccr, ccr); +#endif +#ifdef DIVCF +template c operator/ (ccr, f); +#endif +#ifdef DIVFC +template c operator/ (f, ccr); +#endif +#ifdef PLUS +template c operator+ (ccr); +#endif +#ifdef MINUS +template c operator- (ccr); +#endif +#ifdef EQCC +template bool operator== (ccr, ccr); +#endif +#ifdef EQCF +template bool operator== (ccr, f); +#endif +#ifdef EQFC +template bool operator== (f, ccr); +#endif +#ifdef NECC +template bool operator!= (ccr, ccr); +#endif +#ifdef NECF +template bool operator!= (ccr, f); +#endif +#ifdef NEFC +template bool operator!= (f, ccr); +#endif +#ifdef ABS +template f abs (ccr); +#endif +#ifdef ARG +template f arg (ccr); +#endif +#ifdef POLAR +template c polar (f, f); +#endif +#ifdef CONJ +template c conj (ccr); +#endif +#ifdef NORM +template f norm (ccr); +#endif +#ifdef COS +template c cos (ccr); +#endif +#ifdef COSH +template c cosh (ccr); +#endif +#ifdef EXP +template c exp (ccr); +#endif +#ifdef LOG +template c log (ccr); +#endif +#ifdef POWCC +template c pow (ccr, ccr); +#endif +#ifdef POWCF +template c pow (ccr, f); +#endif +#ifdef POWCI +template c pow (ccr, int); +#endif +#ifdef POWFC +template c pow (f, ccr); +#endif +#ifdef SIN +template c sin (ccr); +#endif +#ifdef SINH +template c sinh (ccr); +#endif +#ifdef SQRT +template c sqrt (ccr); +#endif +#ifdef EXTRACT +template istream& operator>> (istream&, complex&); +#endif +#ifdef INSERT +template ostream& operator<< (ostream&, const complex&); +#endif diff --git a/src/libs/stdc++/cmathi.cc b/src/libs/stdc++/cmathi.cc new file mode 100644 index 0000000000..afd740f013 --- /dev/null +++ b/src/libs/stdc++/cmathi.cc @@ -0,0 +1,7 @@ +// Implementation file for the -*- C++ -*- math functions header. +// This file is part of the GNU ANSI C++ Library. + +#ifdef __GNUG__ +#pragma implementation "cmath" +#endif +#include diff --git a/src/libs/stdc++/config.h b/src/libs/stdc++/config.h new file mode 100644 index 0000000000..64ee865baa --- /dev/null +++ b/src/libs/stdc++/config.h @@ -0,0 +1,222 @@ +/* config.h. Generated automatically by configure. */ +/* config.in. Generated automatically from configure.in by autoheader. */ + +/* Define if using alloca.c. */ +/* #undef C_ALLOCA */ + +/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. + This function is required for alloca.c support on those systems. */ +/* #undef CRAY_STACKSEG_END */ + +/* Define if you have alloca, as a function or macro. */ +#define HAVE_ALLOCA 1 + +/* Define if you have and it should be used (not on Ultrix). */ +#define HAVE_ALLOCA_H 1 + +/* Define if you have that is POSIX.1 compatible. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define if you have . */ +/* #undef HAVE_VFORK_H */ + +/* Define to `int' if doesn't define. */ +/* #undef pid_t */ + +/* Define if you need to in order for stat and other things to work. */ +/* #undef _POSIX_SOURCE */ + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at run-time. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown + */ +/* #undef STACK_DIRECTION */ + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define vfork as fork if vfork does not work. */ +#define vfork fork + +/* Define if you have the sys_errlist variable. */ +/* #undef HAVE_SYS_ERRLIST */ + +/* Define if you have the sys_nerr variable. */ +/* #undef HAVE_SYS_NERR */ + +/* Define if you have the sys_siglist variable. */ +#define HAVE_SYS_SIGLIST 1 + +/* Define if you have the strerror function. */ +#define HAVE_STRERROR 1 + +/* Define if you have the asprintf function. */ +#define HAVE_ASPRINTF 1 + +/* Define if you have the atexit function. */ +#define HAVE_ATEXIT 1 + +/* Define if you have the basename function. */ +/* #undef HAVE_BASENAME */ + +/* Define if you have the bcmp function. */ +#define HAVE_BCMP 1 + +/* Define if you have the bcopy function. */ +#define HAVE_BCOPY 1 + +/* Define if you have the bzero function. */ +#define HAVE_BZERO 1 + +/* Define if you have the calloc function. */ +#define HAVE_CALLOC 1 + +/* Define if you have the clock function. */ +#define HAVE_CLOCK 1 + +/* Define if you have the getcwd function. */ +#define HAVE_GETCWD 1 + +/* Define if you have the getpagesize function. */ +/* #undef HAVE_GETPAGESIZE */ + +/* Define if you have the getrusage function. */ +#define HAVE_GETRUSAGE 1 + +/* Define if you have the gettimeofday function. */ +#define HAVE_GETTIMEOFDAY 1 + +/* Define if you have the index function. */ +#define HAVE_INDEX 1 + +/* Define if you have the insque function. */ +/* #undef HAVE_INSQUE */ + +/* Define if you have the memchr function. */ +#define HAVE_MEMCHR 1 + +/* Define if you have the memcmp function. */ +#define HAVE_MEMCMP 1 + +/* Define if you have the memcpy function. */ +#define HAVE_MEMCPY 1 + +/* Define if you have the memmove function. */ +#define HAVE_MEMMOVE 1 + +/* Define if you have the memset function. */ +#define HAVE_MEMSET 1 + +/* Define if you have the mkstemps function. */ +/* #undef HAVE_MKSTEMPS */ + +/* Define if you have the on_exit function. */ +/* #undef HAVE_ON_EXIT */ + +/* Define if you have the psignal function. */ +/* #undef HAVE_PSIGNAL */ + +/* Define if you have the putenv function. */ +#define HAVE_PUTENV 1 + +/* Define if you have the random function. */ +#define HAVE_RANDOM 1 + +/* Define if you have the rename function. */ +#define HAVE_RENAME 1 + +/* Define if you have the rindex function. */ +#define HAVE_RINDEX 1 + +/* Define if you have the sbrk function. */ +#define HAVE_SBRK 1 + +/* Define if you have the setenv function. */ +/* #undef HAVE_SETENV */ + +/* Define if you have the sigsetmask function. */ +/* #undef HAVE_SIGSETMASK */ + +/* Define if you have the strcasecmp function. */ +#define HAVE_STRCASECMP 1 + +/* Define if you have the strchr function. */ +#define HAVE_STRCHR 1 + +/* Define if you have the strdup function. */ +#define HAVE_STRDUP 1 + +/* Define if you have the strerror function. */ +#define HAVE_STRERROR 1 + +/* Define if you have the strncasecmp function. */ +#define HAVE_STRNCASECMP 1 + +/* Define if you have the strrchr function. */ +#define HAVE_STRRCHR 1 + +/* Define if you have the strsignal function. */ +#define HAVE_STRSIGNAL 1 + +/* Define if you have the strstr function. */ +#define HAVE_STRSTR 1 + +/* Define if you have the strtod function. */ +#define HAVE_STRTOD 1 + +/* Define if you have the strtol function. */ +#define HAVE_STRTOL 1 + +/* Define if you have the strtoul function. */ +#define HAVE_STRTOUL 1 + +/* Define if you have the sysconf function. */ +#define HAVE_SYSCONF 1 + +/* Define if you have the times function. */ +#define HAVE_TIMES 1 + +/* Define if you have the tmpnam function. */ +#define HAVE_TMPNAM 1 + +/* Define if you have the vasprintf function. */ +#define HAVE_VASPRINTF 1 + +/* Define if you have the vfprintf function. */ +#define HAVE_VFPRINTF 1 + +/* Define if you have the vprintf function. */ +#define HAVE_VPRINTF 1 + +/* Define if you have the vsprintf function. */ +#define HAVE_VSPRINTF 1 + +/* Define if you have the waitpid function. */ +#define HAVE_WAITPID 1 + +/* Define if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_FILE_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_RESOURCE_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define if you have the header file. */ +#define HAVE_UNISTD_H 1 diff --git a/src/libs/stdc++/cstdlibi.cc b/src/libs/stdc++/cstdlibi.cc new file mode 100644 index 0000000000..abbfa03464 --- /dev/null +++ b/src/libs/stdc++/cstdlibi.cc @@ -0,0 +1,7 @@ +// Implementation file for the -*- C++ -*- standard library header. +// This file is part of the GNU ANSI C++ Library. + +#ifdef __GNUG__ +#pragma implementation "cstdlib" +#endif +#include diff --git a/src/libs/stdc++/cstringi.cc b/src/libs/stdc++/cstringi.cc new file mode 100644 index 0000000000..2676febc9b --- /dev/null +++ b/src/libs/stdc++/cstringi.cc @@ -0,0 +1,7 @@ +// Implementation file for the -*- C++ -*- null-terminated string header. +// This file is part of the GNU ANSI C++ Library. + +#ifdef __GNUG__ +#pragma implementation "cstring" +#endif +#include diff --git a/src/libs/stdc++/editbuf.cc b/src/libs/stdc++/editbuf.cc new file mode 100644 index 0000000000..22304820f8 --- /dev/null +++ b/src/libs/stdc++/editbuf.cc @@ -0,0 +1,717 @@ +/* This is part of libio/iostream, providing -*- C++ -*- input/output. +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. + +Written by Per Bothner (bothner@cygnus.com). */ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include "libioP.h" +#include "editbuf.h" +#include +#include + +/* NOTE: Some of the code here is taken from GNU emacs */ +/* Hence this file falls under the GNU License! */ + +// Invariants for edit_streambuf: +// An edit_streambuf is associated with a specific edit_string, +// which again is a sub-string of a specific edit_buffer. +// An edit_streambuf is always in either get mode or put mode, never both. +// In get mode, gptr() is the current position, +// and pbase(), pptr(), and epptr() are all NULL. +// In put mode, pptr() is the current position, +// and eback(), gptr(), and egptr() are all NULL. +// Any edit_streambuf that is actively doing insertion (as opposed to +// replacing) // must have its pptr() pointing to the start of the gap. +// Only one edit_streambuf can be actively inserting into a specific +// edit_buffer; the edit_buffer's _writer field points to that edit_streambuf. +// That edit_streambuf "owns" the gap, and the actual start of the +// gap is the pptr() of the edit_streambuf; the edit_buffer::_gap_start pointer +// will only be updated on an edit_streambuf::overflow(). + +int edit_streambuf::truncate() +{ + str->buffer->delete_range(str->buffer->tell((buf_char*)pptr()), + str->buffer->tell(str->end)); + return 0; +} + +#ifdef OLD_STDIO +inline void disconnect_gap_from_file(edit_buffer* buffer, FILE* fp) +{ + if (buffer->gap_start_ptr != &fp->__bufp) + return; + buffer->gap_start_normal = fp->__bufp; + buffer->gap_start_ptr = &buffer->gap_start_normal; +} +#endif + +void edit_streambuf::flush_to_buffer(edit_buffer* buffer) +{ + if (pptr() > buffer->_gap_start && pptr() < buffer->gap_end()) + buffer->_gap_start = pptr(); +} + +void edit_streambuf::disconnect_gap_from_file(edit_buffer* buffer) +{ + if (buffer->_writer != this) return; + flush_to_buffer(buffer); + setp(pptr(),pptr()); + buffer->_writer = NULL; +} + +buf_index edit_buffer::tell(buf_char *ptr) +{ + if (ptr <= gap_start()) + return ptr - data; + else + return ptr - gap_end() + size1(); +} + +#if 0 +buf_index buf_cookie::tell() +{ + return str->buffer->tell(file->__bufp); +} +#endif + +buf_index edit_buffer::tell(edit_mark*mark) +{ + return tell(data + mark->index_in_buffer(this)); +} + +// adjust the position of the gap + +void edit_buffer::move_gap(buf_offset pos) +{ + if (pos < size1()) + gap_left (pos); + else if (pos > size1()) + gap_right (pos); +} + +void edit_buffer::gap_left (int pos) +{ + register buf_char *to, *from; + register int i; + int new_s1; + + i = size1(); + from = gap_start(); + to = from + gap_size(); + new_s1 = size1(); + + /* Now copy the characters. To move the gap down, + copy characters up. */ + + for (;;) + { + /* I gets number of characters left to copy. */ + i = new_s1 - pos; + if (i == 0) + break; +#if 0 + /* If a quit is requested, stop copying now. + Change POS to be where we have actually moved the gap to. */ + if (QUITP) + { + pos = new_s1; + break; + } +#endif + /* Move at most 32000 chars before checking again for a quit. */ + if (i > 32000) + i = 32000; + new_s1 -= i; + while (--i >= 0) + *--to = *--from; + } + + /* Adjust markers, and buffer data structure, to put the gap at POS. + POS is where the loop above stopped, which may be what was specified + or may be where a quit was detected. */ + adjust_markers (pos << 1, size1() << 1, gap_size(), data); +#ifndef OLD_STDIO + _gap_start = data + pos; +#else + if (gap_start_ptr == &gap_start_normal) + gap_start_normal = data + pos; +#endif + __gap_end_pos = to - data; +/* QUIT;*/ +} + +void edit_buffer::gap_right (int pos) +{ + register buf_char *to, *from; + register int i; + int new_s1; + + i = size1(); + to = gap_start(); + from = i + gap_end(); + new_s1 = i; + + /* Now copy the characters. To move the gap up, + copy characters down. */ + + while (1) + { + /* I gets number of characters left to copy. */ + i = pos - new_s1; + if (i == 0) + break; +#if 0 + /* If a quit is requested, stop copying now. + Change POS to be where we have actually moved the gap to. */ + if (QUITP) + { + pos = new_s1; + break; + } +#endif + /* Move at most 32000 chars before checking again for a quit. */ + if (i > 32000) + i = 32000; + new_s1 += i; + while (--i >= 0) + *to++ = *from++; + } + + adjust_markers ((size1() + gap_size()) << 1, (pos + gap_size()) << 1, + - gap_size(), data); +#ifndef OLD_STDIO + _gap_start = data+pos; +#else + if (gap_start_ptr == &gap_start_normal) + gap_start_normal = data + pos; +#endif + __gap_end_pos = from - data; +/* QUIT;*/ +} + +/* make sure that the gap in the current buffer is at least k + characters wide */ + +void edit_buffer::make_gap(buf_offset k) +{ + register buf_char *p1, *p2, *lim; + buf_char *old_data = data; + int s1 = size1(); + + if (gap_size() >= k) + return; + + /* Get more than just enough */ + if (buf_size > 1000) k += 2000; + else k += /*200;*/ 20; // for testing! + + p1 = (buf_char *) realloc (data, s1 + size2() + k); + if (p1 == 0) + abort(); /*memory_full ();*/ + + k -= gap_size(); /* Amount of increase. */ + + /* Record new location of text */ + data = p1; + + /* Transfer the new free space from the end to the gap + by shifting the second segment upward */ + p2 = data + buf_size; + p1 = p2 + k; + lim = p2 - size2(); + while (lim < p2) + *--p1 = *--p2; + + /* Finish updating text location data */ + __gap_end_pos += k; + +#ifndef OLD_STDIO + _gap_start = data + s1; +#else + if (gap_start_ptr == &gap_start_normal) + gap_start_normal = data + s1; +#endif + + /* adjust markers */ + adjust_markers (s1 << 1, (buf_size << 1) + 1, k, old_data); + buf_size += k; +} + +/* Add `amount' to the position of every marker in the current buffer + whose current position is between `from' (exclusive) and `to' (inclusive). + Also, any markers past the outside of that interval, in the direction + of adjustment, are first moved back to the near end of the interval + and then adjusted by `amount'. */ + +void edit_buffer::adjust_markers(register mark_pointer low, + register mark_pointer high, + int amount, buf_char *old_data) +{ + register struct edit_mark *m; + register mark_pointer mpos; + /* convert to mark_pointer */ + amount <<= 1; + + if (_writer) + _writer->disconnect_gap_from_file(this); + + for (m = mark_list(); m != NULL; m = m->chain) + { + mpos = m->_pos; + if (amount > 0) + { + if (mpos > high && mpos < high + amount) + mpos = high + amount; + } + else + { + if (mpos > low + amount && mpos <= low) + mpos = low + amount; + } + if (mpos > low && mpos <= high) + mpos += amount; + m->_pos = mpos; + } + + // Now adjust files + edit_streambuf *file; + + for (file = files; file != NULL; file = file->next) { + mpos = file->current() - old_data; + if (amount > 0) + { + if (mpos > high && mpos < high + amount) + mpos = high + amount; + } + else + { + if (mpos > low + amount && mpos <= low) + mpos = low + amount; + } + if (mpos > low && mpos <= high) + mpos += amount; + char* new_pos = data + mpos; + file->set_current(new_pos, file->is_reading()); + } +} + +#if 0 +stdio_ + __off == index at start of buffer (need only be valid after seek ? ) + __buf == + +if read/read_delete/overwrite mode: + __endp <= min(*gap_start_ptr, edit_string->end->ptr(buffer)) + +if inserting: + must have *gap_start_ptr == __bufp && *gap_start_ptr+gap == __endp + file->edit_string->end->ptr(buffer) == *gap_start_ptr+end +if write_mode: + if before gap +#endif + +int edit_streambuf::underflow() +{ + if (!(_mode & ios::in)) + return EOF; + struct edit_buffer *buffer = str->buffer; + if (!is_reading()) { // Must switch from put to get mode. + disconnect_gap_from_file(buffer); + set_current(pptr(), 1); + } + buf_char *str_end = str->end->ptr(buffer); + retry: + if (gptr() < egptr()) { + return *gptr(); + } + if ((buf_char*)gptr() == str_end) + return EOF; + if (str_end <= buffer->gap_start()) { + setg(eback(), gptr(), str_end); + goto retry; + } + if (gptr() < buffer->gap_start()) { + setg(eback(), gptr(), buffer->gap_start()); + goto retry; + } + if (gptr() == buffer->gap_start()) { + disconnect_gap_from_file(buffer); +// fp->__offset += fp->__bufp - fp->__buffer; + setg(buffer->gap_end(), buffer->gap_end(), str_end); + } + else + setg(eback(), gptr(), str_end); + goto retry; +} + +int edit_streambuf::overflow(int ch) +{ + if (_mode == ios::in) + return EOF; + struct edit_buffer *buffer = str->buffer; + flush_to_buffer(buffer); + if (ch == EOF) + return 0; + if (is_reading()) { // Must switch from get to put mode. + set_current(gptr(), 0); + } + buf_char *str_end = str->end->ptr(buffer); + retry: + if (pptr() < epptr()) { + *pptr() = ch; + pbump(1); + return (unsigned char)ch; + } + if ((buf_char*)pptr() == str_end || inserting()) { + /* insert instead */ + if (buffer->_writer) + buffer->_writer->flush_to_buffer(); // Redundant? + buffer->_writer = NULL; + if (pptr() >= buffer->gap_end()) + buffer->move_gap(pptr() - buffer->gap_size()); + else + buffer->move_gap(pptr()); + buffer->make_gap(1); + setp(buffer->gap_start(), buffer->gap_end()); + buffer->_writer = this; + *pptr() = ch; + pbump(1); + return (unsigned char)ch; + } + if (str_end <= buffer->gap_start()) { + // Entire string is left of gap. + setp(pptr(), str_end); + } + else if (pptr() < buffer->gap_start()) { + // Current pos is left of gap. + setp(pptr(), buffer->gap_start()); + goto retry; + } + else if (pptr() == buffer->gap_start()) { + // Current pos is at start of gap; move to end of gap. +// disconnect_gap_from_file(buffer); + setp(buffer->gap_end(), str_end); +// __offset += __bufp - __buffer; + } + else { + // Otherwise, current pos is right of gap. + setp(pptr(), str_end); + } + goto retry; +} + +void edit_streambuf::set_current(char *new_pos, int reading) +{ + if (reading) { + setg(new_pos, new_pos, new_pos); + setp(NULL, NULL); + } + else { + setg(NULL, NULL, NULL); + setp(new_pos, new_pos); + } +} + +// Called by fseek(fp, pos, whence) if fp is bound to a edit_buffer. + +streampos edit_streambuf::seekoff(streamoff offset, _seek_dir dir, + int /* =ios::in|ios::out*/) +{ + struct edit_buffer *buffer = str->buffer; + disconnect_gap_from_file(buffer); + buf_index cur_pos = buffer->tell((buf_char*)current());; + buf_index start_pos = buffer->tell(str->start); + buf_index end_pos = buffer->tell(str->end); + switch (dir) { + case ios::beg: + offset += start_pos; + break; + case ios::cur: + offset += cur_pos; + break; + case ios::end: + offset += end_pos; + break; + } + if (offset < start_pos || offset > end_pos) + return EOF; + buf_char *new_pos = buffer->data + offset; + buf_char* gap_start = buffer->gap_start(); + if (new_pos > gap_start) { + buf_char* gap_end = buffer->gap_end(); + new_pos += gap_end - gap_start; + if (new_pos >= buffer->data + buffer->buf_size) abort(); // Paranoia. + } + set_current(new_pos, is_reading()); + return EOF; +} + +#if 0 +int buf_seek(void *arg_cookie, fpos_t * pos, int whence) +{ + struct buf_cookie *cookie = arg_cookie; + FILE *file = cookie->file; + struct edit_buffer *buffer = cookie->str->buffer; + buf_char *str_start = cookie->str->start->ptr(buffer); + disconnect_gap_from_file(buffer, cookie->file); + fpos_t cur_pos, new_pos; + if (file->__bufp <= *buffer->gap_start_ptr + || str_start >= buffer->__gap_end) + cur_pos = str_start - file->__bufp; + else + cur_pos = + (*buffer->gap_start_ptr - str_start) + (file->__bufp - __gap_end); + end_pos = ...; + switch (whence) { + case SEEK_SET: + new_pos = *pos; + break; + case SEEK_CUR: + new_pos = cur_pos + *pos; + break; + case SEEK_END: + new_pos = end_pos + *pos; + break; + } + if (new_pos > end_pos) { + seek to end_pos; + insert_nulls(new_pos - end_pos); + return; + } + if (str_start + new_pos <= *gap_start_ptr &* *gap_start_ptr < end) { + __buffer = str_start; + __off = 0; + __bufp = str_start + new_pos; + file->__get_limit = + *buffer->gap_start_ptr; /* what if gap_start_ptr == &bufp ??? */ + } else if () { + + } + *pos = new_pos; +} +#endif + +/* Delete characters from `from' up to (but not incl) `to' */ + +void edit_buffer::delete_range (buf_index from, buf_index to) +{ + register int numdel; + + if ((numdel = to - from) <= 0) + return; + + /* Make sure the gap is somewhere in or next to what we are deleting */ + if (from > size1()) + gap_right (from); + if (to < size1()) + gap_left (to); + + /* Relocate all markers pointing into the new, larger gap + to point at the end of the text before the gap. */ + adjust_markers ((to + gap_size()) << 1, (to + gap_size()) << 1, + - numdel - gap_size(), data); + + __gap_end_pos = to + gap_size(); + _gap_start = data + from; +} + +void edit_buffer::delete_range(struct edit_mark *start, struct edit_mark *end) +{ + delete_range(tell(start), tell(end)); +} + +void buf_delete_chars(struct edit_buffer *, struct edit_mark *, size_t) +{ + abort(); +} + +edit_streambuf::edit_streambuf(edit_string* bstr, int mode) +{ + _mode = mode; + str = bstr; + edit_buffer* buffer = bstr->buffer; + next = buffer->files; + buffer->files = this; + char* buf_ptr = bstr->start->ptr(buffer); + _inserting = 0; +// setb(buf_ptr, buf_ptr, 0); + set_current(buf_ptr, !(mode & ios::out+ios::trunc+ios::app)); + if (_mode & ios::trunc) + truncate(); + if (_mode & ios::ate) + seekoff(0, ios::end); +} + +// Called by fclose(fp) if fp is bound to a edit_buffer. + +#if 0 +static int buf_close(void *arg) +{ + register struct buf_cookie *cookie = arg; + struct edit_buffer *buffer = cookie->str->buffer; + struct buf_cookie **ptr; + for (ptr = &buffer->files; *ptr != cookie; ptr = &(*ptr)->next) ; + *ptr = cookie->next; + disconnect_gap_from_file(buffer, cookie->file); + free (cookie); + return 0; +} +#endif + +edit_streambuf::~edit_streambuf() +{ + if (_mode == ios::out) + truncate(); + // Unlink this from list of files associated with bstr->buffer. + edit_streambuf **ptr = &str->buffer->files; + for (; *ptr != this; ptr = &(*ptr)->next) { } + *ptr = next; + + disconnect_gap_from_file(str->buffer); +} + +edit_buffer::edit_buffer() +{ + buf_size = /*200;*/ 15; /* for testing! */ + data = (buf_char*)malloc(buf_size); + files = NULL; +#ifndef OLD_STDIO + _gap_start = data; + _writer = NULL; +#else + gap_start_normal = data; + gap_start_ptr = &gap_start_normal; +#endif + __gap_end_pos = buf_size; + start_mark.chain = &end_mark; + start_mark._pos = 0; + end_mark.chain = NULL; + end_mark._pos = 2 * buf_size + 1; +} + +// Allocate a new mark, which is adjusted by 'delta' bytes from 'this'. +// Restrict new mark to lie within 'str'. + +edit_mark::edit_mark(struct edit_string *str, long delta) +{ + struct edit_buffer *buf = str->buffer; + chain = buf->start_mark.chain; + buf->start_mark.chain = this; + mark_pointer size1 = buf->size1() << 1; + int gap_size = buf->gap_size() << 1; + delta <<= 1; + + // check if new and old marks are opposite sides of gap + if (_pos <= size1 && _pos + delta > size1) + delta += gap_size; + else if (_pos >= size1 + gap_size && _pos + delta < size1 + gap_size) + delta -= gap_size; + + _pos = _pos + delta; + if (_pos < str->start->_pos & ~1) + _pos = (str->start->_pos & ~ 1) + (_pos & 1); + else if (_pos >= str->end->_pos) + _pos = (str->end->_pos & ~ 1) + (_pos & 1); +} + +// A (slow) way to find the buffer a mark belongs to. + +edit_buffer * edit_mark::buffer() +{ + struct edit_mark *mark; + for (mark = this; mark->chain != NULL; mark = mark->chain) ; + // Assume that the last mark on the chain is the end_mark. + return (edit_buffer *)((char*)mark - offsetof(edit_buffer, end_mark)); +} + +edit_mark::~edit_mark() +{ + // Must unlink mark from chain of owning buffer + struct edit_buffer *buf = buffer(); + if (this == &buf->start_mark || this == &buf->end_mark) abort(); + edit_mark **ptr; + for (ptr = &buf->start_mark.chain; *ptr != this; ptr = &(*ptr)->chain) ; + *ptr = this->chain; +} + +int edit_string::length() const +{ + ptrdiff_t delta = end->ptr(buffer) - start->ptr(buffer); + if (end->ptr(buffer) <= buffer->gap_start() || + start->ptr(buffer) >= buffer->gap_end()) + return delta; + return delta - buffer->gap_size(); +} + +buf_char * edit_string::copy_bytes(int *lenp) const +{ + char *new_str; + int len1, len2; + buf_char *start1, *start2; + start1 = start->ptr(buffer); + if (end->ptr(buffer) <= buffer->gap_start() + || start->ptr(buffer) >= buffer->gap_end()) { + len1 = end->ptr(buffer) - start1; + len2 = 0; + start2 = NULL; // To avoid a warning from g++. + } + else { + len1 = buffer->gap_start() - start1; + start2 = buffer->gap_end(); + len2 = end->ptr(buffer) - start2; + } + new_str = (char*)malloc(len1 + len2 + 1); + memcpy(new_str, start1, len1); + if (len2 > 0) memcpy(new_str + len1, start2, len2); + new_str[len1+len2] = '\0'; + *lenp = len1+len2; + return new_str; +} + +// Replace the buf_chars in 'this' with ones from 'src'. +// Equivalent to deleting this, then inserting src, except tries +// to leave marks in place: Marks whose offset from the start +// of 'this' is less than 'src->length()' will still have the +// same offset in 'this' when done. + +void edit_string::assign(struct edit_string *src) +{ + edit_streambuf dst_file(this, ios::out); + if (buffer == src->buffer /*&& ???*/) { /* overly conservative */ + int src_len; + buf_char *new_str; + new_str = src->copy_bytes(&src_len); + dst_file.sputn(new_str, src_len); + free (new_str); + } else { + edit_streambuf src_file(src, ios::in); + for ( ; ; ) { + int ch = src_file.sbumpc(); + if (ch == EOF) break; + dst_file.sputc(ch); + } + } +} diff --git a/src/libs/stdc++/filebuf.cc b/src/libs/stdc++/filebuf.cc new file mode 100644 index 0000000000..2bd6baba57 --- /dev/null +++ b/src/libs/stdc++/filebuf.cc @@ -0,0 +1,223 @@ +/* This is part of libio/iostream, providing -*- C++ -*- input/output. +Copyright (C) 1993, 1995, 1999 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. + +Written by Per Bothner (bothner@cygnus.com). */ + +#include "iostreamP.h" +#include +#include +#include +#include +#include "builtinbuf.h" + +void filebuf::init() +{ + _IO_file_init(reinterpret_cast<_IO_FILE_plus*>(this)); +} + +filebuf::filebuf() +{ + _IO_file_init(reinterpret_cast<_IO_FILE_plus*>(this)); +} + +#if !_IO_UNIFIED_JUMPTABLES +/* This is like "new filebuf()", but it uses the _IO_file_jump jumptable, + for eficiency. */ + +filebuf* filebuf::__new() +{ + filebuf *fb = new filebuf; + _IO_JUMPS(fb) = &_IO_file_jumps; + fb->_vtable() = builtinbuf_vtable; + return fb; +} +#endif + +filebuf::filebuf(int fd) +{ + _IO_file_init(reinterpret_cast<_IO_FILE_plus*>(this)); + _IO_file_attach(this, fd); +} + +filebuf::filebuf(int fd, char* p, int len) +{ + _IO_file_init(reinterpret_cast<_IO_FILE_plus*>(this)); + _IO_file_attach(this, fd); + setbuf(p, len); +} + +filebuf::~filebuf() +{ + if (_IO_file_is_open(this)) + { + _IO_do_flush (this); + if (!(xflags() & _IO_DELETE_DONT_CLOSE)) + _IO_SYSCLOSE (this); + } +} + +filebuf* filebuf::open(const char *filename, ios::openmode mode, int prot) +{ + if (_IO_file_is_open (this)) + return NULL; + int posix_mode; + int read_write; + if (mode & ios::app) + mode |= ios::out; + if ((mode & (ios::in|ios::out)) == (ios::in|ios::out)) { + posix_mode = O_RDWR; + read_write = 0; + } + else if (mode & ios::out) + posix_mode = O_WRONLY, read_write = _IO_NO_READS; + else if (mode & (int)ios::in) + posix_mode = O_RDONLY, read_write = _IO_NO_WRITES; + else + posix_mode = 0, read_write = _IO_NO_READS+_IO_NO_WRITES; + if (mode & ios::binary) + { + mode &= ~ios::binary; +#ifdef O_BINARY + /* This is a (mis-)feature of DOS/Windows C libraries. */ + posix_mode |= O_BINARY; +#endif + } + if ((mode & (int)ios::trunc) || mode == (int)ios::out) + posix_mode |= O_TRUNC; + if (mode & ios::app) + posix_mode |= O_APPEND, read_write |= _IO_IS_APPENDING; + if (!(mode & (int)ios::nocreate) && mode != ios::in) + posix_mode |= O_CREAT; + if (mode & (int)ios::noreplace) + posix_mode |= O_EXCL; +#if _G_HAVE_IO_FILE_OPEN + if (!_IO_file_open (this, filename, posix_mode, prot, + read_write, 0)) + return NULL; + if (mode & ios::ate) { + if (pubseekoff(0, ios::end) == EOF) { + _IO_un_link (reinterpret_cast<_IO_FILE_plus*>(this)); + return NULL; + } + } + return this; +#else + int fd = ::open(filename, posix_mode, prot); + if (fd < 0) + return NULL; + _fileno = fd; + xsetflags(read_write, _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING); + if (mode & ios::ate) { + if (pubseekoff(0, ios::end) == EOF) + return NULL; + } + _IO_link_in(this); + return this; +#endif +} + +filebuf* filebuf::open(const char *filename, const char *mode) +{ +#if _G_IO_IO_FILE_VERSION == 0x20001 + return (filebuf*)_IO_file_fopen(this, filename, mode, 0); +#else + return (filebuf*)_IO_file_fopen(this, filename, mode); +#endif +} + +filebuf* filebuf::attach(int fd) +{ + return (filebuf*)_IO_file_attach(this, fd); +} + +streambuf* filebuf::setbuf(char* p, int len) +{ + return (streambuf*)_IO_file_setbuf (this, p, len); +} + +int filebuf::doallocate() { return _IO_file_doallocate(this); } + +int filebuf::overflow(int c) +{ + return _IO_file_overflow(this, c); +} + +int filebuf::underflow() +{ + return _IO_file_underflow(this); +} + +int filebuf::sync() +{ + return _IO_file_sync(this); +} + +streampos filebuf::seekoff(streamoff offset, _seek_dir dir, int mode) +{ + return _IO_file_seekoff (this, offset, dir, mode); +} + +filebuf* filebuf::close() +{ + return (_IO_file_close_it(this) ? (filebuf*)NULL : this); +} + +streamsize filebuf::sys_read(char* buf, streamsize size) +{ + return _IO_file_read(this, buf, size); +} + +streampos filebuf::sys_seek(streamoff offset, _seek_dir dir) +{ + return _IO_file_seek(this, offset, dir); +} + +streamsize filebuf::sys_write(const char *buf, streamsize n) +{ + return _IO_file_write (this, buf, n); +} + +int filebuf::sys_stat(void* st) +{ + return _IO_file_stat (this, st); +} + +int filebuf::sys_close() +{ + return _IO_file_close (this); +} + +streamsize filebuf::xsputn(const char *s, streamsize n) +{ + return _IO_file_xsputn(this, s, n); +} + +streamsize filebuf::xsgetn(char *s, streamsize n) +{ + // FIXME: OPTIMIZE THIS (specifically, when unbuffered()). + return streambuf::xsgetn(s, n); +} + +// Non-ANSI AT&T-ism: Default open protection. +const int filebuf::openprot = 0644; diff --git a/src/libs/stdc++/fstream.cc b/src/libs/stdc++/fstream.cc new file mode 100644 index 0000000000..8930e0b927 --- /dev/null +++ b/src/libs/stdc++/fstream.cc @@ -0,0 +1,110 @@ +/* This is part of libio/iostream, providing -*- C++ -*- input/output. +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. + +Written by Per Bothner (bothner@cygnus.com). */ + +#ifdef __GNUG__ +#pragma implementation +#endif +#define _STREAM_COMPAT +extern "C" { +#include "libioP.h" +} +#include + +inline void +fstreambase::__fb_init() +{ +#ifdef _IO_NEW_STREAMS +#if !_IO_UNIFIED_JUMPTABLES + /* Uses the _IO_file_jump jumptable, for eficiency. */ + __my_fb._jumps = &_IO_file_jumps; + __my_fb._vtable() = builtinbuf_vtable; +#endif + init (&__my_fb); +#else + init(filebuf::__new()); + _flags &= ~ios::dont_close; +#endif +} + +fstreambase::fstreambase() +{ + __fb_init (); +} + +fstreambase::fstreambase(int fd) +{ + __fb_init (); + _IO_file_attach(rdbuf(), fd); +} + +fstreambase::fstreambase(const char *name, int mode, int prot) +{ + __fb_init (); + if (!rdbuf()->open(name, mode, prot)) + set(ios::badbit); +} + +fstreambase::fstreambase(int fd, char *p, int l) +{ +#ifdef _IO_NEW_STREAMS + __fb_init (); +#else + init(filebuf::__new()); +#endif + _IO_file_attach(rdbuf(), fd); + _IO_file_setbuf(rdbuf(), p, l); +} + +void fstreambase::open(const char *name, int mode, int prot) +{ + clear(); + if (!rdbuf()->open(name, mode, prot)) + set(ios::badbit); +} + +void fstreambase::close() +{ + if (!rdbuf()->close()) + set(ios::failbit); +} + +void fstreambase::attach(int fd) +{ + if (!rdbuf()->attach(fd)) + set(ios::failbit); +} + +#if 0 +static int mode_to_sys(enum open_mode mode) +{ + return O_WRONLY; +} + +static char* fopen_cmd_arg(io_mode i) +{ + return "w"; +} +#endif diff --git a/src/libs/stdc++/getpagesize.c b/src/libs/stdc++/getpagesize.c new file mode 100644 index 0000000000..564d6c0231 --- /dev/null +++ b/src/libs/stdc++/getpagesize.c @@ -0,0 +1,96 @@ +/* Emulation of getpagesize() for systems that need it. */ + +/* + +NAME + + getpagesize -- return the number of bytes in page of memory + +SYNOPSIS + + int getpagesize (void) + +DESCRIPTION + + Returns the number of bytes in a page of memory. This is the + granularity of many of the system memory management routines. + No guarantee is made as to whether or not it is the same as the + basic memory management hardware page size. + +BUGS + + Is intended as a reasonable replacement for systems where this + is not provided as a system call. The value of 4096 may or may + not be correct for the systems where it is returned as the default + value. + +*/ + +#ifndef VMS + +#include "config.h" + +#include +#ifdef HAVE_SYS_PARAM_H +#include +#endif + +#undef GNU_OUR_PAGESIZE +#if defined (HAVE_SYSCONF) && defined (HAVE_UNISTD_H) +#include +#ifdef _SC_PAGESIZE +#define GNU_OUR_PAGESIZE sysconf(_SC_PAGESIZE) +#endif +#endif + +#ifndef GNU_OUR_PAGESIZE +# ifdef PAGESIZE +# define GNU_OUR_PAGESIZE PAGESIZE +# else /* no PAGESIZE */ +# ifdef EXEC_PAGESIZE +# define GNU_OUR_PAGESIZE EXEC_PAGESIZE +# else /* no EXEC_PAGESIZE */ +# ifdef NBPG +# define GNU_OUR_PAGESIZE (NBPG * CLSIZE) +# ifndef CLSIZE +# define CLSIZE 1 +# endif /* CLSIZE */ +# else /* no NBPG */ +# ifdef NBPC +# define GNU_OUR_PAGESIZE NBPC +# else /* no NBPC */ +# define GNU_OUR_PAGESIZE 4096 /* Just punt and use reasonable value */ +# endif /* NBPC */ +# endif /* NBPG */ +# endif /* EXEC_PAGESIZE */ +# endif /* PAGESIZE */ +#endif /* GNU_OUR_PAGESIZE */ + +int +getpagesize () +{ + return (GNU_OUR_PAGESIZE); +} + +#else /* VMS */ + +#if 0 /* older distributions of gcc-vms are missing */ +#include +#endif +#ifndef SYI$_PAGE_SIZE /* VMS V5.4 and earlier didn't have this yet */ +#define SYI$_PAGE_SIZE 4452 +#endif +extern unsigned long lib$getsyi(const unsigned short *,...); + +int getpagesize () +{ + long pagsiz = 0L; + unsigned short itmcod = SYI$_PAGE_SIZE; + + (void) lib$getsyi (&itmcod, (void *) &pagsiz); + if (pagsiz == 0L) + pagsiz = 512L; /* VAX default */ + return (int) pagsiz; +} + +#endif /* VMS */ diff --git a/src/libs/stdc++/indstream.cc b/src/libs/stdc++/indstream.cc new file mode 100644 index 0000000000..15a1bb2778 --- /dev/null +++ b/src/libs/stdc++/indstream.cc @@ -0,0 +1,121 @@ +/* This is part of libio/iostream, providing -*- C++ -*- input/output. +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. + +Written by Per Bothner (bothner@cygnus.com). */ + +#ifdef __GNUG__ +#pragma implementation +#endif + +#include + +indirectbuf::indirectbuf(streambuf *get, streambuf *put, int delete_mode) +: streambuf() +{ + _get_stream = get; + _put_stream = put == NULL ? get : put; + _delete_flags = delete_mode; +} + +indirectbuf::~indirectbuf() +{ + if (_delete_flags & ios::in) delete get_stream(); + if (_delete_flags & ios::out) delete put_stream(); +} + +streamsize indirectbuf::xsputn(const char* s, streamsize n) +{ + return put_stream()->sputn(s, n); +} + +streamsize indirectbuf::xsgetn(char* s, streamsize n) +{ + return get_stream()->sgetn(s, n); +} + +int indirectbuf::overflow(int c /* = EOF */) +{ + if (c == EOF) + return put_stream()->overflow(c); + else + return put_stream()->sputc(c); +} + +int indirectbuf::underflow() +{ + return get_stream()->sgetc(); +} + +int indirectbuf::uflow() +{ + return get_stream()->sbumpc(); +} + +streampos indirectbuf::seekoff(streamoff off, _seek_dir dir, int mode) +{ + int ret_val = 0; + int select = mode == 0 ? (ios::in|ios::out) : mode; + streambuf *gbuf = (select & ios::in) ? get_stream() : (streambuf*)NULL; + streambuf *pbuf = (select & ios::out) ? put_stream() : (streambuf*)NULL; + if (gbuf == pbuf) + ret_val = gbuf->seekoff(off, dir, mode); + else { + if (gbuf) + ret_val = gbuf->seekoff(off, dir, ios::in); + if (pbuf && ret_val != EOF) + ret_val = pbuf->seekoff(off, dir, ios::out); + } + return ret_val; +} + +streampos indirectbuf::seekpos(streampos pos, int mode) +{ + int ret_val = EOF; + int select = mode == 0 ? (ios::in|ios::out) : mode; + streambuf *gbuf = (select & ios::in) ? get_stream() : (streambuf*)NULL; + streambuf *pbuf = (select & ios::out) ? put_stream() : (streambuf*)NULL; + if (gbuf == pbuf && gbuf != NULL) + ret_val = gbuf->seekpos(pos, mode); + else { + if (gbuf) + ret_val = gbuf->seekpos(pos, ios::in); + if (pbuf && ret_val != EOF) + ret_val = pbuf->seekpos(pos, ios::out); + } + return ret_val; +} + +int indirectbuf::sync() +{ + streambuf *gbuf = get_stream(); + int get_ret_val = gbuf ? gbuf->sync() : 0; + streambuf *pbuf = put_stream(); + int put_ret_val = (pbuf && pbuf != gbuf) ? pbuf->sync() : 0; + return get_ret_val || put_ret_val; +} + +int indirectbuf::pbackfail(int c) +{ + return get_stream()->sputbackc(c); +} diff --git a/src/libs/stdc++/insque.c b/src/libs/stdc++/insque.c new file mode 100644 index 0000000000..775019f8ff --- /dev/null +++ b/src/libs/stdc++/insque.c @@ -0,0 +1,50 @@ +/* insque(3C) routines + This file is in the public domain. */ + +/* +NAME + insque, remque -- insert, remove an element from a queue + +SYNOPSIS + struct qelem { + struct qelem *q_forw; + struct qelem *q_back; + char q_data[]; + }; + + void insque (struct qelem *elem, struct qelem *pred) + + void remque (struct qelem *elem) + +DESCRIPTION + Routines to manipulate queues built from doubly linked lists. + The insque routine inserts ELEM in the queue immediately after + PRED. The remque routine removes ELEM from its containing queue. +*/ + + +struct qelem { + struct qelem *q_forw; + struct qelem *q_back; +}; + + +void +insque (elem, pred) + struct qelem *elem; + struct qelem *pred; +{ + elem -> q_forw = pred -> q_forw; + pred -> q_forw -> q_back = elem; + elem -> q_back = pred; + pred -> q_forw = elem; +} + + +void +remque (elem) + struct qelem *elem; +{ + elem -> q_forw -> q_back = elem -> q_back; + elem -> q_back -> q_forw = elem -> q_forw; +} diff --git a/src/libs/stdc++/ioassign.cc b/src/libs/stdc++/ioassign.cc new file mode 100644 index 0000000000..5b8e68bbf5 --- /dev/null +++ b/src/libs/stdc++/ioassign.cc @@ -0,0 +1,49 @@ +/* This is part of libio/iostream, providing -*- C++ -*- input/output. +Copyright (C) 1994 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + +/* Written by Per Bothner (bothner@cygnus.com). */ + +#include +#include "libioP.h" + +// These method are provided for backward compatibility reasons. +// It's generally poor style to use them. +// They are not supported by the ANSI/ISO working paper. + +_IO_istream_withassign& _IO_istream_withassign::operator=(istream& rhs) +{ + if (&rhs != (istream*)this) + { + init (rhs.rdbuf ()); + _gcount = 0; + } + return *this; +} + +_IO_ostream_withassign& _IO_ostream_withassign::operator=(ostream& rhs) +{ + if (&rhs != (ostream*)this) + init (rhs.rdbuf ()); + return *this; +} diff --git a/src/libs/stdc++/ioextend.cc b/src/libs/stdc++/ioextend.cc new file mode 100644 index 0000000000..a31ff36e6e --- /dev/null +++ b/src/libs/stdc++/ioextend.cc @@ -0,0 +1,132 @@ +/* +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General 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 + +static int __xalloc = 0; + +int ios::xalloc() +{ + return __xalloc++; +} + +static ios::fmtflags __used_fmt_flags += ios::skipws | ios::left | ios::right | ios::internal +| ios::dec | ios::oct | ios::hex | ios::showbase | ios::showpoint +| ios::uppercase | ios::showpos | ios::scientific | ios::fixed +#ifndef _IO_NEW_STREAMS +| ios::dont_close +#endif +| ios::unitbuf | ios::stdio; + +ios::fmtflags ios::bitalloc() +{ + fmtflags bit_to_try = (fmtflags)1; + for (; bit_to_try; bit_to_try <<= 1) + { + if ((__used_fmt_flags & bit_to_try) == 0) + { + __used_fmt_flags |= bit_to_try; + return bit_to_try; + } + } + return 0; +} + +// NOTE: This implementation of ios::iword and ios::pword assumes +// that these methods are seldom used, so we want to minimize +// the space and time overhead when NOT using these methods. +// +// ANSI specifies two conceptually-infinite arrays, one whose +// elements are longs, and one whose elements are (void*)s. +// We implement this as a single array, each of whose element is +// a (struct ptr_and_long), which has space for both a long and a void*. +// We also specify that (the i field of) the 0'th element of the array +// contains the allocated length of the array (not counting that +// initial element). + +struct ptr_and_long { + void *p; + long i; +}; + +static struct ptr_and_long& +get_array_element(ios& io, int index) +{ + if (index < 0) + io._throw_failure(); + register struct ptr_and_long *array = (ptr_and_long*)io._arrays; + int old_length = array == NULL ? 0 : array[0].i; + if (index >= old_length) + { + register int i; + int new_length = index + 10; + register struct ptr_and_long *new_array + = new ptr_and_long[1 + new_length]; + if (array != NULL) + { + for (i = 1; i <= old_length; i++) + new_array[i] = array[i]; + delete [] array; + } + for (i = old_length + 1; i <= new_length; i++) + { + new_array[i].i = 0; + new_array[i].p = NULL; + } + new_array[0].i = new_length; + new_array[0].p = NULL; + io._arrays = (void*)new_array; + array = new_array; + } + return array[index+1]; +} + +long& ios::iword(int index) +{ + return get_array_element(*this, index).i; +} + +void*& ios::pword(int index) +{ + return get_array_element(*this, index).p; +} + +long ios::iword(int index) const +{ + if (index < 0) + _throw_failure(); + register struct ptr_and_long *pl_array = (ptr_and_long*)_arrays; + int len = pl_array == NULL ? 0 : pl_array[0].i; + return index >= len ? 0 : pl_array[index+1].i; +} + +void* ios::pword(int index) const +{ + if (index < 0) + _throw_failure(); + register struct ptr_and_long *pl_array = (ptr_and_long*)_arrays; + int len = pl_array == NULL ? 0 : pl_array[0].i; + return index >= len ? 0 : pl_array[index+1].p; +} diff --git a/src/libs/stdc++/iomanip.cc b/src/libs/stdc++/iomanip.cc new file mode 100644 index 0000000000..fddba55a2b --- /dev/null +++ b/src/libs/stdc++/iomanip.cc @@ -0,0 +1,90 @@ +/* This is part of libio/iostream, providing -*- C++ -*- input/output. +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + +#ifdef __GNUG__ +#pragma implementation +#endif + +#include "iomanip.h" + + +// Those functions are called through a pointer, +// thus it does not make sense, to inline them. + +ios & __iomanip_setbase (ios& i, int n) +{ + ios::fmtflags b; + switch (n) + { + case 8: + b = ios::oct; break; + case 10: + b = ios::dec; break; + case 16: + b = ios::hex; break; + default: + b = 0; + } + i.setf(b, ios::basefield); + return i; +} + +ios & __iomanip_setfill (ios& i, int n) +{ + //FIXME if ( i.flags() & ios::widechar ) + i.fill( (char) n); + //FIXME else + //FIXME i.fill( (wchar) n); + return i; +} + +ios & __iomanip_setprecision (ios& i, int n) +{ + i.precision(n); + return i; +} +ios & __iomanip_setw (ios& i, int n) +{ + i.width(n); + return i; +} + +ios & __iomanip_setiosflags (ios& i, ios::fmtflags n) +{ + i.setf(n,n); + return i; +} + +ios & __iomanip_resetiosflags (ios& i, ios::fmtflags n) +{ + i.setf(0,n); + return i; +} + +template class smanip; +template class smanip; +template istream& operator>>(istream&, const smanip&); +template istream& operator>>(istream&, const smanip&); +template ostream& operator<<(ostream&, const smanip&); +template ostream& operator<<(ostream&, const smanip&); diff --git a/src/libs/stdc++/iostream.cc b/src/libs/stdc++/iostream.cc new file mode 100644 index 0000000000..84011d11a2 --- /dev/null +++ b/src/libs/stdc++/iostream.cc @@ -0,0 +1,1098 @@ +/* This is part of libio/iostream, providing -*- C++ -*- input/output. + Copyright (C) 1993, 1997, 2000 Free Software Foundation, Inc. + + This file is part of the GNU IO Library. This library is free + software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) + any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this library; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. + + As a special exception, if you link this library with files + compiled with a GNU compiler to produce an executable, this does not cause + the resulting executable to be covered by the GNU General Public License. + This exception does not however invalidate any other reasons why + the executable file might be covered by the GNU General Public License. */ + +/* Written by Per Bothner (bothner@cygnus.com). */ + +#ifdef __GNUC__ +#pragma implementation +#endif +#define _STREAM_COMPAT +#include +#include "libioP.h" +#include /* Needed for sprintf */ +#include +#include +#include + +#if _G_HAVE_PRINTF_FP +#include +extern "C" int __printf_fp (_IO_FILE *, const struct printf_info *, + const void *const *); +#else +#include "floatio.h" +# ifndef _IO_USE_DTOA +int __cvt_double(double number, register int prec, int flags, int *signp, + int fmtch, char *startp, char *endp); +# endif +#endif + +#define BUF (MAXEXP+MAXFRACT+1) /* + decimal point */ + +//#define isspace(ch) ((ch)==' ' || (ch)=='\t' || (ch)=='\n') + +istream::istream(streambuf *sb, ostream* tied) +{ + init (sb, tied); + _gcount = 0; +} + +int skip_ws(streambuf* sb) +{ + int ch; + for (;;) { + ch = sb->sbumpc(); + if (ch == EOF || !isspace(ch)) + return ch; + } +} + +istream& istream::get(char& c) +{ + if (ipfx1()) { + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _strbuf); + int ch = _strbuf->sbumpc(); + if (ch == EOF) { + set(ios::eofbit|ios::failbit); + _gcount = 0; + } + else { + c = (char)ch; + _gcount = 1; + } + isfx(); + _IO_cleanup_region_end (0); + } + else + _gcount = 0; + return *this; +} + +int istream::peek() +{ + if (!good()) + return EOF; + if (_tie && rdbuf()->in_avail() == 0) + _tie->flush(); + int ch = _strbuf->sgetc(); + if (ch == EOF) + set(ios::eofbit); + return ch; +} + +// [zooey]: added for R5-compatibility with bdb +istream& istream::read(char *ptr, int n) +{ + return read((char*)ptr, (streamsize)n); +} +istream& istream::read(unsigned char *ptr, int n) +{ + return read((char*)ptr, (streamsize)n); +} +istream& istream::read(signed char *ptr, int n) +{ + return read((char*)ptr, (streamsize)n); +} +istream& istream::read(void *ptr, int n) +{ + return read((char*)ptr, (streamsize)n); +} + +istream& istream::ignore(int n /* = 1 */, int delim /* = EOF */) +{ + _gcount = 0; + if (ipfx1()) { + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _strbuf); + register streambuf* sb = _strbuf; + if (delim == EOF) { + _gcount = sb->ignore(n); + goto unlock; + } + for (;;) { +#if 0 + if (n != MAXINT) // FIXME +#endif + if (--n < 0) + break; + int ch = sb->sbumpc(); + if (ch == EOF) { + set(ios::eofbit|ios::failbit); + break; + } + _gcount++; + if (ch == delim) + break; + } + unlock: + isfx(); + _IO_cleanup_region_end (0); + } + return *this; +} + +istream& istream::read(char *s, streamsize n) +{ + if (ipfx1()) { + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _strbuf); + _gcount = _strbuf->sgetn(s, n); + if ((streamsize)_gcount != n) + set(ios::failbit|ios::eofbit); + isfx(); + _IO_cleanup_region_end (0); + } + else + _gcount = 0; + return *this; +} + +int +istream::sync () +{ + streambuf *sb = rdbuf (); + if (sb == NULL) + return EOF; + if (sb->sync ()) // Later: pubsync + { + setstate (ios::badbit); + return EOF; + } + else + return 0; +} + +istream& istream::seekg(streampos pos) +{ + pos = _strbuf->pubseekpos(pos, ios::in); + if (pos == streampos(EOF)) + set(ios::badbit); + return *this; +} + +istream& istream::seekg(streamoff off, _seek_dir dir) +{ + streampos pos = _IO_seekoff (_strbuf, off, (int) dir, _IOS_INPUT); + if (pos == streampos(EOF)) + set(ios::badbit); + return *this; +} + +streampos istream::tellg() +{ +#if 0 + streampos pos = _strbuf->pubseekoff(0, ios::cur, ios::in); +#else + streampos pos = _IO_seekoff (_strbuf, 0, _IO_seek_cur, _IOS_INPUT); +#endif + if (pos == streampos(EOF)) + set(ios::badbit); + return pos; +} + +istream& istream::operator>>(char& c) +{ + if (ipfx0()) { + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _strbuf); + int ch = _strbuf->sbumpc(); + if (ch == EOF) + set(ios::eofbit|ios::failbit); + else + c = (char)ch; + isfx(); + _IO_cleanup_region_end (0); + } + return *this; +} + +istream& +istream::operator>> (char* ptr) +{ + register char *p = ptr; + int w = width(0); + if (ipfx0()) + { + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _strbuf); + register streambuf* sb = _strbuf; + for (;;) + { + int ch = sb->sbumpc(); + if (ch == EOF) + { + set(ios::eofbit); + break; + } + else if (isspace(ch) || w == 1) + { + sb->sputbackc(ch); + break; + } + else *p++ = ch; + w--; + } + if (p == ptr) + set(ios::failbit); + isfx(); + _IO_cleanup_region_end (0); + } + *p = '\0'; + return *this; +} + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +#define LONGEST long long +#else +#define LONGEST long +#endif + +static int read_int(istream& stream, unsigned LONGEST& val, int& neg) +{ + if (!stream.ipfx0()) + return 0; + int retval; + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + stream._strbuf); + register streambuf* sb = stream.rdbuf(); + int base = 10; + int ndigits = 0; + register int ch = skip_ws(sb); + if (ch == EOF) + goto eof_fail; + neg = 0; + if (ch == '+') { + ch = skip_ws(sb); + } + else if (ch == '-') { + neg = 1; + ch = skip_ws(sb); + } + if (ch == EOF) goto eof_fail; + if (!(stream.flags() & ios::basefield)) { + if (ch == '0') { + ch = sb->sbumpc(); + if (ch == EOF) { + val = 0; + goto unlock; + } + if (ch == 'x' || ch == 'X') { + base = 16; + ch = sb->sbumpc(); + if (ch == EOF) goto eof_fail; + } + else { + sb->sputbackc(ch); + base = 8; + ch = '0'; + } + } + } + else if ((stream.flags() & ios::basefield) == ios::hex) + base = 16; + else if ((stream.flags() & ios::basefield) == ios::oct) + base = 8; + val = 0; + for (;;) { + if (ch == EOF) + break; + int digit; + if (ch >= '0' && ch <= '9') + digit = ch - '0'; + else if (ch >= 'A' && ch <= 'F') + digit = ch - 'A' + 10; + else if (ch >= 'a' && ch <= 'f') + digit = ch - 'a' + 10; + else + digit = 999; + if (digit >= base) { + sb->sputbackc(ch); + if (ndigits == 0) + goto fail; + else + goto unlock; + } + ndigits++; + val = base * val + digit; + ch = sb->sbumpc(); + } + unlock: + retval = 1; + goto out; + fail: + stream.set(ios::failbit); + retval = 0; + goto out; + eof_fail: + stream.set(ios::failbit|ios::eofbit); + retval = 0; + out: + stream.isfx(); + _IO_cleanup_region_end (0); + return retval; +} + +#define READ_INT(TYPE) \ +istream& istream::operator>>(TYPE& i)\ +{\ + unsigned LONGEST val; int neg;\ + if (read_int(*this, val, neg)) {\ + if (neg) val = -val;\ + i = (TYPE)val;\ + }\ + return *this;\ +} + +READ_INT(short) +READ_INT(unsigned short) +READ_INT(int) +READ_INT(unsigned int) +READ_INT(long) +READ_INT(unsigned long) +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +READ_INT(long long) +READ_INT(unsigned long long) +#endif +#if _G_HAVE_BOOL +READ_INT(bool) +#endif + +static void do_scan(istream *istr, const char *format, ...) +{ + streambuf *_strbuf = istr->_strbuf; + va_list ap; + va_start(ap, format); + int errcode = 0; + int count = _IO_vfscanf(_strbuf, format, ap, &errcode); + if ((errcode & (_IOS_EOF|_IOS_FAIL)) == _IOS_EOF && count != 1) + errcode |= _IOS_FAIL; + istr->setstate((ios::iostate)errcode); + va_end(ap); +} + +istream& istream::operator>>(long double& x) +{ + if (ipfx0()) + { + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _strbuf); +#if _G_HAVE_LONG_DOUBLE_IO + do_scan(this, "%Lg", &x); +#else + double y; + do_scan(this, "%lg", &y); + x = y; +#endif + isfx(); + _IO_cleanup_region_end (0); + } + return *this; +} + +istream& istream::operator>>(double& x) +{ + if (ipfx0()) + { + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _strbuf); + do_scan(this, "%lg", &x); + isfx(); + _IO_cleanup_region_end (0); + } + return *this; +} + +istream& istream::operator>>(float& x) +{ + if (ipfx0()) + { + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _strbuf); + do_scan(this, "%g", &x); + isfx(); + _IO_cleanup_region_end (0); + } + return *this; +} + +istream& istream::operator>>(register streambuf* sbuf) +{ + if (ipfx0()) { + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _strbuf); + register streambuf* inbuf = rdbuf(); + // FIXME: Should optimize! + for (;;) { + register int ch = inbuf->sbumpc(); + if (ch == EOF) { + set(ios::eofbit); + break; + } + if (sbuf->sputc(ch) == EOF) { + set(ios::failbit); + break; + } + } + isfx(); + _IO_cleanup_region_end (0); + } + return *this; +} + +ostream& ostream::operator<<(char c) +{ + if (opfx()) { + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _strbuf); +#if 1 + // This is what the cfront implementation does. + if (_strbuf->sputc(c) == EOF) { + set(ios::badbit); + goto failed; + } +#else + // This is what cfront documentation and current ANSI drafts say. + int w = width(0); + char fill_char = fill(); + register int padding = w > 0 ? w - 1 : 0; + register streambuf *sb = _strbuf; + if (!(flags() & ios::left) && padding) // Default adjustment. + if (_IO_padn(sb, fill_char, padding) < padding) { + set(ios::badbit); + goto failed; + } + if (sb->sputc(c) == EOF) { + set(ios::badbit); + goto failed; + } + if (flags() & ios::left && padding) // Left adjustment. + if (_IO_padn(sb, fill_char, padding) < padding) + set(ios::badbit); +#endif + failed: + osfx(); + _IO_cleanup_region_end (0); + } + return *this; +} + +/* Write VAL on STREAM. + If SIGN<0, val is the absolute value of a negative number. + If SIGN>0, val is a signed non-negative number. + If SIGN==0, val is unsigned. */ + +static void write_int(ostream& stream, unsigned LONGEST val, int sign) +{ +#define WRITE_BUF_SIZE (10 + sizeof(unsigned LONGEST) * 3) + char buf[WRITE_BUF_SIZE]; + register char *buf_ptr = buf+WRITE_BUF_SIZE; // End of buf. + const char *show_base = ""; + int show_base_len = 0; + int show_pos = 0; // If 1, print a '+'. + + // Now do the actual conversion, placing the result at the *end* of buf. + // Note that we use separate code for decimal, octal, and hex, + // so we can divide by optimizable constants. + if ((stream.flags() & ios::basefield) == ios::oct) { // Octal + do { + *--buf_ptr = (val & 7) + '0'; + val = val >> 3; + } while (val != 0); + if ((stream.flags() & ios::showbase) && (*buf_ptr != '0')) + *--buf_ptr = '0'; + } + else if ((stream.flags() & ios::basefield) == ios::hex) { // Hex + const char *xdigs = (stream.flags() & ios::uppercase) ? "0123456789ABCDEF0X" + : "0123456789abcdef0x"; + do { + *--buf_ptr = xdigs[val & 15]; + val = val >> 4; + } while (val != 0); + if ((stream.flags() & ios::showbase)) { + show_base = xdigs + 16; // Either "0X" or "0x". + show_base_len = 2; + } + } + else { // Decimal +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) + // Optimization: Only use long long when we need to. + while (val > UINT_MAX) { + *--buf_ptr = (val % 10) + '0'; + val /= 10; + } + // Use more efficient (int) arithmetic for the rest. + register unsigned int ival = (unsigned int)val; +#else + register unsigned LONGEST ival = val; +#endif + do { + *--buf_ptr = (ival % 10) + '0'; + ival /= 10; + } while (ival != 0); + if (sign > 0 && (stream.flags() & ios::showpos)) + show_pos=1; + } + + int buf_len = buf+WRITE_BUF_SIZE - buf_ptr; + int w = stream.width(0); + + // Calculate padding. + int len = buf_len+show_pos; + if (sign < 0) len++; + len += show_base_len; + int padding = len > w ? 0 : w - len; + + // Do actual output. + register streambuf* sbuf = stream.rdbuf(); + ios::fmtflags pad_kind = + stream.flags() & (ios::left|ios::right|ios::internal); + char fill_char = stream.fill(); + if (padding > 0 + && pad_kind != (ios::fmtflags)ios::left + && pad_kind != (ios::fmtflags)ios::internal) // Default (right) adjust. + if (_IO_padn(sbuf, fill_char, padding) < padding) + goto failed; + if (sign < 0 || show_pos) + { + char ch = sign < 0 ? '-' : '+'; + if (sbuf->sputc(ch) < 0) + goto failed; + } + if (show_base_len) + if (_IO_sputn(sbuf, show_base, show_base_len) <= 0) + goto failed; + if (pad_kind == (ios::fmtflags)ios::internal && padding > 0) + if (_IO_padn(sbuf, fill_char, padding) < padding) + goto failed; + if ((int)_IO_sputn (sbuf, buf_ptr, buf_len) != buf_len) + goto failed; + if (pad_kind == (ios::fmtflags)ios::left && padding > 0) // Left adjustment + if (_IO_padn(sbuf, fill_char, padding) < padding) + goto failed; + stream.osfx(); + return; + failed: + stream.set(ios::badbit); + stream.osfx(); +} + +ostream& ostream::operator<<(int n) +{ + if (opfx()) { + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _strbuf); + int sign = 1; + unsigned int abs_n = (unsigned)n; + if (n < 0 && (flags() & (ios::oct|ios::hex)) == 0) + abs_n = -((unsigned)n), sign = -1; + write_int(*this, abs_n, sign); + _IO_cleanup_region_end (0); + } + return *this; +} + +ostream& ostream::operator<<(unsigned int n) +{ + if (opfx()) { + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _strbuf); + write_int(*this, n, 0); + _IO_cleanup_region_end (0); + } + return *this; +} + + +ostream& ostream::operator<<(long n) +{ + if (opfx()) { + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _strbuf); + int sign = 1; + unsigned long abs_n = (unsigned long)n; + if (n < 0 && (flags() & (ios::oct|ios::hex)) == 0) + abs_n = -((unsigned long)n), sign = -1; + write_int(*this, abs_n, sign); + _IO_cleanup_region_end (0); + } + return *this; +} + +ostream& ostream::operator<<(unsigned long n) +{ + if (opfx()) { + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _strbuf); + write_int(*this, n, 0); + _IO_cleanup_region_end (0); + } + return *this; +} + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +ostream& ostream::operator<<(long long n) +{ + if (opfx()) { + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _strbuf); + int sign = 1; + unsigned long long abs_n = (unsigned long long)n; + if (n < 0 && (flags() & (ios::oct|ios::hex)) == 0) + abs_n = -((unsigned long long)n), sign = -1; + write_int(*this, abs_n, sign); + _IO_cleanup_region_end (0); + } + return *this; +} + + +ostream& ostream::operator<<(unsigned long long n) +{ + if (opfx()) { + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _strbuf); + write_int(*this, n, 0); + _IO_cleanup_region_end (0); + } + return *this; +} +#endif /*__GNUC__*/ + +ostream& ostream::operator<<(double n) +{ + if (opfx()) { + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _strbuf); + // Uses __cvt_double (renamed from static cvt), in Chris Torek's + // stdio implementation. The setup code uses the same logic + // as in __vsbprintf.C (also based on Torek's code). + int format_char; + if ((flags() & ios::floatfield) == ios::fixed) + format_char = 'f'; + else if ((flags() & ios::floatfield) == ios::scientific) + format_char = flags() & ios::uppercase ? 'E' : 'e'; + else + format_char = flags() & ios::uppercase ? 'G' : 'g'; + + int prec = precision(); + if (prec <= 0 && !(flags() & ios::fixed)) + prec = 6; /* default */ + + // Do actual conversion. +#if _G_HAVE_PRINTF_FP + { + struct printf_info info = { /* prec: */ prec, + /* width: */ width(0), + /* spec: */ format_char, + /* is_long_double: */ 0, + /* is_short: */ 0, + /* is_long: */ 0, + /* alt: */ (flags() & ios::showpoint) != 0, + /* space: */ 0, + /* left: */ (flags() & ios::left) != 0, + /* showsign: */ (flags() & ios::showpos) != 0, + /* group: */ 0, +#if defined __GLIBC__ && (__GLIBC__ >= 2 || __GLIBC__ <= -2) + /* extra: */ 0, +#if __GLIBC_MINOR__ >= 1 + /* is_char: */ 0, +#if __GLIBC_MINOR__ >= 2 + /* wide: */ 0, + /* i18n: */ 0, +#endif +#endif +#endif + /* pad: */ fill() + }; + const void *ptr = (const void *) &n; + if (__printf_fp (rdbuf(), &info, &ptr) < 0) + set(ios::badbit|ios::failbit); + } +#elif defined _IO_USE_DTOA + if (_IO_outfloat(n, rdbuf(), format_char, width(0), + prec, flags(), + flags() & ios::showpos ? '+' : 0, + fill()) < 0) + set(ios::badbit|ios::failbit); // ?? +#else + int fpprec = 0; // 'Extra' (suppressed) floating precision. + if (prec > MAXFRACT) { + if (flags() & (ios::fixed|ios::scientific) & ios::showpos) + fpprec = prec - MAXFRACT; + prec = MAXFRACT; + } + int negative; + char buf[BUF]; + int sign = '\0'; + char *cp = buf; + *cp = 0; + int size = __cvt_double(n, prec, + flags() & ios::showpoint ? 0x80 : 0, + &negative, + format_char, cp, buf + sizeof(buf)); + if (negative) sign = '-'; + else if (flags() & ios::showpos) sign = '+'; + if (*cp == 0) + cp++; + + // Calculate padding. + int fieldsize = size + fpprec; + if (sign) fieldsize++; + int padding = 0; + int w = width(0); + if (fieldsize < w) + padding = w - fieldsize; + + // Do actual output. + register streambuf* sbuf = rdbuf(); + register i; + char fill_char = fill(); + ios::fmtflags pad_kind = + flags() & (ios::left|ios::right|ios::internal); + if (pad_kind != (ios::fmtflags)ios::left // Default (right) adjust. + && pad_kind != (ios::fmtflags)ios::internal) + for (i = padding; --i >= 0; ) sbuf->sputc(fill_char); + if (sign) + sbuf->sputc(sign); + if (pad_kind == (ios::fmtflags)ios::internal) + for (i = padding; --i >= 0; ) sbuf->sputc(fill_char); + + // Emit the actual concented field, followed by extra zeros. + _IO_sputn (sbuf, cp, size); + for (i = fpprec; --i >= 0; ) sbuf->sputc('0'); + + if (pad_kind == (ios::fmtflags)ios::left) // Left adjustment + for (i = padding; --i >= 0; ) sbuf->sputc(fill_char); +#endif + osfx(); + _IO_cleanup_region_end (0); + } + return *this; +} + +#if _G_HAVE_LONG_DOUBLE_IO +ostream& ostream::operator<<(long double n) +{ + if (opfx()) + { + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _strbuf); + int format_char; + if ((flags() & ios::floatfield) == ios::fixed) + format_char = 'f'; + else if ((flags() & ios::floatfield) == ios::scientific) + format_char = flags() & ios::uppercase ? 'E' : 'e'; + else + format_char = flags() & ios::uppercase ? 'G' : 'g'; + + int prec = precision(); + if (prec <= 0 && !(flags() & ios::fixed)) + prec = 6; /* default */ + +#if _G_HAVE_PRINTF_FP + // Do actual conversion. + struct printf_info info = { /* prec: */ prec, + /* width: */ width(0), + /* spec: */ format_char, + /* is_long_double: */ 1, + /* is_short: */ 0, + /* is_long: */ 0, + /* alt: */ (flags() & ios::showpoint) != 0, + /* space: */ 0, + /* left: */ (flags() & ios::left) != 0, + /* showsign: */ (flags() & ios::showpos) != 0, + /* group: */ 0, +#if defined __GLIBC__ && (__GLIBC__ >= 2 || __GLIBC__ <= -2) + /* extra: */ 0, +#if __GLIBC_MINOR__ >= 1 + /* is_char: */ 0, +#if __GLIBC_MINOR__ >= 2 + /* wide: */ 0, + /* i18n: */ 0, +#endif +#endif +#endif + /* pad: */ fill() + }; + + const void *ptr = (const void *) &n; + + if (__printf_fp (rdbuf(), &info, &ptr) < 0) + set (ios::badbit|ios::failbit); +#else +# error "long double I/O using dtoa or cvt_double is not implemented" +#endif + osfx(); + _IO_cleanup_region_end (0); + } + return *this; +} +#endif + +ostream& ostream::operator<<(const char *s) +{ + if (opfx()) + { + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _strbuf); + if (s == NULL) + s = "(null)"; + int len = strlen(s); + int w = width(0); +// FIXME: Should we: if (w && len>w) len = w; + char fill_char = fill(); + register streambuf *sbuf = rdbuf(); + register int padding = w > len ? w - len : 0; + if (!(flags() & ios::left) && padding > 0) // Default adjustment. + if (_IO_padn(sbuf, fill_char, padding) != padding) + { + set(ios::badbit); + goto failed; + } + if ((int)_IO_sputn (sbuf, s, len) != len) + { + set(ios::badbit); + goto failed; + } + if (flags() & ios::left && padding > 0) // Left adjustment. + if (_IO_padn(sbuf, fill_char, padding) != padding) + set(ios::badbit); + failed: + osfx(); + _IO_cleanup_region_end (0); + } + return *this; +} + +#if 0 +ostream& ostream::operator<<(const void *p) +{ Is in osform.cc, to avoid pulling in all of _IO_vfprintf by this file. */ } +#endif + +ostream& ostream::operator<<(register streambuf* sbuf) +{ + if (opfx()) + { + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _strbuf); + char buffer[_IO_BUFSIZ]; + register streambuf* outbuf = _strbuf; + for (;;) + { + _IO_size_t count = _IO_sgetn(sbuf, buffer, _IO_BUFSIZ); + if (count <= 0) + break; + if (_IO_sputn(outbuf, buffer, count) != count) + { + set(ios::badbit); + break; + } + } + osfx(); + _IO_cleanup_region_end (0); + } + return *this; +} + +ostream::ostream(streambuf* sb, ostream* tied) +{ + init (sb, tied); +} + +ostream& ostream::seekp(streampos pos) +{ + pos = _strbuf->pubseekpos(pos, ios::out); + if (pos == streampos(EOF)) + set(ios::badbit); + return *this; +} + +ostream& ostream::seekp(streamoff off, _seek_dir dir) +{ + streampos pos = _IO_seekoff (_strbuf, off, (int) dir, _IOS_OUTPUT); + if (pos == streampos(EOF)) + set(ios::badbit); + return *this; +} + +streampos ostream::tellp() +{ +#if 1 + streampos pos = _IO_seekoff (_strbuf, 0, _IO_seek_cur, _IOS_OUTPUT); +#else + streampos pos = _strbuf->pubseekoff(0, ios::cur, ios::out); +#endif + if (pos == streampos(EOF)) + set(ios::badbit); + return pos; +} + +ostream& ostream::flush() +{ + if (_strbuf->sync()) + set(ios::badbit); + return *this; +} + +ostream& flush(ostream& outs) +{ + return outs.flush(); +} + +istream& ws(istream& ins) +{ + if (ins.ipfx1()) { + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + ins._strbuf); + int ch = skip_ws(ins._strbuf); + if (ch == EOF) + ins.set(ios::eofbit); + else + ins._strbuf->sputbackc(ch); + ins.isfx(); + _IO_cleanup_region_end (0); + } + return ins; +} + +// Skip white-space. Return 0 on failure (EOF), or 1 on success. +// Differs from ws() manipulator in that failbit is set on EOF. +// Called by ipfx() and ipfx0() if needed. + +int istream::_skip_ws() +{ + int ch = skip_ws(_strbuf); + if (ch == EOF) { + set(ios::eofbit|ios::failbit); + return 0; + } + else { + _strbuf->sputbackc(ch); + return 1; + } +} + +ostream& ends(ostream& outs) +{ + outs.put('\0'); + return outs; +} + +ostream& endl(ostream& outs) +{ + return flush(outs.put('\n')); +} + +istream& lock(istream& ins) +{ + _IO_flockfile (ins._strbuf); + return ins; +} +istream& unlock(istream& ins) +{ + _IO_funlockfile (ins._strbuf); + return ins; +} +ostream& lock(ostream& outs) +{ + _IO_flockfile (outs._strbuf); + return outs; +} +ostream& unlock(ostream& outs) +{ + _IO_funlockfile (outs._strbuf); + return outs; +} + + +ostream& ostream::write(const char *s, streamsize n) +{ + if (opfx()) { + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _strbuf); + if ((streamsize)_IO_sputn(_strbuf, s, n) != n) + set(ios::failbit); + osfx(); + _IO_cleanup_region_end (0); + } + return *this; +} + +// [zooey]: added for R5-compatibility +ostream& ostream::write(const char *s, int n) +{ + return write((const char*)s, (streamsize)n); +} +ostream& ostream::write(const unsigned char *s, int n) +{ + return write((const char*)s, (streamsize)n); +} +ostream& ostream::write(const signed char *s, int n) +{ + return write((const char*)s, (streamsize)n); +} +ostream& ostream::write(const void *s, int n) +{ + return write((const char*)s, (streamsize)n); +} + +void ostream::do_osfx() +{ + if (flags() & ios::unitbuf) + flush(); + if (flags() & ios::stdio) { + fflush(stdout); + fflush(stderr); + } +} + +iostream::iostream(streambuf* sb, ostream* tied) +{ + init (sb, tied); +} + +// NOTE: extension for compatibility with old libg++. +// Not really compatible with fistream::close(). +#ifdef _STREAM_COMPAT +void ios::close() +{ + if (_strbuf->_flags & _IO_IS_FILEBUF) + ((struct filebuf*)rdbuf())->close(); + else if (_strbuf != NULL) + rdbuf()->sync(); + _strbuf = NULL; + _state = badbit; +} + +int istream::skip(int i) +{ + int old = (_flags & ios::skipws) != 0; + if (i) + _flags |= ios::skipws; + else + _flags &= ~ios::skipws; + return old; +} +#endif diff --git a/src/libs/stdc++/iostreamP.h b/src/libs/stdc++/iostreamP.h new file mode 100644 index 0000000000..c9c40cb6ba --- /dev/null +++ b/src/libs/stdc++/iostreamP.h @@ -0,0 +1,26 @@ +/* +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General 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 "streambuf.h" +#include "libioP.h" diff --git a/src/libs/stdc++/isgetline.cc b/src/libs/stdc++/isgetline.cc new file mode 100644 index 0000000000..5e48a000c0 --- /dev/null +++ b/src/libs/stdc++/isgetline.cc @@ -0,0 +1,153 @@ +/* This is part of libio/iostream, providing -*- C++ -*- input/output. +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General 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 +#include "iostream.h" +#include + +istream& istream::getline(char* buf, int len, char delim) +{ + _gcount = 0; + if (len <= 0) + { + set(ios::failbit); + return *this; + } + int ch; + if (ipfx1()) + { + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _strbuf); + streambuf *sb = rdbuf(); + _gcount = _IO_getline_info(sb, buf, len - 1, delim, -1, &ch); + if (ch != EOF) + ch = sb->sbumpc(); + if (ch == EOF) + set (_gcount == 0 ? (ios::failbit|ios::eofbit) : ios::eofbit); + else if (ch != (unsigned char) delim) + { + set(ios::failbit); + sb->sungetc(); // Leave delimiter unread. + } + isfx(); + _IO_cleanup_region_end (0); + } + else + ch = EOF; + buf[_gcount] = '\0'; + if (ch == (unsigned char)delim) + _gcount++; // The delimiter is counted in the gcount(). + return *this; +} + +istream& istream::get(char* buf, int len, char delim) +{ + _gcount = 0; + if (len <= 0) + { + set(ios::failbit); + return *this; + } + if (ipfx1()) + { + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _strbuf); + streambuf *sbuf = rdbuf(); + int ch; + _gcount = _IO_getline_info(sbuf, buf, len - 1, delim, -1, &ch); + if (_gcount == 0 && ch == EOF) + set(ios::failbit|ios::eofbit); + isfx(); + _IO_cleanup_region_end (0); + } + buf[_gcount] = '\0'; + return *this; +} + + +// from Doug Schmidt + +#define CHUNK_SIZE 512 + +/* Reads an arbitrarily long input line terminated by a user-specified + TERMINATOR. Super-nifty trick using recursion avoids unnecessary calls + to NEW! */ + +char *_sb_readline (streambuf *sb, long& total, char terminator) +{ + char buf[CHUNK_SIZE]; + char *ptr; + int ch; + + _IO_size_t count = _IO_getline_info(sb, buf, CHUNK_SIZE, terminator, + -1, &ch); + if (ch != EOF) + ch = sb->sbumpc(); + long old_total = total; + total += count; + if (ch != EOF && ch != terminator) { + total++; // Include ch in total. + ptr = _sb_readline(sb, total, terminator); + if (ptr) { + memcpy(ptr + old_total, buf, count); + ptr[old_total+count] = ch; + } + return ptr; + } + + ptr = new char[total+1]; + if (ptr != NULL) { + ptr[total] = '\0'; + memcpy(ptr + total - count, buf, count); + } + return ptr; +} + +/* Reads an arbitrarily long input line terminated by TERMINATOR. + This routine allocates its own memory, so the user should + only supply the address of a (char *). */ + +istream& istream::gets(char **s, char delim /* = '\n' */) +{ + if (ipfx1()) { + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _strbuf); + long size = 0; + streambuf *sb = rdbuf(); + *s = _sb_readline (sb, size, delim); + _gcount = *s ? size : 0; + if (sb->_flags & _IO_EOF_SEEN) { + set(ios::eofbit); + if (_gcount == 0) + set(ios::failbit); + } + isfx(); + _IO_cleanup_region_end (0); + } + else { + _gcount = 0; + *s = NULL; + } + return *this; +} diff --git a/src/libs/stdc++/isgetsb.cc b/src/libs/stdc++/isgetsb.cc new file mode 100644 index 0000000000..655c972589 --- /dev/null +++ b/src/libs/stdc++/isgetsb.cc @@ -0,0 +1,63 @@ +/* This is part of libio/iostream, providing -*- C++ -*- input/output. +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General 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 "libioP.h" +#include "iostream.h" +#include + +istream& istream::get(streambuf& sb, char delim /* = '\n' */) +{ + _gcount = 0; + if (ipfx1()) + { + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _strbuf); + register streambuf* isb = rdbuf(); + for (;;) + { + streamsize len = isb->_IO_read_end - isb->_IO_read_ptr; + if (len <= 0) + if (__underflow(isb) == EOF) + break; + else + len = isb->_IO_read_end - isb->_IO_read_ptr; + char *delimp = (char*)memchr((void*)isb->_IO_read_ptr, delim, len); + if (delimp != NULL) + len = delimp - isb->_IO_read_ptr; + int written = sb.sputn(isb->_IO_read_ptr, len); + isb->_IO_read_ptr += written; + _gcount += written; + if (written != len) + { + set(ios::failbit); + break; + } + if (delimp != NULL) + break; + } + isfx(); + _IO_cleanup_region_end (0); + } + return *this; +} diff --git a/src/libs/stdc++/isscan.cc b/src/libs/stdc++/isscan.cc new file mode 100644 index 0000000000..977559c2cb --- /dev/null +++ b/src/libs/stdc++/isscan.cc @@ -0,0 +1,55 @@ +/* +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General 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 "libioP.h" +#include +#include + +istream& istream::scan(const char *format ...) +{ + if (ipfx0()) { + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _strbuf); + va_list ap; + va_start(ap, format); + _strbuf->vscan(format, ap, this); + va_end(ap); + isfx(); + _IO_cleanup_region_end (0); + } + return *this; +} + +istream& istream::vscan(const char *format, _IO_va_list args) +{ + if (ipfx0()) + { + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _strbuf); + _strbuf->vscan(format, args, this); + isfx(); + _IO_cleanup_region_end (0); + } + return *this; +} diff --git a/src/libs/stdc++/libiberty.h b/src/libs/stdc++/libiberty.h new file mode 100644 index 0000000000..cf313662ef --- /dev/null +++ b/src/libs/stdc++/libiberty.h @@ -0,0 +1,180 @@ +/* Function declarations for libiberty. + Written by Cygnus Support, 1994. + + The libiberty library provides a number of functions which are + missing on some operating systems. We do not declare those here, + to avoid conflicts with the system header files on operating + systems that do support those functions. In this file we only + declare those functions which are specific to libiberty. */ + +#ifndef LIBIBERTY_H +#define LIBIBERTY_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "ansidecl.h" + +/* Build an argument vector from a string. Allocates memory using + malloc. Use freeargv to free the vector. */ + +extern char **buildargv PARAMS ((char *)); + +/* Free a vector returned by buildargv. */ + +extern void freeargv PARAMS ((char **)); + +/* Duplicate an argument vector. Allocates memory using malloc. Use + freeargv to free the vector. */ + +extern char **dupargv PARAMS ((char **)); + + +/* Return the last component of a path name. Note that we can't use a + prototype here because the parameter is declared inconsistently + across different systems, sometimes as "char *" and sometimes as + "const char *" */ + +#if defined (__GNU_LIBRARY__ ) || defined (__linux__) || defined (__FreeBSD__) || defined (__CYGWIN__) || defined (__CYGWIN32__) +extern char *basename PARAMS ((const char *)); +#else +extern char *basename (); +#endif + +/* Concatenate an arbitrary number of strings, up to (char *) NULL. + Allocates memory using xmalloc. */ + +extern char *concat PARAMS ((const char *, ...)); + +/* Check whether two file descriptors refer to the same file. */ + +extern int fdmatch PARAMS ((int fd1, int fd2)); + +/* Get the amount of time the process has run, in microseconds. */ + +extern long get_run_time PARAMS ((void)); + +/* Choose a temporary directory to use for scratch files. */ + +extern char *choose_temp_base PARAMS ((void)); + +/* Allocate memory filled with spaces. Allocates using malloc. */ + +extern const char *spaces PARAMS ((int count)); + +/* Return the maximum error number for which strerror will return a + string. */ + +extern int errno_max PARAMS ((void)); + +/* Return the name of an errno value (e.g., strerrno (EINVAL) returns + "EINVAL"). */ + +extern const char *strerrno PARAMS ((int)); + +/* Given the name of an errno value, return the value. */ + +extern int strtoerrno PARAMS ((const char *)); + +/* ANSI's strerror(), but more robust. */ + +extern char *xstrerror PARAMS ((int)); + +/* Return the maximum signal number for which strsignal will return a + string. */ + +extern int signo_max PARAMS ((void)); + +/* Return a signal message string for a signal number + (e.g., strsignal (SIGHUP) returns something like "Hangup"). */ +/* This is commented out as it can conflict with one in system headers. + We still document its existence though. */ + +/*extern const char *strsignal PARAMS ((int));*/ + +/* Return the name of a signal number (e.g., strsigno (SIGHUP) returns + "SIGHUP"). */ + +extern const char *strsigno PARAMS ((int)); + +/* Given the name of a signal, return its number. */ + +extern int strtosigno PARAMS ((const char *)); + +/* Register a function to be run by xexit. Returns 0 on success. */ + +extern int xatexit PARAMS ((void (*fn) (void))); + +/* Exit, calling all the functions registered with xatexit. */ + +#ifndef __GNUC__ +extern void xexit PARAMS ((int status)); +#else +void xexit PARAMS ((int status)) __attribute__ ((noreturn)); +#endif + +/* Set the program name used by xmalloc. */ + +extern void xmalloc_set_program_name PARAMS ((const char *)); + +/* Allocate memory without fail. If malloc fails, this will print a + message to stderr (using the name set by xmalloc_set_program_name, + if any) and then call xexit. */ + +#ifdef ANSI_PROTOTYPES +/* Get a definition for size_t. */ +#include +#endif +extern PTR xmalloc PARAMS ((size_t)); + +/* Reallocate memory without fail. This works like xmalloc. + + FIXME: We do not declare the parameter types for the same reason as + xmalloc. */ + +extern PTR xrealloc PARAMS ((PTR, size_t)); + +/* Allocate memory without fail and set it to zero. This works like + xmalloc. */ + +extern PTR xcalloc PARAMS ((size_t, size_t)); + +/* Copy a string into a memory buffer without fail. */ + +extern char *xstrdup PARAMS ((const char *)); + +/* hex character manipulation routines */ + +#define _hex_array_size 256 +#define _hex_bad 99 +extern char _hex_value[_hex_array_size]; +extern void hex_init PARAMS ((void)); +#define hex_p(c) (hex_value (c) != _hex_bad) +/* If you change this, note well: Some code relies on side effects in + the argument being performed exactly once. */ +#define hex_value(c) (_hex_value[(unsigned char) (c)]) + +/* Definitions used by the pexecute routine. */ + +#define PEXECUTE_FIRST 1 +#define PEXECUTE_LAST 2 +#define PEXECUTE_ONE (PEXECUTE_FIRST + PEXECUTE_LAST) +#define PEXECUTE_SEARCH 4 +#define PEXECUTE_VERBOSE 8 + +/* Execute a program. */ + +extern int pexecute PARAMS ((const char *, char * const *, const char *, + const char *, char **, char **, int)); + +/* Wait for pexecute to finish. */ + +extern int pwait PARAMS ((int, int *, int)); + +#ifdef __cplusplus +} +#endif + + +#endif /* ! defined (LIBIBERTY_H) */ diff --git a/src/libs/stdc++/osform.cc b/src/libs/stdc++/osform.cc new file mode 100644 index 0000000000..f08f2efaa3 --- /dev/null +++ b/src/libs/stdc++/osform.cc @@ -0,0 +1,66 @@ +/* +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General 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 "libioP.h" +#include +#include + +ostream& ostream::form(const char *format ...) +{ + if (opfx()) { + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _strbuf); + va_list ap; + va_start(ap, format); + _IO_vfprintf(rdbuf(), format, ap); + va_end(ap); + osfx(); + _IO_cleanup_region_end (0); + } + return *this; +} + +ostream& ostream::vform(const char *format, _IO_va_list args) +{ + if (opfx()) { + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _strbuf); + _IO_vfprintf(rdbuf(), format, args); + osfx(); + _IO_cleanup_region_end (0); + } + return *this; +} + +ostream& ostream::operator<<(const void *p) +{ + if (opfx()) { + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _strbuf); + form("%p", p); + osfx(); + _IO_cleanup_region_end (0); + } + return *this; +} diff --git a/src/libs/stdc++/parsestream.cc b/src/libs/stdc++/parsestream.cc new file mode 100644 index 0000000000..e430e602c8 --- /dev/null +++ b/src/libs/stdc++/parsestream.cc @@ -0,0 +1,317 @@ +/* This is part of libio/iostream, providing -*- C++ -*- input/output. +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. + +Written by Per Bothner (bothner@cygnus.com). */ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include "libioP.h" +#include "parsestream.h" +#include + +streambuf* parsebuf::setbuf(char*, int) +{ + return NULL; +} + +int parsebuf::tell_in_line() +{ + return 0; +} + +int parsebuf::pbackfail(int c) +{ + if (c == EOF) + return 0; + if (seekoff(-1, ios::cur) == EOF) + return EOF; + return (unsigned char)c; +} + +char* parsebuf::current_line() { return NULL; } + +streampos parsebuf::seekoff(streamoff offset, _seek_dir dir, int) +{ + // Make offset relative to line start. + switch (dir) { + case ios::beg: + offset -= pos_at_line_start; + break; + case ios::cur: + offset += tell_in_line(); + break; + default: + return EOF; + } + if (offset < -1) + return EOF; + if (offset > _line_length + 1) + return EOF; + return seek_in_line(offset) + pos_at_line_start; +} + +// string_parsebuf invariants: +// The reserve ares (base() .. ebuf()) is always the entire string. +// The get area (eback() .. egptr()) is the extended current line +// (i.e. with the '\n' at either end, if these exist). + +string_parsebuf::string_parsebuf(char *buf, int len, + int delete_at_close /* = 0*/) +: parsebuf() +{ + setb(buf, buf+len, delete_at_close); + register char *ptr = buf; + while (ptr < ebuf() && *ptr != '\n') ptr++; + _line_length = ptr - buf; + setg(buf, buf, ptr); +} + +int string_parsebuf::underflow() +{ + register char* ptr = egptr(); // Point to end of current_line + do { + int i = right() - ptr; + if (i <= 0) + return EOF; + ptr++; i--; // Skip '\n'. + char *line_start = ptr; + while (ptr < right() && *ptr == '\n') ptr++; + setg(line_start-1, line_start, ptr + (ptr < right())); + pos_at_line_start = line_start - left(); + _line_length = ptr - line_start; + __line_number++; + } while (gptr() == ptr); + return *gptr(); +} + +char* string_parsebuf::current_line() +{ + char *ptr = eback(); + if (__line_number > 0) + ptr++; // Skip '\n' at end of previous line. + return ptr; +} + +int string_parsebuf::tell_in_line() +{ + int offset = gptr() - eback(); + if (__line_number > 0) + offset--; + return offset; +} + +int string_parsebuf::seek_in_line(int i) +{ + int delta = i - tell_in_line(); + gbump(delta); // FIXME: Needs error (bounds) checking! + return i; +} + +static const char NewLine[1] = { '\n' }; + +general_parsebuf::general_parsebuf(streambuf *buf, int delete_arg_buf) + : parsebuf() +{ + delete_buf = delete_arg_buf; + sbuf = buf; + int buf_size = 128; + char* buffer = (char*)malloc(buf_size); + setb(buffer, buffer+buf_size, 1); +// setg(buffer, buffer, buffer); +} + +general_parsebuf::~general_parsebuf() +{ + if (delete_buf) + delete sbuf; +} + +int general_parsebuf::underflow() +{ + register char *ptr = base(); + int has_newline = eback() < gptr() && gptr()[-1] == '\n'; + if (has_newline) + *ptr++ = '\n'; + register streambuf *sb = sbuf; + register int ch; + for (;;) { + ch = sb->sbumpc(); + if (ch == EOF) + break; + if (ptr == ebuf()) { + int old_size = ebuf() - base(); + char *new_buffer = new char[old_size * 2]; + memcpy(new_buffer, base(), old_size); + setb(new_buffer, new_buffer + 2 * old_size, 1); + ptr = new_buffer + old_size; + } + *ptr++ = ch; + if (ch == '\n') + break; + } + char *cur_pos = base() + has_newline; + pos_at_line_start += _line_length + 1; + _line_length = ptr - cur_pos; + if (ch != EOF || _line_length > 0) + __line_number++; + setg(base(), cur_pos, ptr); + return ptr == cur_pos ? EOF : cur_pos[0]; +} + +char* general_parsebuf::current_line() +{ + char* ret = base(); + if (__line_number > 1) + ret++; // Move past '\n' from end of previous line. + return ret; +} + +int general_parsebuf::tell_in_line() +{ + int off = gptr() - base(); + if (__line_number > 1) + off--; // Subtract 1 for '\n' from end of previous line. + return off; +} + +int general_parsebuf::seek_in_line(int i) +{ + if (__line_number == 0) + (void)general_parsebuf::underflow(); + if (__line_number > 1) + i++; // Add 1 for '\n' from end of previous line. + if (i < 0) i = 0; + int len = egptr() - eback(); + if (i > len) i = len; + setg(base(), base() + i, egptr()); + return i; +} + +func_parsebuf::func_parsebuf(CharReader func, void *argm) : parsebuf() +{ + read_func = func; + arg = argm; + buf_start = NULL; + buf_end = NULL; + setb((char*)NewLine, (char*)NewLine+1, 0); + setg((char*)NewLine, (char*)NewLine+1, (char*)NewLine+1); + backed_up_to_newline = 0; +} + +int func_parsebuf::tell_in_line() +{ + if (buf_start == NULL) + return 0; + if (egptr() != (char*)NewLine+1) + // Get buffer was line buffer. + return gptr() - buf_start; + if (backed_up_to_newline) + return -1; // Get buffer is '\n' preceding current line. + // Get buffer is '\n' following current line. + return (buf_end - buf_start) + (gptr() - (char*)NewLine); +} + +char* func_parsebuf::current_line() +{ + return buf_start; +} + +int func_parsebuf::seek_in_line(int i) +{ + if (i < 0) { + // Back up to preceding '\n'. + if (i < -1) i = -1; + backed_up_to_newline = 1; + setg((char*)NewLine, (char*)NewLine+(i+1), (char*)NewLine+1); + return i; + } + backed_up_to_newline = 0; + int line_length = buf_end-buf_start; + if (i <= line_length) { + setg(buf_start, buf_start+i, buf_end); + return i; + } + i -= line_length; + if (i > 0) i = 1; + setg((char*)NewLine, (char*)NewLine+i, (char*)NewLine+1); + return line_length + i; +} + +int func_parsebuf::underflow() +{ + retry: + if (gptr() < egptr()) + return *gptr(); + if (gptr() != (char*)NewLine+1) { + // Get buffer was line buffer. Move to following '\n'. + setg((char*)NewLine, (char*)NewLine, (char*)NewLine+1); + return *gptr(); + } + if (backed_up_to_newline) + // Get buffer was '\n' preceding current line. Move to current line. + backed_up_to_newline = 0; + else { + // Get buffer was '\n' following current line. Read new line. + if (buf_start) free(buf_start); + char *str = (*read_func)(arg); + buf_start = str; + if (str == NULL) + return EOF; + // Initially, _line_length == -1, so pos_at_line_start becomes 0. + pos_at_line_start += _line_length + 1; + _line_length = strlen(str); + buf_end = str + _line_length; + __line_number++; + } + setg(buf_start, buf_start, buf_end); + goto retry; +} + +#if 0 +size_t parsebuf::line_length() +{ + if (current_line_length == (size_t)(-1)) // Initial value; + (void)sgetc(); + return current_line_length; +} +#endif + +int parsebuf::seek_in_line(int i) +{ +#if 1 + abort(); + return i; // Suppress warnings. +#else + if (i > 0) { + size_t len = line_length(); + if ((unsigned)i > len) i = len; + } + else if (i < -1) i = -1; + int new_pos = seekoff(pos_at_line_start + i, ios::beg); + if (new_pos == EOF) + return tell_in_line(); + else return new_pos - pos_at_line_start; +#endif +} diff --git a/src/libs/stdc++/pfstream.cc b/src/libs/stdc++/pfstream.cc new file mode 100644 index 0000000000..3fa93c958f --- /dev/null +++ b/src/libs/stdc++/pfstream.cc @@ -0,0 +1,92 @@ +/* This is part of libio/iostream, providing -*- C++ -*- input/output. +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + +/* Written by Per Bothner (bothner@cygnus.com). */ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include "libioP.h" +#include +#include + +ipfstream::ipfstream(const char *name, int mode, int prot) +{ + const char* p; + + // Look for '| command' (as used by ftp). + for (p = name; *p == ' ' || *p == '\t'; p++) ; + if (*p == '|') { + procbuf *pbuf = new procbuf(); + init(pbuf); + if (!pbuf->open(p+1, mode)) + set(ios::badbit); + return; + } + + // Look for 'command |' + while (*p) p++; // Point to last + while (p[-1] == ' ' || p[-1] == '\t' || p[-1] == '\n') p--; + if (p[-1] == '|') { + // Must remove the final '|'. + p--; +#if !defined (__GNUC__) || defined (__STRICT_ANSI__) + char *command = new char[p-name+1]; +#else + char command[p-name+1]; +#endif + memcpy(command, name, p-name); + command[p-name] = '\0'; + + procbuf *pbuf = new procbuf(); + if (pbuf->open(command, mode)) + set(ios::badbit); +#if !defined (__GNUC__) || defined (__STRICT_ANSI__) + delete command; +#endif + return; + } + + init(new filebuf()); + if (!rdbuf()->open(name, mode, prot)) + set(ios::badbit); +} + +opfstream::opfstream(const char *name, int mode, int prot) +{ + const char *p; + // Look for '| command'. + for (p = name; *p == ' ' || *p == '\t'; p++) ; + if (*p == '|') { + procbuf *pbuf = new procbuf(); + init(pbuf); + if (!pbuf->open(p+1, mode)) + set(ios::badbit); + } + else { + init(new filebuf()); + if (!rdbuf()->open(name, mode, prot)) + set(ios::badbit); + } +} diff --git a/src/libs/stdc++/procbuf.cc b/src/libs/stdc++/procbuf.cc new file mode 100644 index 0000000000..eb6d50e779 --- /dev/null +++ b/src/libs/stdc++/procbuf.cc @@ -0,0 +1,54 @@ +/* This is part of libio/iostream, providing -*- C++ -*- input/output. +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + +/* Written by Per Bothner (bothner@cygnus.com). */ + +#ifdef __GNUG__ +#pragma implementation +#endif + +#include "libioP.h" +#include "procbuf.h" + +procbuf::procbuf(const char *command, int mode) : filebuf() +{ + _IO_proc_open(this, command, (mode & ios::in) ? "r" : "w"); +} + +procbuf *procbuf::open(const char *command, int mode) +{ + return (procbuf*)_IO_proc_open(this, command, (mode & ios::in) ? "r" : "w"); +} + +/* #define USE_SIGMASK */ + +int procbuf::sys_close() +{ + return _IO_proc_close(this); +} + +procbuf::~procbuf() +{ + close(); +} diff --git a/src/libs/stdc++/sbform.cc b/src/libs/stdc++/sbform.cc new file mode 100644 index 0000000000..c17bd08db1 --- /dev/null +++ b/src/libs/stdc++/sbform.cc @@ -0,0 +1,40 @@ +/* +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General 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 "libioP.h" +#include "streambuf.h" +#include + +int streambuf::vform(char const *fmt0, _IO_va_list ap) +{ + return _IO_vfprintf(this, fmt0, ap); +} +int streambuf::form(char const *format ...) +{ + va_list ap; + va_start(ap, format); + int count = _IO_vfprintf(this, format, ap); + va_end(ap); + return count; +} diff --git a/src/libs/stdc++/sbgetline.cc b/src/libs/stdc++/sbgetline.cc new file mode 100644 index 0000000000..0475114c62 --- /dev/null +++ b/src/libs/stdc++/sbgetline.cc @@ -0,0 +1,31 @@ +/* +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General 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 "libioP.h" +#include "streambuf.h" + +long streambuf::sgetline(char* buf, _IO_size_t n, char delim, int extract_delim) +{ + return _IO_getline_info(this, buf, n, delim, extract_delim, (int *) 0); +} diff --git a/src/libs/stdc++/sbscan.cc b/src/libs/stdc++/sbscan.cc new file mode 100644 index 0000000000..c0ec35c53d --- /dev/null +++ b/src/libs/stdc++/sbscan.cc @@ -0,0 +1,45 @@ + +/* +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General 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 "libioP.h" +#include "streambuf.h" +#include + +int streambuf::vscan(char const *fmt0, _IO_va_list ap, ios* stream /* = NULL*/) +{ + int errcode = 0; + int count = _IO_vfscanf(this, fmt0, ap, &errcode); + if (stream) + stream->setstate((ios::iostate)errcode); + return count; +} +int streambuf::scan(char const *format ...) +{ + va_list ap; + va_start(ap, format); + int count = _IO_vfscanf(this, format, ap, NULL); + va_end(ap); + return count; +} diff --git a/src/libs/stdc++/sigsetmask.c b/src/libs/stdc++/sigsetmask.c new file mode 100644 index 0000000000..2a09e6a6c5 --- /dev/null +++ b/src/libs/stdc++/sigsetmask.c @@ -0,0 +1,30 @@ +/* Version of sigsetmask.c + Written by Steve Chamberlain (sac@cygnus.com). + Contributed by Cygnus Support. + This file is in the public doamin. */ + +/* Set the current signal mask to the set provided, and return the + previous value */ + +#define _POSIX_SOURCE +#include +/* Including seems to be needed by ISC. */ +#include +#include + +#ifdef SIG_SETMASK +int +DEFUN(sigsetmask,(set), + int set) +{ + sigset_t new; + sigset_t old; + + sigemptyset (&new); + if (set != 0) { + abort(); /* FIXME, we don't know how to translate old mask to new */ + } + sigprocmask(SIG_SETMASK, &new, &old); + return 1; /* FIXME, we always return 1 as old value. */ +} +#endif diff --git a/src/libs/stdc++/sinst.cc b/src/libs/stdc++/sinst.cc new file mode 100644 index 0000000000..0b3617ece6 --- /dev/null +++ b/src/libs/stdc++/sinst.cc @@ -0,0 +1,135 @@ +// Instantiation file for the -*- C++ -*- string classes. +// Copyright (C) 1994 Free Software Foundation + +// This file is part of the GNU ANSI C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// As a special exception, if you link this library with files +// compiled with a GNU compiler to produce an executable, this does not cause +// the resulting executable to be covered by the GNU General Public License. +// This exception does not however invalidate any other reasons why +// the executable file might be covered by the GNU General Public License. + +// Written by Jason Merrill based upon the specification by Takanori Adachi +// in ANSI X3J16/94-0013R2. + +#ifdef __GNUG__ +#ifdef TRAITS +#ifdef C +#pragma implementation "std/straits.h" +#endif +#endif +#endif + +#include + +#ifdef C +typedef char c; +#endif +#ifdef W +typedef wchar_t c; +#endif + +#if defined(TRAITS) && !defined(C) +template class string_char_traits ; +#else +/* string_char_traits is already explicitly specialized in + std/straits.h. */ +#endif + +typedef basic_string s; + +#ifdef MAIN +template class basic_string ; +#endif + +#ifdef ADDSS +template s operator+ (const s&, const s&); +#endif +#ifdef ADDPS +template s operator+ (const c*, const s&); +#endif +#ifdef ADDCS +template s operator+ (c, const s&); +#endif +#ifdef ADDSP +template s operator+ (const s&, const c*); +#endif +#ifdef ADDSC +template s operator+ (const s&, c); +#endif +#ifdef EQSS +template bool operator== (const s&, const s&); +#endif +#ifdef EQPS +template bool operator== (const c*, const s&); +#endif +#ifdef EQSP +template bool operator== (const s&, const c*); +#endif +#ifdef NESS +template bool operator!= (const s&, const s&); +#endif +#ifdef NEPS +template bool operator!= (const c*, const s&); +#endif +#ifdef NESP +template bool operator!= (const s&, const c*); +#endif +#ifdef LTSS +template bool operator< (const s&, const s&); +#endif +#ifdef LTPS +template bool operator< (const c*, const s&); +#endif +#ifdef LTSP +template bool operator< (const s&, const c*); +#endif +#ifdef GTSS +template bool operator> (const s&, const s&); +#endif +#ifdef GTPS +template bool operator> (const c*, const s&); +#endif +#ifdef GTSP +template bool operator> (const s&, const c*); +#endif +#ifdef LESS +template bool operator<= (const s&, const s&); +#endif +#ifdef LEPS +template bool operator<= (const c*, const s&); +#endif +#ifdef LESP +template bool operator<= (const s&, const c*); +#endif +#ifdef GESS +template bool operator>= (const s&, const s&); +#endif +#ifdef GEPS +template bool operator>= (const c*, const s&); +#endif +#ifdef GESP +template bool operator>= (const s&, const c*); +#endif +#ifdef EXTRACT +template istream& operator>> (istream&, s&); +#endif // EXTRACT +#ifdef INSERT +template ostream& operator<< (ostream&, const s&); +#endif // INSERT +#ifdef GETLINE +template istream& getline (istream&, s&, c); +#endif diff --git a/src/libs/stdc++/stdexcepti.cc b/src/libs/stdc++/stdexcepti.cc new file mode 100644 index 0000000000..9c02c71f49 --- /dev/null +++ b/src/libs/stdc++/stdexcepti.cc @@ -0,0 +1,21 @@ +// Implementation file for Exception Support for -*- C++ -*- +// This file is part of the GNU ANSI C++ Library. + +#ifdef __GNUG__ +#pragma implementation "stdexcept" +#endif + +#include + +// Entry points for string. + +void +__out_of_range (const char *s) +{ + throw std::out_of_range (s); +} + +void __length_error (const char *s) +{ + throw std::length_error (s); +} diff --git a/src/libs/stdc++/stdiostream.cc b/src/libs/stdc++/stdiostream.cc new file mode 100644 index 0000000000..ee0907b209 --- /dev/null +++ b/src/libs/stdc++/stdiostream.cc @@ -0,0 +1,159 @@ +/* This is part of libio/iostream, providing -*- C++ -*- input/output. +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + +/* Written by Per Bothner (bothner@cygnus.com). */ + +#ifdef __GNUG__ +#pragma implementation +#endif + +#include "libioP.h" +#include + +// A stdiobuf is "tied" to a FILE object (as used by the stdio package). +// Thus a stdiobuf is always synchronized with the corresponding FILE, +// though at the cost of some overhead. (If you use the implementation +// of stdio supplied with this library, you don't need stdiobufs.) +// This implementation inherits from filebuf, but implement the virtual +// functions sys_read/..., using the stdio functions fread/... instead +// of the low-level read/... system calls. This has the advantage that +// we get all of the nice filebuf semantics automatically, though +// with some overhead. + + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif +#ifndef SEEK_CUR +#define SEEK_CUR 1 +#endif +#ifndef SEEK_END +#define SEEK_END 2 +#endif + +stdiobuf::stdiobuf(FILE *f) : filebuf(fileno(f)) +{ + _file = f; + // Turn off buffer in stdiobuf. Instead, rely on buffering in (FILE). + // Thus the stdiobuf will be synchronized with the FILE. + setbuf(NULL, 0); +} + +stdiobuf::~stdiobuf() +{ + /* Only needed if we're buffered. Not buffered is the default. */ + _IO_do_flush((_IO_FILE*)this); +} + +streamsize stdiobuf::sys_read(char* buf, streamsize size) +{ + // A minor optimization, but it makes a noticable difference. + // A bigger optimization would be to write stdiobuf::underflow, + // but that has some modularity disadvantages. Re-evaluate that + // after we have gotten rid of the double indirection. FIXME + if (size == 1) + { + register int ch = getc(_file); + if (ch == EOF) + return 0; + *buf = (char)ch; + return 1; + } + else + return fread(buf, 1, size, _file); +} + +streamsize stdiobuf::sys_write(const char *buf, streamsize n) +{ + _IO_ssize_t count = fwrite(buf, 1, n, _file); + if (_offset >= 0) + _offset += n; + return count; +} + +streampos stdiobuf::sys_seek(streamoff offset, _seek_dir dir) +{ + // Normally, equivalent to: fdir=dir + int fdir = + (dir == ios::beg) ? SEEK_SET : + (dir == ios::cur) ? SEEK_CUR : + (dir == ios::end) ? SEEK_END : + dir; + return fseek(_file, offset, fdir); +} + +int stdiobuf::sys_close() +{ + int status = fclose(_file); + _file = NULL; + return status; +} + +int stdiobuf::sync() +{ + if (_IO_do_flush((_IO_FILE*)this)) + return EOF; + if (!(xflags() & _IO_NO_WRITES)) + if (fflush(_file)) + return EOF; + return 0; +} + +int stdiobuf::overflow(int c /* = EOF*/) +{ + if (filebuf::overflow(c) == EOF) + return EOF; + if (c != EOF) + return c; + return fflush(_file); +} + +streamsize stdiobuf::xsputn(const char* s, streamsize n) +{ + if (buffered ()) + { + // The filebuf implementation of sputn loses. + return streambuf::xsputn(s, n); + } + else + return fwrite (s, 1, n, _file); +} + +void stdiobuf::buffered (int b) +{ + if (b) + { + if (_flags & _IO_UNBUFFERED) + { /* Was unbuffered, make it buffered. */ + _flags &= ~_IO_UNBUFFERED; + } + } + else + { + if (!(_flags & _IO_UNBUFFERED)) + { /* Was buffered, make it unbuffered. */ + setbuf(NULL, 0); + } + } +} diff --git a/src/libs/stdc++/stdstrbufs.cc b/src/libs/stdc++/stdstrbufs.cc new file mode 100644 index 0000000000..6bbbb59faa --- /dev/null +++ b/src/libs/stdc++/stdstrbufs.cc @@ -0,0 +1,127 @@ +/* +Copyright (C) 1994 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + + +/* This file provides definitions of _IO_stdin, _IO_stdout, and _IO_stderr + for C++ code. Compare stdfiles.c. + (The difference is that here the vtable field is set to + point to builtinbuf's vtable, so the objects are effectively + of class builtinbuf.) */ + +#include "libioP.h" +#include + +#if !defined(filebuf_vtable) && defined(__cplusplus) +#ifdef __GNUC__ +extern char filebuf_vtable[] + asm (_G_VTABLE_LABEL_PREFIX +#if _G_VTABLE_LABEL_HAS_LENGTH + "7" +#endif + "filebuf"); +#else /* !__GNUC__ */ +#if _G_VTABLE_LABEL_HAS_LENGTH +#define filebuf_vtable _G_VTABLE_LABEL_PREFIX_ID##7filebuf +#else +#define filebuf_vtable _G_VTABLE_LABEL_PREFIX_ID##filebuf +#endif +extern char filebuf_vtable[]; +#endif /* !__GNUC__ */ +#endif /* !defined(filebuf_vtable) && defined(__cplusplus) */ + +#ifndef STD_VTABLE +#define STD_VTABLE (const struct _IO_jump_t *)filebuf_vtable +#endif + +#ifdef _STDIO_USES_IOSTREAM +#ifdef _IO_MTSAFE_IO +#define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \ + static _IO_lock_t _IO_stdfile_##FD##_lock = _IO_lock_initializer; \ + struct _IO_FILE_plus NAME \ + = {FILEBUF_LITERAL(CHAIN, FLAGS, FD, NULL), STD_VTABLE} +#else +#define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \ + struct _IO_FILE_plus NAME = {FILEBUF_LITERAL(CHAIN, FLAGS, FD, NULL), STD_VTABLE} +#endif + +DEF_STDFILE(_IO_stdin_, 0, 0, _IO_NO_WRITES); +DEF_STDFILE(_IO_stdout_, 1, &_IO_stdin_.file, _IO_NO_READS); +DEF_STDFILE(_IO_stderr_, 2, &_IO_stdout_.file, + _IO_NO_READS+_IO_UNBUFFERED); + +_IO_FILE_plus *_IO_list_all = &_IO_stderr_; +#else /* !_STDIO_USES_IOSTREAM */ +#include "stdiostream.h" + +struct _IO_fake_stdiobuf { + struct { + _IO_FILE file; + const void *vtable; + } s; + FILE *stdio_file; +}; + +/* Define stdiobuf_vtable as a name for the virtual function table + of the stdiobuf class. */ +#ifndef stdiobuf_vtable +#ifdef __GNUC__ +extern struct _IO_jump_t stdiobuf_vtable + asm (_G_VTABLE_LABEL_PREFIX +#if _G_VTABLE_LABEL_HAS_LENGTH + "8" +#endif + "stdiobuf"); +#else /* !__GNUC__ */ +#if _G_VTABLE_LABEL_HAS_LENGTH +#define stdiobuf_vtable _G_VTABLE_LABEL_PREFIX_ID##8stdiobuf +#else +#define stdiobuf_vtable _G_VTABLE_LABEL_PREFIX_ID##stdiobuf +#endif +extern struct _IO_jump_t stdiobuf_vtable; +#endif /* !__GNUC__ */ +#endif /* !stdiobuf_vtable */ + +#ifdef _IO_MTSAFE_IO +#define DEF_STDIOFILE(NAME, FD, FILE, FLAGS, CHAIN) \ + static _IO_lock_t _IO_stdfile_##FD##_lock = _IO_lock_initializer; \ + struct _IO_fake_stdiobuf NAME = \ + {{{ _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+_IO_UNBUFFERED+FLAGS, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CHAIN, FD, \ + 0, 0, 0, 0, { 0 }, &_IO_stdfile_##FD##_lock},\ + &stdiobuf_vtable}, FILE} +#else +#define DEF_STDIOFILE(NAME, FD, FILE, FLAGS, CHAIN) \ + struct _IO_fake_stdiobuf NAME = \ + {{{ _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+_IO_UNBUFFERED+FLAGS, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CHAIN, FD}, \ + &stdiobuf_vtable}, FILE} +#endif + +DEF_STDIOFILE(_IO_stdin_buf, 0, stdin, _IO_NO_WRITES, &_IO_stderr_.file); +DEF_STDIOFILE(_IO_stdout_buf, 1, stdout, _IO_NO_READS, &_IO_stdin_buf.s.file); +DEF_STDIOFILE(_IO_stderr_buf, 2, stderr, _IO_NO_READS, &_IO_stdout_buf.s.file); + +_IO_FILE_plus *_IO_list_all + = reinterpret_cast<_IO_FILE_plus*>(&_IO_stderr_buf.s); +#endif /* !_STDIO_USES_IOSTREAM */ diff --git a/src/libs/stdc++/stdstreams.cc b/src/libs/stdc++/stdstreams.cc new file mode 100644 index 0000000000..36e40ff14c --- /dev/null +++ b/src/libs/stdc++/stdstreams.cc @@ -0,0 +1,152 @@ +/* This is part of libio/iostream, providing -*- C++ -*- input/output. +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + +/* Written by Per Bothner (bothner@cygnus.com). */ + +#include "libioP.h" +#include "streambuf.h" +#include + +// The ANSI draft requires that operations on cin/cout/cerr can be +// mixed with operations on stdin/stdout/stderr on a character by +// character basis. This normally requires that the streambuf's +// used by cin/cout/cerr be stdiostreams. However, if the stdio +// implementation is the one that is built using this library, +// then we don't need to, since in that case stdin/stdout/stderr +// are identical to _IO_stdin/_IO_stdout/_IO_stderr. + +#include + +#ifdef _STDIO_USES_IOSTREAM +#define CIN_SBUF _IO_stdin_ +#define COUT_SBUF _IO_stdout_ +#define CERR_SBUF _IO_stderr_ +#else +#define CIN_SBUF _IO_stdin_buf +#define COUT_SBUF _IO_stdout_buf +#define CERR_SBUF _IO_stderr_buf +static int use_stdiobuf = 1; +#endif + +#define cin CIN +#define cout COUT +#define cerr CERR +#define clog CLOG +#include "iostream.h" +#undef cin +#undef cout +#undef cerr +#undef clog + +#ifdef __GNUG__ +#define PAD 0 /* g++ allows 0-length arrays. */ +#else +#define PAD 1 +#endif +struct _fake_istream { + struct myfields { +#ifdef __GNUC__ + _ios_fields *vb; /* pointer to virtual base class ios */ + _IO_ssize_t _gcount; +#else + /* This is supposedly correct for cfront. */ + _IO_ssize_t _gcount; + void *vptr; + _ios_fields *vb; /* pointer to virtual base class ios */ +#endif + } mine; + _ios_fields base; + char filler[sizeof(struct istream)-sizeof(struct _ios_fields)+PAD]; +}; +struct _fake_ostream { + struct myfields { +#ifndef __GNUC__ + void *vptr; +#endif + _ios_fields *vb; /* pointer to virtual base class ios */ + } mine; + _ios_fields base; + char filler[sizeof(struct ostream)-sizeof(struct _ios_fields)+PAD]; +}; + + +#ifdef _IO_NEW_STREAMS +#define STD_STR(SBUF, TIE, EXTRA_FLAGS) \ + (streambuf*)&SBUF, TIE, 0, ios::skipws|ios::dec|EXTRA_FLAGS, ' ',0,0,6 +#else +#define STD_STR(SBUF, TIE, EXTRA_FLAGS) \ + (streambuf*)&SBUF, TIE, 0, ios::dont_close|ios::dec|ios::skipws|EXTRA_FLAGS, ' ',0,0,6 +#endif + +#ifdef __GNUC__ +#define OSTREAM_DEF(NAME, SBUF, TIE, EXTRA_FLAGS, ASM) \ + _fake_ostream NAME ASM = { {&NAME.base}, {STD_STR(SBUF, TIE, EXTRA_FLAGS) }}; +#define ISTREAM_DEF(NAME, SBUF, TIE, EXTRA_FLAGS) \ + _fake_istream NAME = { {&NAME.base}, {STD_STR(SBUF, TIE, EXTRA_FLAGS) }}; +#else +#define OSTREAM_DEF(NAME, SBUF, TIE, EXTRA_FLAGS) \ + _fake_ostream NAME = { {0, &NAME.base}, {STD_STR(SBUF, TIE, EXTRA_FLAGS) }}; +#define ISTREAM_DEF(NAME, SBUF, TIE, EXTRA_FLAGS) \ + _fake_istream NAME = {{0, 0, &NAME.base}, {STD_STR(SBUF, TIE, EXTRA_FLAGS)}}; +#endif + +OSTREAM_DEF(cout, COUT_SBUF, NULL, 0, ) +OSTREAM_DEF(cerr, CERR_SBUF,(ostream*)&cout, ios::unitbuf, ) +ISTREAM_DEF(cin, CIN_SBUF, (ostream*)&cout, 0) + +/* Only for (partial) compatibility with AT&T's library. */ +#if _G_CLOG_CONFLICT +OSTREAM_DEF(clog, CERR_SBUF, (ostream*)&cout, 0, __asm__ ("__IO_clog")) +#else +OSTREAM_DEF(clog, CERR_SBUF, (ostream*)&cout, 0, ) +#endif + +// Switches between using _IO_std{in,out,err} and __std{in,out,err}_buf +// for standard streams. This does not normally need to be called +// explicitly, but is provided for AT&T compatibility. + +int ios::sync_with_stdio(int new_state) +{ +#ifdef _STDIO_USES_IOSTREAM + // It is always synced. + return 0; +#else + if (new_state == use_stdiobuf) // The usual case now. + return use_stdiobuf; + if (new_state) { + cin.base._strbuf = (streambuf*)&_IO_stdin_buf; + cout.base._strbuf = (streambuf*)&_IO_stdout_buf; + cerr.base._strbuf = (streambuf*)&_IO_stderr_buf; + clog.base._strbuf = (streambuf*)&_IO_stderr_buf; + } else { + cin.base._strbuf = (streambuf*)_IO_stdin; + cout.base._strbuf = (streambuf*)_IO_stdout; + cerr.base._strbuf = (streambuf*)_IO_stderr; + clog.base._strbuf = (streambuf*)_IO_stderr; + } + int old_state = use_stdiobuf; + use_stdiobuf = new_state; + return old_state; +#endif +} diff --git a/src/libs/stdc++/stlinst.cc b/src/libs/stdc++/stlinst.cc new file mode 100644 index 0000000000..2a221fbaee --- /dev/null +++ b/src/libs/stdc++/stlinst.cc @@ -0,0 +1,10 @@ +// Instantiation file for the -*- C++ -*- Standard Library allocator templates +// This file is part of the GNU ANSI C++ Library. + +#include + +#ifndef __USE_MALLOC +template class __default_alloc_template<__NODE_ALLOCATOR_THREADS, 0>; +#endif + +template class __malloc_alloc_template<0>; diff --git a/src/libs/stdc++/stream.cc b/src/libs/stdc++/stream.cc new file mode 100644 index 0000000000..5b947bbb56 --- /dev/null +++ b/src/libs/stdc++/stream.cc @@ -0,0 +1,170 @@ +/* +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General 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 +#include +#include "libioP.h" +#include "stream.h" +#include "strstream.h" + +static char Buffer[_IO_BUFSIZ]; +#define EndBuffer (Buffer+_IO_BUFSIZ) +static char* next_chunk = Buffer; // Start of available part of Buffer. + +char* form(const char* format, ...) +{ + int space_left = EndBuffer - next_chunk; + // If less that 25% of the space is available start over. + if (space_left < (_IO_BUFSIZ>>2)) + next_chunk = Buffer; + char* buf = next_chunk; + + strstreambuf stream(buf, EndBuffer-buf-1, buf); + va_list ap; + va_start(ap, format); + stream.vform(format, ap); + va_end(ap); + stream.sputc(0); + next_chunk = buf + stream.pcount(); + return buf; +} + +#define u_long unsigned long + +static char* itoa(unsigned long i, int size, int neg, int base) +{ + // Conservative estimate: If base==2, might need 8 characters + // for each input byte, but normally 3 is plenty. + int needed = size ? size + : (base >= 8 ? 3 : 8) * sizeof(unsigned long) + 2; + int space_left = EndBuffer - next_chunk; + if (space_left <= needed) + next_chunk = Buffer; // start over. + + char* buf = next_chunk; + + register char* ptr = buf+needed+1; + next_chunk = ptr; + + if (needed < (2+neg) || ptr > EndBuffer) + return NULL; + *--ptr = 0; + + if (i == 0) + *--ptr = '0'; + while (i != 0 && ptr > buf) { + int ch = i % base; + i = i / base; + if (ch >= 10) + ch += 'a' - 10; + else + ch += '0'; + *--ptr = ch; + } + if (neg) + *--ptr = '-'; + if (size == 0) + return ptr; + while (ptr > buf) + *--ptr = ' '; + return buf; +} + +char* dec(long i, int len /* = 0 */) +{ + if (i >= 0) return itoa((unsigned long)i, len, 0, 10); + else return itoa((unsigned long)(-i), len, 1, 10); +} +char* dec(int i, int len /* = 0 */) +{ + if (i >= 0) return itoa((unsigned long)i, len, 0, 10); + else return itoa((unsigned long)(-i), len, 1, 10); +} +char* dec(unsigned long i, int len /* = 0 */) +{ + return itoa(i, len, 0, 10); +} +char* dec(unsigned int i, int len /* = 0 */) +{ + return itoa(i, len, 0, 10); +} + +char* hex(long i, int len /* = 0 */) +{ + return itoa((unsigned long)i, len, 0, 16); +} +char* hex(int i, int len /* = 0 */) +{ + return itoa((unsigned long)i, len, 0, 16); +} +char* hex(unsigned long i, int len /* = 0 */) +{ + return itoa(i, len, 0, 16); +} +char* hex(unsigned int i, int len /* = 0 */) +{ + return itoa(i, len, 0, 16); +} + +char* oct(long i, int len /* = 0 */) +{ + return itoa((unsigned long)i, len, 0, 8); +} +char* oct(int i, int len /* = 0 */) +{ + return itoa((unsigned long)i, len, 0, 8); +} +char* oct(unsigned long i, int len /* = 0 */) +{ + return itoa(i, len, 0, 8); +} +char* oct(unsigned int i, int len /* = 0 */) +{ + return itoa(i, len, 0, 8); +} + +static char *str(const char* s, int len, int width) +{ + if (width < len) + width = len; + int space_left = EndBuffer - next_chunk; + if (space_left <= width + 1) + next_chunk = Buffer; // start over. + char* buf = next_chunk; + memset (buf, ' ', width - len); + memcpy (buf + width - len, s, len); + buf[width] = 0; + return buf; +} + +char* str(const char* s, int width) +{ + return str (s, strlen (s), width); +} + +char* chr(char ch, int width) +{ + char c = ch; + return str (&c, 1, width); +} diff --git a/src/libs/stdc++/streambuf.cc b/src/libs/stdc++/streambuf.cc new file mode 100644 index 0000000000..677f6965fc --- /dev/null +++ b/src/libs/stdc++/streambuf.cc @@ -0,0 +1,364 @@ +/* This is part of libio/iostream, providing -*- C++ -*- input/output. +Copyright (C) 1991, 1992, 1993, 1995 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + +/* Written by Per Bothner (bothner@cygnus.com). */ + +#define _STREAM_COMPAT +#ifdef __GNUG__ +#pragma implementation +#endif +#include "iostreamP.h" +#include +#include +#include +#ifndef errno +extern int errno; +#endif + +void streambuf::_un_link() { _IO_un_link(reinterpret_cast<_IO_FILE_plus*>(this)); } + +void streambuf::_link_in() { _IO_link_in(reinterpret_cast<_IO_FILE_plus*>(this)); } + +int streambuf::switch_to_get_mode() +{ return _IO_switch_to_get_mode(this); } + +void streambuf::free_backup_area() +{ _IO_free_backup_area(this); } + +#if 0 +int streambuf::switch_to_put_mode() +{ return _IO_:switch_to_put_mode(this); } +#endif + +int __overflow(streambuf* sb, int c) +{ + return sb->overflow(c); +} + +int streambuf::underflow() +{ return EOF; } + +int streambuf::uflow() +{ return _IO_default_uflow (this); } + +int streambuf::overflow(int /* = EOF */) +{ return EOF; } + +streamsize streambuf::xsputn(register const char* s, streamsize n) +{ return _IO_default_xsputn(this, s, n); } + +streamsize streambuf::xsgetn(char* s, streamsize n) +{ return _IO_default_xsgetn(this, s, n); } + +int streambuf::ignore(int n) +{ + register int more = n; + for (;;) { + int count = _IO_read_end - _IO_read_ptr; // Data available. + if (count > 0) { + if (count > more) + count = more; + _IO_read_ptr += count; + more -= count; + } + if (more == 0 || __underflow(this) == EOF) + break; + } + return n - more; +} + +int streambuf::sync() +{ + return 0; +} + +int streambuf::pbackfail(int c) +{ + return _IO_default_pbackfail(this, c); +} + +streambuf* streambuf::setbuf(char* p, int len) +{ + if (sync() == EOF) + return NULL; + if (p == NULL || len == 0) { + unbuffered(1); + setb(_shortbuf, _shortbuf+1, 0); + } + else { + unbuffered(0); + setb(p, p+len, 0); + } + setp(0, 0); + setg(0, 0, 0); + return this; +} + +streampos streambuf::seekpos(streampos pos, int mode) +{ + return seekoff(pos, ios::beg, mode); +} + +streampos streambuf::sseekpos(streampos pos, int mode) +{ + return _IO_seekpos (this, pos, mode); +} + +void streambuf::setb(char* b, char* eb, int a) +{ _IO_setb(this, b, eb, a); } + +int streambuf::doallocate() { return _IO_default_doallocate(this); } + +void streambuf::doallocbuf() { _IO_doallocbuf(this); } + +#if !_IO_UNIFIED_JUMPTABLES +/* The following are jump table entries that just call the virtual method */ + +static int _IO_sb_overflow(_IO_FILE *fp, int c) +{ return ((streambuf*)fp)->overflow(c); } +static int _IO_sb_underflow(_IO_FILE *fp) +{ return ((streambuf*)fp)->underflow(); } +static _IO_size_t _IO_sb_xsputn(_IO_FILE *fp, const void *s, _IO_size_t n) +{ return ((streambuf*)fp)->xsputn((const char*)s, n); } +static _IO_size_t _IO_sb_xsgetn(_IO_FILE *fp, void *s, _IO_size_t n) +{ return ((streambuf*)fp)->xsgetn((char*)s, n); } +static int _IO_sb_close(_IO_FILE *fp) +{ return ((streambuf*)fp)->sys_close(); } +static int _IO_sb_stat(_IO_FILE *fp, void *b) +{ return ((streambuf*)fp)->sys_stat(b); } +static int _IO_sb_doallocate(_IO_FILE *fp) +{ return ((streambuf*)fp)->doallocate(); } + +static _IO_pos_t _IO_sb_seekoff(_IO_FILE *fp, _IO_off_t pos, int dir, int mode) +{ + return ((streambuf*)fp)->seekoff(pos, (ios::seek_dir)dir, mode); +} + +static _IO_pos_t _IO_sb_seekpos(_IO_FILE *fp, _IO_pos_t pos, int mode) +{ + return ((streambuf*)fp)->seekpos(pos, mode); +} + +static int _IO_sb_pbackfail(_IO_FILE *fp, int ch) +{ return ((streambuf*)fp)->pbackfail(ch); } +static void _IO_sb_finish(_IO_FILE *fp, int) +{ ((streambuf*)fp)->~streambuf(); } +static _IO_ssize_t _IO_sb_read(_IO_FILE *fp, void *buf, _IO_ssize_t n) +{ return ((streambuf*)fp)->sys_read((char*)buf, n); } +static _IO_ssize_t _IO_sb_write(_IO_FILE *fp, const void *buf, _IO_ssize_t n) +{ return ((streambuf*)fp)->sys_write((const char*)buf, n); } +static int _IO_sb_sync(_IO_FILE *fp) +{ return ((streambuf*)fp)->sync(); } +static _IO_pos_t _IO_sb_seek(_IO_FILE *fp, _IO_off_t off, int dir) +{ return ((streambuf*)fp)->sys_seek(off, (_seek_dir)dir); } +static _IO_FILE* _IO_sb_setbuf(_IO_FILE *fp, char *buf, _IO_ssize_t n) +{ return ((streambuf*)fp)->setbuf(buf, n); } + +/* This callbacks in this jumptable just call the corresponding + virtual function, so that C functions can access (potentially user-defined) + streambuf-derived objects. + Contrast the builtinbuf class, which does the converse: Allow + C++ virtual calls to be used on _IO_FILE objects that are builtin + (or defined by C code). */ + + +struct _IO_jump_t _IO_streambuf_jumps = { + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_sb_finish), + JUMP_INIT(overflow, _IO_sb_overflow), + JUMP_INIT(underflow, _IO_sb_underflow), + JUMP_INIT(uflow, _IO_default_uflow), + JUMP_INIT(pbackfail, _IO_sb_pbackfail), + JUMP_INIT(xsputn, _IO_sb_xsputn), + JUMP_INIT(xsgetn, _IO_sb_xsgetn), + JUMP_INIT(seekoff, _IO_sb_seekoff), + JUMP_INIT(seekpos, _IO_sb_seekpos), + JUMP_INIT(setbuf, _IO_sb_setbuf), + JUMP_INIT(sync, _IO_sb_sync), + JUMP_INIT(doallocate, _IO_sb_doallocate), + JUMP_INIT(read, _IO_sb_read), + JUMP_INIT(write, _IO_sb_write), + JUMP_INIT(seek, _IO_sb_seek), + JUMP_INIT(close, _IO_sb_close), + JUMP_INIT(stat, _IO_sb_stat) +}; +#endif + +streambuf::streambuf(int flags) +{ +#ifdef _IO_MTSAFE_IO + _lock = new _IO_lock_t; +#endif + _IO_init(this, flags); +#if !_IO_UNIFIED_JUMPTABLES + _jumps = &_IO_streambuf_jumps; +#endif +} + +streambuf::~streambuf() +{ + _IO_default_finish(this,0); +#ifdef _IO_MTSAFE_IO + if (this != _IO_stdin && this != _IO_stdout && this != _IO_stderr) + delete _lock; +#endif +} + +streampos +streambuf::seekoff(streamoff, _seek_dir, int /*=ios::in|ios::out*/) +{ + return EOF; +} + +streampos +streambuf::sseekoff(streamoff o , _seek_dir d, int m /*=ios::in|ios::out*/) +{ + return _IO_seekoff (this, o, d, m); +} + +int streambuf::sputbackc(char c) +{ + return _IO_sputbackc(this, c); +} + +int streambuf::sungetc() +{ + return _IO_sungetc(this); +} + +#if 0 /* Work in progress */ +void streambuf::collumn(int c) +{ + if (c == -1) + _collumn = -1; + else + _collumn = c - (_IO_write_ptr - _IO_write_base); +} +#endif + + +int streambuf::get_column() +{ + if (_cur_column) + return _IO_adjust_column(_cur_column - 1, pbase(), pptr() - pbase()); + return -1; +} + +int streambuf::set_column(int i) +{ + _cur_column = i+1; + return 0; +} + +int streambuf::flush_all() { return _IO_flush_all (); } + +void streambuf::flush_all_linebuffered() +{ _IO_flush_all_linebuffered(); } + +int streambuf::sys_stat(void *) +{ +#ifdef EIO + errno = EIO; +#endif + return -1; +} + +streamsize streambuf::sys_read(char* /*buf*/, streamsize /*size*/) +{ + return 0; +} + +streamsize streambuf::sys_write(const char* /*buf*/, streamsize /*size*/) +{ + return 0; +} + +streampos streambuf::sys_seek(streamoff, _seek_dir) +{ + return EOF; +} + +int streambuf::sys_close() { return 0; /* Suceess; do nothing */ } + +#if _G_IO_IO_FILE_VERSION == 0x20001 +int streambuf::showmanyc() +{ + return -1; +} + +void streambuf::imbue(void *) +{ +} +#endif + +streammarker::streammarker(streambuf *sb) +{ + _IO_init_marker(this, sb); +} + +streammarker::~streammarker() +{ + _IO_remove_marker(this); +} + +#define BAD_DELTA EOF + +int streammarker::delta(streammarker& other_mark) +{ + return _IO_marker_difference(this, &other_mark); +} + +int streammarker::delta() +{ + return _IO_marker_delta(this); +} + +int streambuf::seekmark(streammarker& mark, int delta /* = 0 */) +{ + return _IO_seekmark(this, &mark, delta); +} + +void streambuf::unsave_markers() +{ + _IO_unsave_markers(this); +} + +int ios::readable() { return !(rdbuf()->_flags & _IO_NO_READS); } +int ios::writable() { return !(rdbuf()->_flags & _IO_NO_WRITES); } +int ios::is_open() { return rdbuf() + && (rdbuf()->_flags & _IO_NO_READS+_IO_NO_WRITES) + != _IO_NO_READS+_IO_NO_WRITES; } + +#if defined(linux) +#define IO_CLEANUP +#endif + +#ifdef IO_CLEANUP + IO_CLEANUP +#else +struct __io_defs { + ~__io_defs() { _IO_cleanup (); } +}; +__io_defs io_defs__; +#endif diff --git a/src/libs/stdc++/strerror.c b/src/libs/stdc++/strerror.c new file mode 100644 index 0000000000..644cc75462 --- /dev/null +++ b/src/libs/stdc++/strerror.c @@ -0,0 +1,831 @@ +/* Extended support for using errno values. + Written by Fred Fish. fnf@cygnus.com + This file is in the public domain. --Per Bothner. */ + +#include "ansidecl.h" +#include "libiberty.h" + +#include "config.h" + +#ifdef HAVE_SYS_ERRLIST +/* Note that errno.h (not sure what OS) or stdio.h (BSD 4.4, at least) + might declare sys_errlist in a way that the compiler might consider + incompatible with our later declaration, perhaps by using const + attributes. So we hide the declaration in errno.h (if any) using a + macro. */ +#define sys_errlist sys_errlist__ +#endif + +#include +#include + +#ifdef HAVE_SYS_ERRLIST +#undef sys_errlist +#endif + +/* Routines imported from standard C runtime libraries. */ + +#ifdef __STDC__ +#include +extern void *malloc (size_t size); /* 4.10.3.3 */ +extern void *memset (void *s, int c, size_t n); /* 4.11.6.1 */ +#else /* !__STDC__ */ +extern char *malloc (); /* Standard memory allocater */ +extern char *memset (); +#endif /* __STDC__ */ + +#ifndef MAX +# define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif + +static void init_error_tables PARAMS ((void)); + +/* Translation table for errno values. See intro(2) in most UNIX systems + Programmers Reference Manuals. + + Note that this table is generally only accessed when it is used at runtime + to initialize errno name and message tables that are indexed by errno + value. + + Not all of these errnos will exist on all systems. This table is the only + thing that should have to be updated as new error numbers are introduced. + It's sort of ugly, but at least its portable. */ + +struct error_info +{ + int value; /* The numeric value from */ + const char *name; /* The equivalent symbolic value */ +#ifndef HAVE_SYS_ERRLIST + const char *msg; /* Short message about this value */ +#endif +}; + +#ifndef HAVE_SYS_ERRLIST +# define ENTRY(value, name, msg) {value, name, msg} +#else +# define ENTRY(value, name, msg) {value, name} +#endif + +static const struct error_info error_table[] = +{ +#if defined (EPERM) + ENTRY(EPERM, "EPERM", "Not owner"), +#endif +#if defined (ENOENT) + ENTRY(ENOENT, "ENOENT", "No such file or directory"), +#endif +#if defined (ESRCH) + ENTRY(ESRCH, "ESRCH", "No such process"), +#endif +#if defined (EINTR) + ENTRY(EINTR, "EINTR", "Interrupted system call"), +#endif +#if defined (EIO) + ENTRY(EIO, "EIO", "I/O error"), +#endif +#if defined (ENXIO) + ENTRY(ENXIO, "ENXIO", "No such device or address"), +#endif +#if defined (E2BIG) + ENTRY(E2BIG, "E2BIG", "Arg list too long"), +#endif +#if defined (ENOEXEC) + ENTRY(ENOEXEC, "ENOEXEC", "Exec format error"), +#endif +#if defined (EBADF) + ENTRY(EBADF, "EBADF", "Bad file number"), +#endif +#if defined (ECHILD) + ENTRY(ECHILD, "ECHILD", "No child processes"), +#endif +#if defined (EWOULDBLOCK) /* Put before EAGAIN, sometimes aliased */ + ENTRY(EWOULDBLOCK, "EWOULDBLOCK", "Operation would block"), +#endif +#if defined (EAGAIN) + ENTRY(EAGAIN, "EAGAIN", "No more processes"), +#endif +#if defined (ENOMEM) + ENTRY(ENOMEM, "ENOMEM", "Not enough space"), +#endif +#if defined (EACCES) + ENTRY(EACCES, "EACCES", "Permission denied"), +#endif +#if defined (EFAULT) + ENTRY(EFAULT, "EFAULT", "Bad address"), +#endif +#if defined (ENOTBLK) + ENTRY(ENOTBLK, "ENOTBLK", "Block device required"), +#endif +#if defined (EBUSY) + ENTRY(EBUSY, "EBUSY", "Device busy"), +#endif +#if defined (EEXIST) + ENTRY(EEXIST, "EEXIST", "File exists"), +#endif +#if defined (EXDEV) + ENTRY(EXDEV, "EXDEV", "Cross-device link"), +#endif +#if defined (ENODEV) + ENTRY(ENODEV, "ENODEV", "No such device"), +#endif +#if defined (ENOTDIR) + ENTRY(ENOTDIR, "ENOTDIR", "Not a directory"), +#endif +#if defined (EISDIR) + ENTRY(EISDIR, "EISDIR", "Is a directory"), +#endif +#if defined (EINVAL) + ENTRY(EINVAL, "EINVAL", "Invalid argument"), +#endif +#if defined (ENFILE) + ENTRY(ENFILE, "ENFILE", "File table overflow"), +#endif +#if defined (EMFILE) + ENTRY(EMFILE, "EMFILE", "Too many open files"), +#endif +#if defined (ENOTTY) + ENTRY(ENOTTY, "ENOTTY", "Not a typewriter"), +#endif +#if defined (ETXTBSY) + ENTRY(ETXTBSY, "ETXTBSY", "Text file busy"), +#endif +#if defined (EFBIG) + ENTRY(EFBIG, "EFBIG", "File too large"), +#endif +#if defined (ENOSPC) + ENTRY(ENOSPC, "ENOSPC", "No space left on device"), +#endif +#if defined (ESPIPE) + ENTRY(ESPIPE, "ESPIPE", "Illegal seek"), +#endif +#if defined (EROFS) + ENTRY(EROFS, "EROFS", "Read-only file system"), +#endif +#if defined (EMLINK) + ENTRY(EMLINK, "EMLINK", "Too many links"), +#endif +#if defined (EPIPE) + ENTRY(EPIPE, "EPIPE", "Broken pipe"), +#endif +#if defined (EDOM) + ENTRY(EDOM, "EDOM", "Math argument out of domain of func"), +#endif +#if defined (ERANGE) + ENTRY(ERANGE, "ERANGE", "Math result not representable"), +#endif +#if defined (ENOMSG) + ENTRY(ENOMSG, "ENOMSG", "No message of desired type"), +#endif +#if defined (EIDRM) + ENTRY(EIDRM, "EIDRM", "Identifier removed"), +#endif +#if defined (ECHRNG) + ENTRY(ECHRNG, "ECHRNG", "Channel number out of range"), +#endif +#if defined (EL2NSYNC) + ENTRY(EL2NSYNC, "EL2NSYNC", "Level 2 not synchronized"), +#endif +#if defined (EL3HLT) + ENTRY(EL3HLT, "EL3HLT", "Level 3 halted"), +#endif +#if defined (EL3RST) + ENTRY(EL3RST, "EL3RST", "Level 3 reset"), +#endif +#if defined (ELNRNG) + ENTRY(ELNRNG, "ELNRNG", "Link number out of range"), +#endif +#if defined (EUNATCH) + ENTRY(EUNATCH, "EUNATCH", "Protocol driver not attached"), +#endif +#if defined (ENOCSI) + ENTRY(ENOCSI, "ENOCSI", "No CSI structure available"), +#endif +#if defined (EL2HLT) + ENTRY(EL2HLT, "EL2HLT", "Level 2 halted"), +#endif +#if defined (EDEADLK) + ENTRY(EDEADLK, "EDEADLK", "Deadlock condition"), +#endif +#if defined (ENOLCK) + ENTRY(ENOLCK, "ENOLCK", "No record locks available"), +#endif +#if defined (EBADE) + ENTRY(EBADE, "EBADE", "Invalid exchange"), +#endif +#if defined (EBADR) + ENTRY(EBADR, "EBADR", "Invalid request descriptor"), +#endif +#if defined (EXFULL) + ENTRY(EXFULL, "EXFULL", "Exchange full"), +#endif +#if defined (ENOANO) + ENTRY(ENOANO, "ENOANO", "No anode"), +#endif +#if defined (EBADRQC) + ENTRY(EBADRQC, "EBADRQC", "Invalid request code"), +#endif +#if defined (EBADSLT) + ENTRY(EBADSLT, "EBADSLT", "Invalid slot"), +#endif +#if defined (EDEADLOCK) + ENTRY(EDEADLOCK, "EDEADLOCK", "File locking deadlock error"), +#endif +#if defined (EBFONT) + ENTRY(EBFONT, "EBFONT", "Bad font file format"), +#endif +#if defined (ENOSTR) + ENTRY(ENOSTR, "ENOSTR", "Device not a stream"), +#endif +#if defined (ENODATA) + ENTRY(ENODATA, "ENODATA", "No data available"), +#endif +#if defined (ETIME) + ENTRY(ETIME, "ETIME", "Timer expired"), +#endif +#if defined (ENOSR) + ENTRY(ENOSR, "ENOSR", "Out of streams resources"), +#endif +#if defined (ENONET) + ENTRY(ENONET, "ENONET", "Machine is not on the network"), +#endif +#if defined (ENOPKG) + ENTRY(ENOPKG, "ENOPKG", "Package not installed"), +#endif +#if defined (EREMOTE) + ENTRY(EREMOTE, "EREMOTE", "Object is remote"), +#endif +#if defined (ENOLINK) + ENTRY(ENOLINK, "ENOLINK", "Link has been severed"), +#endif +#if defined (EADV) + ENTRY(EADV, "EADV", "Advertise error"), +#endif +#if defined (ESRMNT) + ENTRY(ESRMNT, "ESRMNT", "Srmount error"), +#endif +#if defined (ECOMM) + ENTRY(ECOMM, "ECOMM", "Communication error on send"), +#endif +#if defined (EPROTO) + ENTRY(EPROTO, "EPROTO", "Protocol error"), +#endif +#if defined (EMULTIHOP) + ENTRY(EMULTIHOP, "EMULTIHOP", "Multihop attempted"), +#endif +#if defined (EDOTDOT) + ENTRY(EDOTDOT, "EDOTDOT", "RFS specific error"), +#endif +#if defined (EBADMSG) + ENTRY(EBADMSG, "EBADMSG", "Not a data message"), +#endif +#if defined (ENAMETOOLONG) + ENTRY(ENAMETOOLONG, "ENAMETOOLONG", "File name too long"), +#endif +#if defined (EOVERFLOW) + ENTRY(EOVERFLOW, "EOVERFLOW", "Value too large for defined data type"), +#endif +#if defined (ENOTUNIQ) + ENTRY(ENOTUNIQ, "ENOTUNIQ", "Name not unique on network"), +#endif +#if defined (EBADFD) + ENTRY(EBADFD, "EBADFD", "File descriptor in bad state"), +#endif +#if defined (EREMCHG) + ENTRY(EREMCHG, "EREMCHG", "Remote address changed"), +#endif +#if defined (ELIBACC) + ENTRY(ELIBACC, "ELIBACC", "Can not access a needed shared library"), +#endif +#if defined (ELIBBAD) + ENTRY(ELIBBAD, "ELIBBAD", "Accessing a corrupted shared library"), +#endif +#if defined (ELIBSCN) + ENTRY(ELIBSCN, "ELIBSCN", ".lib section in a.out corrupted"), +#endif +#if defined (ELIBMAX) + ENTRY(ELIBMAX, "ELIBMAX", "Attempting to link in too many shared libraries"), +#endif +#if defined (ELIBEXEC) + ENTRY(ELIBEXEC, "ELIBEXEC", "Cannot exec a shared library directly"), +#endif +#if defined (EILSEQ) + ENTRY(EILSEQ, "EILSEQ", "Illegal byte sequence"), +#endif +#if defined (ENOSYS) + ENTRY(ENOSYS, "ENOSYS", "Operation not applicable"), +#endif +#if defined (ELOOP) + ENTRY(ELOOP, "ELOOP", "Too many symbolic links encountered"), +#endif +#if defined (ERESTART) + ENTRY(ERESTART, "ERESTART", "Interrupted system call should be restarted"), +#endif +#if defined (ESTRPIPE) + ENTRY(ESTRPIPE, "ESTRPIPE", "Streams pipe error"), +#endif +#if defined (ENOTEMPTY) + ENTRY(ENOTEMPTY, "ENOTEMPTY", "Directory not empty"), +#endif +#if defined (EUSERS) + ENTRY(EUSERS, "EUSERS", "Too many users"), +#endif +#if defined (ENOTSOCK) + ENTRY(ENOTSOCK, "ENOTSOCK", "Socket operation on non-socket"), +#endif +#if defined (EDESTADDRREQ) + ENTRY(EDESTADDRREQ, "EDESTADDRREQ", "Destination address required"), +#endif +#if defined (EMSGSIZE) + ENTRY(EMSGSIZE, "EMSGSIZE", "Message too long"), +#endif +#if defined (EPROTOTYPE) + ENTRY(EPROTOTYPE, "EPROTOTYPE", "Protocol wrong type for socket"), +#endif +#if defined (ENOPROTOOPT) + ENTRY(ENOPROTOOPT, "ENOPROTOOPT", "Protocol not available"), +#endif +#if defined (EPROTONOSUPPORT) + ENTRY(EPROTONOSUPPORT, "EPROTONOSUPPORT", "Protocol not supported"), +#endif +#if defined (ESOCKTNOSUPPORT) + ENTRY(ESOCKTNOSUPPORT, "ESOCKTNOSUPPORT", "Socket type not supported"), +#endif +#if defined (EOPNOTSUPP) + ENTRY(EOPNOTSUPP, "EOPNOTSUPP", "Operation not supported on transport endpoint"), +#endif +#if defined (EPFNOSUPPORT) + ENTRY(EPFNOSUPPORT, "EPFNOSUPPORT", "Protocol family not supported"), +#endif +#if defined (EAFNOSUPPORT) + ENTRY(EAFNOSUPPORT, "EAFNOSUPPORT", "Address family not supported by protocol"), +#endif +#if defined (EADDRINUSE) + ENTRY(EADDRINUSE, "EADDRINUSE", "Address already in use"), +#endif +#if defined (EADDRNOTAVAIL) + ENTRY(EADDRNOTAVAIL, "EADDRNOTAVAIL","Cannot assign requested address"), +#endif +#if defined (ENETDOWN) + ENTRY(ENETDOWN, "ENETDOWN", "Network is down"), +#endif +#if defined (ENETUNREACH) + ENTRY(ENETUNREACH, "ENETUNREACH", "Network is unreachable"), +#endif +#if defined (ENETRESET) + ENTRY(ENETRESET, "ENETRESET", "Network dropped connection because of reset"), +#endif +#if defined (ECONNABORTED) + ENTRY(ECONNABORTED, "ECONNABORTED", "Software caused connection abort"), +#endif +#if defined (ECONNRESET) + ENTRY(ECONNRESET, "ECONNRESET", "Connection reset by peer"), +#endif +#if defined (ENOBUFS) + ENTRY(ENOBUFS, "ENOBUFS", "No buffer space available"), +#endif +#if defined (EISCONN) + ENTRY(EISCONN, "EISCONN", "Transport endpoint is already connected"), +#endif +#if defined (ENOTCONN) + ENTRY(ENOTCONN, "ENOTCONN", "Transport endpoint is not connected"), +#endif +#if defined (ESHUTDOWN) + ENTRY(ESHUTDOWN, "ESHUTDOWN", "Cannot send after transport endpoint shutdown"), +#endif +#if defined (ETOOMANYREFS) + ENTRY(ETOOMANYREFS, "ETOOMANYREFS", "Too many references: cannot splice"), +#endif +#if defined (ETIMEDOUT) + ENTRY(ETIMEDOUT, "ETIMEDOUT", "Connection timed out"), +#endif +#if defined (ECONNREFUSED) + ENTRY(ECONNREFUSED, "ECONNREFUSED", "Connection refused"), +#endif +#if defined (EHOSTDOWN) + ENTRY(EHOSTDOWN, "EHOSTDOWN", "Host is down"), +#endif +#if defined (EHOSTUNREACH) + ENTRY(EHOSTUNREACH, "EHOSTUNREACH", "No route to host"), +#endif +#if defined (EALREADY) + ENTRY(EALREADY, "EALREADY", "Operation already in progress"), +#endif +#if defined (EINPROGRESS) + ENTRY(EINPROGRESS, "EINPROGRESS", "Operation now in progress"), +#endif +#if defined (ESTALE) + ENTRY(ESTALE, "ESTALE", "Stale NFS file handle"), +#endif +#if defined (EUCLEAN) + ENTRY(EUCLEAN, "EUCLEAN", "Structure needs cleaning"), +#endif +#if defined (ENOTNAM) + ENTRY(ENOTNAM, "ENOTNAM", "Not a XENIX named type file"), +#endif +#if defined (ENAVAIL) + ENTRY(ENAVAIL, "ENAVAIL", "No XENIX semaphores available"), +#endif +#if defined (EISNAM) + ENTRY(EISNAM, "EISNAM", "Is a named type file"), +#endif +#if defined (EREMOTEIO) + ENTRY(EREMOTEIO, "EREMOTEIO", "Remote I/O error"), +#endif + ENTRY(0, NULL, NULL) +}; + +#ifdef EVMSERR +/* This is not in the table, because the numeric value of EVMSERR (32767) + lies outside the range of sys_errlist[]. */ +static struct { int value; const char *name, *msg; } + evmserr = { EVMSERR, "EVMSERR", "VMS-specific error" }; +#endif + +/* Translation table allocated and initialized at runtime. Indexed by the + errno value to find the equivalent symbolic value. */ + +static const char **error_names; +static int num_error_names = 0; + +/* Translation table allocated and initialized at runtime, if it does not + already exist in the host environment. Indexed by the errno value to find + the descriptive string. + + We don't export it for use in other modules because even though it has the + same name, it differs from other implementations in that it is dynamically + initialized rather than statically initialized. */ + +#ifndef HAVE_SYS_ERRLIST + +static int sys_nerr; +static const char **sys_errlist; + +#else + +extern int sys_nerr; +extern char *sys_errlist[]; + +#endif + + +/* + +NAME + + init_error_tables -- initialize the name and message tables + +SYNOPSIS + + static void init_error_tables (); + +DESCRIPTION + + Using the error_table, which is initialized at compile time, generate + the error_names and the sys_errlist (if needed) tables, which are + indexed at runtime by a specific errno value. + +BUGS + + The initialization of the tables may fail under low memory conditions, + in which case we don't do anything particularly useful, but we don't + bomb either. Who knows, it might succeed at a later point if we free + some memory in the meantime. In any case, the other routines know + how to deal with lack of a table after trying to initialize it. This + may or may not be considered to be a bug, that we don't specifically + warn about this particular failure mode. + +*/ + +static void +init_error_tables () +{ + const struct error_info *eip; + int nbytes; + + /* If we haven't already scanned the error_table once to find the maximum + errno value, then go find it now. */ + + if (num_error_names == 0) + { + for (eip = error_table; eip -> name != NULL; eip++) + { + if (eip -> value >= num_error_names) + { + num_error_names = eip -> value + 1; + } + } + } + + /* Now attempt to allocate the error_names table, zero it out, and then + initialize it from the statically initialized error_table. */ + + if (error_names == NULL) + { + nbytes = num_error_names * sizeof (char *); + if ((error_names = (const char **) malloc (nbytes)) != NULL) + { + memset (error_names, 0, nbytes); + for (eip = error_table; eip -> name != NULL; eip++) + { + error_names[eip -> value] = eip -> name; + } + } + } + +#ifndef HAVE_SYS_ERRLIST + + /* Now attempt to allocate the sys_errlist table, zero it out, and then + initialize it from the statically initialized error_table. */ + + if (sys_errlist == NULL) + { + nbytes = num_error_names * sizeof (char *); + if ((sys_errlist = (const char **) malloc (nbytes)) != NULL) + { + memset (sys_errlist, 0, nbytes); + sys_nerr = num_error_names; + for (eip = error_table; eip -> name != NULL; eip++) + { + sys_errlist[eip -> value] = eip -> msg; + } + } + } + +#endif + +} + +/* + +NAME + + errno_max -- return the max errno value + +SYNOPSIS + + int errno_max (); + +DESCRIPTION + + Returns the maximum errno value for which a corresponding symbolic + name or message is available. Note that in the case where + we use the sys_errlist supplied by the system, it is possible for + there to be more symbolic names than messages, or vice versa. + In fact, the manual page for perror(3C) explicitly warns that one + should check the size of the table (sys_nerr) before indexing it, + since new error codes may be added to the system before they are + added to the table. Thus sys_nerr might be smaller than value + implied by the largest errno value defined in . + + We return the maximum value that can be used to obtain a meaningful + symbolic name or message. + +*/ + +int +errno_max () +{ + int maxsize; + + if (error_names == NULL) + { + init_error_tables (); + } + maxsize = MAX (sys_nerr, num_error_names); + return (maxsize - 1); +} + +#ifndef HAVE_STRERROR + +/* + +NAME + + strerror -- map an error number to an error message string + +SYNOPSIS + + char *strerror (int errnoval) + +DESCRIPTION + + Maps an errno number to an error message string, the contents of + which are implementation defined. On systems which have the external + variables sys_nerr and sys_errlist, these strings will be the same + as the ones used by perror(). + + If the supplied error number is within the valid range of indices + for the sys_errlist, but no message is available for the particular + error number, then returns the string "Error NUM", where NUM is the + error number. + + If the supplied error number is not a valid index into sys_errlist, + returns NULL. + + The returned string is only guaranteed to be valid only until the + next call to strerror. + +*/ + +char * +strerror (errnoval) + int errnoval; +{ + char *msg; + static char buf[32]; + +#ifndef HAVE_SYS_ERRLIST + + if (error_names == NULL) + { + init_error_tables (); + } + +#endif + + if ((errnoval < 0) || (errnoval >= sys_nerr)) + { +#ifdef EVMSERR + if (errnoval == evmserr.value) + msg = evmserr.msg; + else +#endif + /* Out of range, just return NULL */ + msg = NULL; + } + else if ((sys_errlist == NULL) || (sys_errlist[errnoval] == NULL)) + { + /* In range, but no sys_errlist or no entry at this index. */ + sprintf (buf, "Error %d", errnoval); + msg = buf; + } + else + { + /* In range, and a valid message. Just return the message. */ + msg = (char *) sys_errlist[errnoval]; + } + + return (msg); +} + +#endif /* ! HAVE_STRERROR */ + + +/* + +NAME + + strerrno -- map an error number to a symbolic name string + +SYNOPSIS + + const char *strerrno (int errnoval) + +DESCRIPTION + + Given an error number returned from a system call (typically + returned in errno), returns a pointer to a string containing the + symbolic name of that error number, as found in . + + If the supplied error number is within the valid range of indices + for symbolic names, but no name is available for the particular + error number, then returns the string "Error NUM", where NUM is + the error number. + + If the supplied error number is not within the range of valid + indices, then returns NULL. + +BUGS + + The contents of the location pointed to are only guaranteed to be + valid until the next call to strerrno. + +*/ + +const char * +strerrno (errnoval) + int errnoval; +{ + const char *name; + static char buf[32]; + + if (error_names == NULL) + { + init_error_tables (); + } + + if ((errnoval < 0) || (errnoval >= num_error_names)) + { +#ifdef EVMSERR + if (errnoval == evmserr.value) + name = evmserr.name; + else +#endif + /* Out of range, just return NULL */ + name = NULL; + } + else if ((error_names == NULL) || (error_names[errnoval] == NULL)) + { + /* In range, but no error_names or no entry at this index. */ + sprintf (buf, "Error %d", errnoval); + name = (const char *) buf; + } + else + { + /* In range, and a valid name. Just return the name. */ + name = error_names[errnoval]; + } + + return (name); +} + +/* + +NAME + + strtoerrno -- map a symbolic errno name to a numeric value + +SYNOPSIS + + int strtoerrno (char *name) + +DESCRIPTION + + Given the symbolic name of a error number, map it to an errno value. + If no translation is found, returns 0. + +*/ + +int +strtoerrno (name) + const char *name; +{ + int errnoval = 0; + + if (name != NULL) + { + if (error_names == NULL) + { + init_error_tables (); + } + for (errnoval = 0; errnoval < num_error_names; errnoval++) + { + if ((error_names[errnoval] != NULL) && + (strcmp (name, error_names[errnoval]) == 0)) + { + break; + } + } + if (errnoval == num_error_names) + { +#ifdef EVMSERR + if (strcmp (name, evmserr.name) == 0) + errnoval = evmserr.value; + else +#endif + errnoval = 0; + } + } + return (errnoval); +} + + +/* A simple little main that does nothing but print all the errno translations + if MAIN is defined and this file is compiled and linked. */ + +#ifdef MAIN + +#include + +int +main () +{ + int errn; + int errnmax; + const char *name; + char *msg; + char *strerror (); + + errnmax = errno_max (); + printf ("%d entries in names table.\n", num_error_names); + printf ("%d entries in messages table.\n", sys_nerr); + printf ("%d is max useful index.\n", errnmax); + + /* Keep printing values until we get to the end of *both* tables, not + *either* table. Note that knowing the maximum useful index does *not* + relieve us of the responsibility of testing the return pointer for + NULL. */ + + for (errn = 0; errn <= errnmax; errn++) + { + name = strerrno (errn); + name = (name == NULL) ? "" : name; + msg = strerror (errn); + msg = (msg == NULL) ? "" : msg; + printf ("%-4d%-18s%s\n", errn, name, msg); + } + + return 0; +} + +#endif diff --git a/src/libs/stdc++/strstream.cc b/src/libs/stdc++/strstream.cc new file mode 100644 index 0000000000..fcfa02dbac --- /dev/null +++ b/src/libs/stdc++/strstream.cc @@ -0,0 +1,116 @@ +/* This is part of libio/iostream, providing -*- C++ -*- input/output. +Copyright (C) 1993 Free Software Foundation + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + +/* Written by Per Bothner (bothner@cygnus.com). */ + +#ifdef __GNUG__ +#pragma implementation +#endif +#include "iostreamP.h" +#include "strstream.h" +#include + +static void* default_alloc(_IO_size_t size) +{ + return (void*)new char[size]; +} + +static void default_free(void* ptr) +{ + delete [] (char*)ptr; +} + +istrstream::istrstream(const char *cp, int n) +{ + __my_sb.init_readonly (cp, n); +} + +strstreambase::strstreambase(char *cp, int n, int mode) +: __my_sb (cp, n, + (mode == ios::app || mode == ios::ate) ? cp + strlen(cp) : cp) +{ + init (&__my_sb); +} + +char *strstreambuf::str() +{ + freeze(1); + return base(); +} + +_IO_ssize_t strstreambuf::pcount () { return _IO_write_ptr - _IO_write_base; } + +int strstreambuf::overflow(int c /* = EOF */) +{ + return _IO_str_overflow (this, c); +} + +int strstreambuf::underflow() +{ + return _IO_str_underflow(this); +} + + +void strstreambuf::init_dynamic(_IO_alloc_type alloc, _IO_free_type free, + int initial_size) + +{ + _s._allocate_buffer = alloc ? alloc : default_alloc; + _s._free_buffer = free ? free : default_free; + if (initial_size > 0) + { + char * buf = (char*)(*_s._allocate_buffer)(initial_size); + setb(buf, buf + initial_size, 1); + setp(buf, buf + initial_size); + setg(buf, buf, buf); + } +} + +void strstreambuf::init_static(char *ptr, int size, char *pstart) +{ + _IO_str_init_static (reinterpret_cast<_IO_strfile_*>(this), ptr, size, pstart); +} + +void strstreambuf::init_readonly (const char *ptr, int size) +{ + _IO_str_init_readonly (reinterpret_cast<_IO_strfile_*>(this), ptr, size); +} + +strstreambuf::~strstreambuf() +{ + if (_IO_buf_base && !(_flags & _IO_USER_BUF)) + (_s._free_buffer)(_IO_buf_base); + _IO_buf_base = NULL; +} + +streampos strstreambuf::seekoff(streamoff off, _seek_dir dir, + int mode /*=ios::in|ios::out*/) +{ + return _IO_str_seekoff (this, off, dir, mode); +} + +int strstreambuf::pbackfail(int c) +{ + return _IO_str_pbackfail (this, c); +} diff --git a/src/libs/stdc++/valarray.cc b/src/libs/stdc++/valarray.cc new file mode 100644 index 0000000000..5e7fe0cf05 --- /dev/null +++ b/src/libs/stdc++/valarray.cc @@ -0,0 +1,50 @@ +#include + +// Some Explicit Instanciations. +template class multiplies; +template size_t accumulate(size_t*, size_t*, size_t, multiplies); + +template void + __valarray_fill(size_t* __restrict__, size_t, const size_t&); + +template void + __valarray_copy(const size_t* __restrict__, size_t, size_t* __restrict__); + +template valarray::valarray(size_t); +template valarray::~valarray(); +template valarray::valarray(const valarray&); +template size_t valarray::size() const; +template size_t& valarray::operator[](size_t); +template size_t valarray::product() const; + + +void __gslice_to_index(size_t __o, const valarray& __l, + const valarray& __s, + valarray& __i) +{ + const size_t __n = __l.size(); + size_t* const __t = static_cast(alloca(__n*sizeof(size_t))); + __valarray_fill(__t, __n, size_t(0)); + const size_t __z = __i.size(); + __valarray_fill(&__i[0], __z, __o); + for (size_t __j=0; __j<__z; ++__j) { + for (size_t __k=0; __k<__n; ++__k) + __i[__j] += __s[__k]*__t[__k]; + ++__t[__n-1]; + for (size_t __k=__n-1; __k; --__k) { + if (__t[__k] >= __l[__k]) { + __t[__k] = 0; + ++__t[__k-1]; + } + } + } +} + +_Indexer::_Indexer(size_t __o, const valarray& __l, + const valarray& __s) + : _M_count(1), _M_start(__o), _M_size(__l), _M_stride(__s), + _M_index(__l.size() ? __l.product() : 0) +{ __gslice_to_index(__o, __l, __s, _M_index); } + + + diff --git a/src/libs/stdc++/vfork.c b/src/libs/stdc++/vfork.c new file mode 100644 index 0000000000..b75e314036 --- /dev/null +++ b/src/libs/stdc++/vfork.c @@ -0,0 +1,10 @@ +/* Emulate vfork using just plain fork, for systems without a real vfork. + This function is in the public domain. */ + +#include + +int +vfork () +{ + return (fork ()); +}