diff options
author | obrien <obrien@FreeBSD.org> | 1999-10-04 08:12:38 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 1999-10-04 08:12:38 +0000 |
commit | b9cf96069d0d7f048d1d4b19ed28599da02f9340 (patch) | |
tree | 2938e0e4733de573054ab45365da2ee858f9c3b7 /contrib | |
parent | 65f7b2e95b3f38eb1f69e19923dcd0a9cc406719 (diff) | |
parent | 2cef6469c5bfaca5647a9b7478a519d0de7d7b64 (diff) | |
download | FreeBSD-src-b9cf96069d0d7f048d1d4b19ed28599da02f9340.zip FreeBSD-src-b9cf96069d0d7f048d1d4b19ed28599da02f9340.tar.gz |
This commit was generated by cvs2svn to compensate for changes in r51920,
which included commits to RCS files with non-trunk default branches.
Diffstat (limited to 'contrib')
159 files changed, 26972 insertions, 0 deletions
diff --git a/contrib/libstdc++/ChangeLog b/contrib/libstdc++/ChangeLog new file mode 100644 index 0000000..d29a773 --- /dev/null +++ b/contrib/libstdc++/ChangeLog @@ -0,0 +1,1106 @@ +Sun Mar 14 02:38:07 PST 1999 Jeff Law (law@cygnus.com) + + * egcs-1.1.2 Released. + +Thu Feb 25 02:21:22 1999 Jeffrey A Law (law@cygnus.com) + + Thu Feb 18 19:53:17 1999 Marc Espie <espie@cvs.openbsd.org> + * configure.in: Handle OpenBSD with and without threads. + * config/openbsd.ml: New file. + * config/openbsd.mt: New file. + +Mon Nov 23 09:44:26 1998 Richard Henderson <rth@cygnus.com> + + * configure.in: Append mh-ppcpic and mh-elfalphapic as appropriate. + +1998-08-17 Mark Mitchell <mark@markmitchell.com> + + * stdexcept: Put things in the std namespace, if appropriate. + +1998-07-12 Jason Merrill <jason@yorick.cygnus.com> + + * Makefile.in (VERSION): Bump to 2.9.0. + +1998-07-12 Lars Albertsson <lalle@sics.se> + + * std/bastring.cc (find_last_of): Fix. + (find_last_not_of): Likewise. + +1998-07-06 Manfred Hollstein <manfred@s-direktnet.de> + + * configure.in (INSTALLDIR): Make sed pattern failsafe. + +1998-07-06 Ulrich Drepper <drepper@cygnus.com> + + * std/bastring.h (class basic_string): Correct iterator return + values in insert member functions. + +1998-07-02 Ulrich Drepper <drepper@cygnus.com> + + * std/bastring.h (class basic_string): Return correct iterators in + erase member functions. + +1998-06-24 Manfred Hollstein <manfred@s-direktnet.de> + + * Makefile.in (INSTALLDIR): Add comment to document the fact, + this macro will be properly initialized at make's runtime. + (install): Add initialization of INSTALLDIR depending on $(libsubdir) + and ${enable_version_specific_runtime_libs}; use $${INSTALLDIR} shell + variable instead of the $(INSTALLDIR) make macro. + +Tue Mar 24 10:13:07 1998 Jason Merrill <jason@yorick.cygnus.com> + + * std/bastring.cc (basic_string::copy): Mark const here, too. + +1998-03-23 15:59 Ulrich Drepper <drepper@cygnus.com> + + * std/bastring.h (basic_string::copy): Mark copy function as const. + Reported by Scott Schurr <scotts@ims.com>. + +Thu Mar 5 09:23:28 1998 Manfred Hollstein <manfred@s-direktnet.de> + + * configure.in: Make locating frag files failsafe even for the + special case if configuring and building in srcdir. + +1998-03-04 12:37 Ulrich Drepper <drepper@cygnus.com> + + * cinst.cc [INSERT] (operator<<): Correct type of numeric argument. + +Fri Feb 6 01:36:21 1998 Manfred Hollstein <manfred@s-direktnet.de> + + * Makefile.in (piclist): Check value of enable_shared, not PICFLAG. + (stmp-string, ...): Dito. + (bigstmp-string, ...): Dito. + +Sun Feb 1 13:38:07 1998 H.J. Lu (hjl@gnu.org) + + * config/linux.mt: Don't define _PTHREADS, but define + _IO_MTSAFE_IO. + +Wed Jan 28 10:27:11 1998 Manfred Hollstein <manfred@s-direktnet.de> + + * tests/configure.in, testsuite/configure.in: Update with yesterday's + toplevel configure.in changes. + +Tue Jan 27 23:27:32 1998 Manfred Hollstein <manfred@s-direktnet.de> + + * configure.in (package_makefile_rules_frag): New variable + which is used in the call to config.shared; redirect file descriptor 2 + to ${package_makefile_rules_frag}. + +Tue Jan 27 10:11:27 1998 Jason Merrill <jason@yorick.cygnus.com> + + * Makefile.in (install): Remove the shared library symlink even if + we aren't installing it. + +Tue Jan 27 10:29:44 1998 H.J. Lu (hjl@gnu.org) + + * configure.in (topsrcdir): New. + (configdirs): Check ${topsrcdir}/gcc instead. + (config-ml.in): Use ${topsrcdir}/config-ml.in. + + * tests/configure.in (topsrcdir): New. + (check): Check ${topsrcdir}/gcc instead. + +Sun Jan 25 14:01:50 1998 Jason Merrill <jason@yorick.cygnus.com> + + * std/bastring.h (unique): We only need length bytes. + (c_str): Avoid writing over random memory. + #include <std/bastring.cc>. + Lose _G_ALLOC_CONTROL. + * std/bastring.cc: Likewise. + (nilRep): Add initializer for selfish. + * sinst.cc: Just #include <string>. + +Tue Jan 13 21:23:05 1998 H.J. Lu (hjl@gnu.org) + + * configure.in (configdirs): Include testsuite only if + ${srcdir}/../gcc exists. + + * tests/configure.in (check): Set to ${CHECK} if + ${srcdir}/../../gcc doesn't exists. + +1998-01-05 Brendan Kehoe <brendan@lisa.cygnus.com> + + * std/bastring.cc (basic_string::Rep::operator delete): Don't claim + to return from deallocate, since this is a void method. + +Sat Jan 3 12:15:41 1998 Franz Sirl <franz.sirl-kernel@lauterbach.com> + + * configure.in: Finalize support for {alpha|powerpc}*-*-linux-gnulibc1 + +Sun Dec 7 02:34:40 1997 Jody Goldberg <jodyg@idt.net> + + * libstdc++/std/bastring.h : Move closer to the draft standard + implementation of basic_string by adding 3 paramter 'Allocator'. + NOTE: this still differs from the standard in not offering per + instance allocators. + * libstdc++/std/bastring.cc : Likewise. + * libstdc++/stlinst.cc : Handle thread safe allocators if they are the + default. + +Sun Dec 7 02:32:20 1997 Jason Merrill <jason@yorick.cygnus.com> + + * iosfwd: New header. + * Makefile.in (HEADERS): Add it. + +Sun Dec 7 02:32:20 1997 Gregory L. Galloway (gregg@eoeml.gtri.gatech.edu) + + * Makefile.in (HEADERS): Modified list of headers to + install to include all of SGI STL headers especially hash_set and + hash_map, and added ANSI C++ style wrappers for fstream, iomanip, + iostream, and strstream. + + * fstream, iomanip, iostream, strstream: New forwarding headers + added. + +Thu Nov 27 01:33:55 1997 Jeffrey A Law (law@cygnus.com) + + * Makefile.in (install): Change gxx_includedir to gxx_include_dir. + +Tue Nov 25 23:16:44 1997 Jason Merrill <jason@yorick.cygnus.com> + + London changes to string: + * std/bastring.cc (check_realloc): Don't be selfish anymore. + * std/bastring.h (non-const operator[]): Be selfish. + (iterator forms of insert and erase): Stay selfish. + +Tue Nov 25 14:03:43 1997 H.J. Lu (hjl@gnu.org) + + * Makefile.in (stmp-complex, bigstmp-complex): Changed to + xxxx-complx. + +Mon Nov 24 14:41:33 1997 Jeffrey A Law (law@cygnus.com) + + * Makefile.in: Use ln -f -s, not ln -s -f. + +Fri Nov 21 12:56:24 1997 Manfred Hollstein <manfred@s-direktnet.de> + + * Makefile.in (bigstmp-complex): Name changed to bigstmp-complx to + cope with filesystem not capable to handle names longer than + 14 characters. + +Sun Nov 16 22:41:55 1997 Jeffrey A Law (law@cygnus.com) + + * Makefile.in (SHLIB): Build with CC instead of CXX. + +Sun Nov 2 23:34:09 1997 Manfred Hollstein <manfred@s-direktnet.de> + + * configure.in: Use delta.mt for m68k-motorola-sysv. + * config/delta.mt: New makefile fragment. + +Sun Nov 2 12:14:37 1997 Jason Merrill <jason@yorick.cygnus.com> + + * Makefile.in (install): Some of HEADERS come from the stl dir now. + * algorithm, deque, functional, iterator, list, map, memory, numeric, + queue, set, stack, utility, vector: Now in stl dir. + +Fri Oct 10 00:40:00 1997 Jason Merrill <jason@yorick.cygnus.com> + + * std/bastring.h: Use ibegin internally. Return passed iterator + instead of recalculating it where appropriate. + * std/bastring.cc: Adjust for erase. + + From Yotam Medini: + * std/bastring.h: Replace remove with erase. + +Thu Oct 9 23:24:36 1997 Jason Merrill <jason@yorick.cygnus.com> + + * stdexcepti.cc (__out_of_range): New fn. + (__length_error): New fn. + + * std/bastring.h (OUTOFRANGE): Fix logic. Use throwing functions. + (LENGTHERROR): Likewise. + Revert Oct 2 changes. + * string: Revert Oct 2 changes. + +Tue Oct 7 00:51:51 1997 Jason Merrill <jason@yorick.cygnus.com> + + * std/{f,d,ld}complex.h: Replace guiding fns if not -ansi. + +Thu Oct 2 00:08:18 1997 Jason Merrill <jason@yorick.cygnus.com> + + * std/bastring.h: Move exception stuff after definition of string. + Move typedef of string here. + * string: From here. + +Sat Sep 27 16:48:00 1997 Jason Merrill <jason@yorick.cygnus.com> + + * std/complext.h: Lose injection decls. + * std/fcomplex.h: Likewise. + * std/dcomplex.h: Likewise. + * std/ldcomplex.h: Likewise. + +Sat Sep 27 16:47:35 1997 Mark Mitchell <mmitchell@usa.net> + + * std/complext.h: Declare templates before making them + friends. Use new friend <> syntax. + * std/complext.cc: Don't rely on guiding declarations. + * std/fcomplex.h: Use new friend <> syntax. + * std/dcomplex.h: Likewise. + * std/ldcomplex.h: Likewise. + +Thu Sep 25 19:55:56 1997 Jason Merrill <jason@yorick.cygnus.com> + + * std/bastring.h: Enable exceptions. + (assign, append, insert, replace): Implement member template versions. + +1997-09-15 02:37 Ulrich Drepper <drepper@cygnus.com> + + * config/linux.mt: New file. Make sure _PTHREADS is defined + if necessary. + * configure.in: Find linux.mt file. + +Thu Sep 11 15:03:20 1997 Jason Merrill <jason@yorick.cygnus.com> + + * std/bastring.h (class basic_string): Add global scope to + use of reverse_iterator. + +Tue Sep 9 19:47:07 1997 Jason Merrill <jason@yorick.cygnus.com> + + * std/bastring.h: Adjust use of reverse_iterator template. + +Wed Aug 27 00:04:33 1997 Alexandre Oliva (oliva@dcc.unicamp.br) + + * Makefile.in: create correct multiple links to + shared libstdc++. + +Tue Aug 26 12:24:01 1997 H.J. Lu (hjl@gnu.ai.mit.edu) + + * testsuite/Makefile.in (check): Don't depend on site.exp. + (just-check): Depend on site.exp. + +Mon Aug 25 14:26:45 1997 Jason Merrill <jason@yorick.cygnus.com> + + * Makefile.in (CXXFLAGS): Add -Weffc++. + +Sat Aug 23 21:25:37 1997 Mark Mitchell <mmitchell@usa.net> + + * bastring.h: Enable reverse_iterator and its ilk. + + * bastring.h: Provide specializations of member function templates + for const_iterator. + +Wed Jul 30 10:59:00 1997 Benjamin Kosnik <bkoz@rhino.cygnus.com> + + * stlinst.cc: Add instantiation file for + __default_alloc_template<fale, 0> and + __malloc_alloc_template<0> + +Sun Jun 1 17:03:40 1997 Jason Merrill <jason@yorick.cygnus.com> + + * std/bastring.cc (find_last_of): Correct handling of POS. + (find_last_not_of): Likewise. + +Thu May 1 17:37:10 1997 Jason Merrill <jason@yorick.cygnus.com> + + * Makefile.in ($(SHLIB)): Add $(LIBCXXFLAGS). + +Wed Apr 30 12:06:23 1997 Jason Merrill <jason@yorick.cygnus.com> + + * Makefile.in (IO_DIR): Remove $(MULTIBUILDTOP). + (LIBIBERTY_DIR): Likewise. + * configure.in: Don't turn on multilib here. + +Fri Apr 25 16:09:15 1997 Bob Manson <manson@charmed.cygnus.com> + + * testsuite/libstdc++.tests/test.exp, testsuite/lib/libstdc++.exp, + testsuite/configure.in, testsuite/Makefile.in, + testsuite/config/default.exp, testsuite/ChangeLog: New files. + + * configure.in: Add new testsuite directory to be configured. + +Tue Apr 22 19:03:39 1997 Alexandre Oliva <oliva@dcc.unicamp.br> + + * Makefile.in (install): Fix handling of mshlink. + +Fri Apr 4 03:25:13 1997 Ulrich Drepper <drepper@cygnus.com> + + * Makefile.in (IO_DIR): Prepend $(MULTIBUILDTOP) to + support multilib build. + (LIBIBERTY_DIR): Likewise. + + * configure.in: Enable multilibing by default. + Update multilib template to read config-ml.in. + +Wed Mar 12 16:09:34 1997 Jason Merrill <jason@yorick.cygnus.com> + + * configure.in (XCXXINCLUDES): Add the STL directory. + +Thu Jan 23 08:08:43 1997 Brendan Kehoe <brendan@lisa.cygnus.com> + + * stdexcept: Delete dtors for all of the error classes, to match + their removal in the Apr 1995 WP. + (class overflow_error): Define missing class, added in May 1996 WP. + +Mon Nov 18 16:57:25 1996 Jason Merrill <jason@yorick.cygnus.com> + + * Makefile.in (stuff[12]): More rules for my own evil purposes. + (CXXFLAGS, CFLAGS): Use -O instead of -O3 so debugging works. + +Wed Oct 16 13:47:45 1996 Jason Merrill <jason@yorick.cygnus.com> + + * config/irix5.ml: Do link against the math library. + * configure.in: Support shared libs on Irix 6. + +Fri Oct 11 18:06:09 1996 Jason Merrill <jason@yorick.cygnus.com> + + * config/linux.ml: Lose version overrides. + + * Makefile.in (MSHLINK): Defaults to .so.2.x + (mshlink): Indirect rule for making it. + +Tue Sep 24 17:58:31 1996 Jason Merrill <jason@yorick.cygnus.com> + + * Remove new, typeinfo, exception, stddef*. + * Move public headers from std/*.h to *. + +Sun Sep 22 05:35:55 1996 Jason Merrill <jason@yorick.cygnus.com> + + * Makefile.in: Remove new, exception, typeinfo handling. + * exceptioni.cc, newi.cc, typeinfoi.cc, std/exception.h, std/new.h, + std/typeinfo.h, new.h: Remove. + * typeinfo, new, exception: Refer to the files with .h in gcc. + +Fri Sep 20 14:39:19 1996 Jason Merrill <jason@yorick.cygnus.com> + + * Makefile.in: Remove references to stl.list. + * configure.in (configdirs): Remove stl. + +Sat Sep 14 09:42:08 1996 Jason Merrill <jason@yorick.cygnus.com> + + * Makefile.in (stuff): Convenience for me. + + * std/bastring.h: Remove kludge obsoleted by new overloading code. + +Fri Sep 6 16:43:21 1996 Jason Merrill <jason@yorick.cygnus.com> + + * typeinfoi.cc (__dynamic_cast): Fix static_cast. + (__rtti_si): Likewise. + (dcast): Likewise. + +Thu Aug 29 17:06:23 1996 Michael Meissner <meissner@tiktok.cygnus.com> + + * configure.in (i[345]86-*-*): Recognize i686 for pentium pro. + +Tue Jul 23 14:27:44 1996 Mike Stump <mrs@cygnus.com> + + * Makefile.in (exceptioni.o): Use -fexceptions now. + +Mon Jun 17 13:57:24 1996 Per Bothner <bothner@deneb.cygnus.com> + + * std/bastring.h (class basic_string::remove): Add casts. + + * configure.in: Use EXTRA_DISTCLEAN rather than DISTCLEAN. + +Fri Jun 7 14:09:20 1996 Jason Merrill <jason@yorick.cygnus.com> + + * typeinfoi.cc (BUILTIN): Align typeinfo object like a pointer. + +Wed May 29 16:48:35 1996 Mike Stump <mrs@cygnus.com> + + * exceptioni.cc (__throw_bad_exception): Add. + * std/exception.h (bad_exception): Add. + * std/typeinfo.h: Remove leftovers of bad_cast_object. + +Mon May 6 14:04:42 1996 Jason Merrill <jason@yorick.cygnus.com> + + * std/complext.h: s/FLOAT/_FLT/g. + +Thu May 2 17:26:24 1996 Mike Stump <mrs@cygnus.com> + + * exceptioni.cc (uncaught_exception): New routine. + * std/exception.h: Declare it. + +Thu Apr 25 13:20:57 1996 Jason Merrill <jason@yorick.cygnus.com> + + * Makefile.in (typeinfoi.o, stdexcepti.o): Use default rule. + +Wed Apr 24 18:38:24 1996 Mike Stump <mrs@cygnus.com> + + * exceptioni.cc: Add #pragma implementation. + * std/exception.h: Add #pragma interface. Moved exception from + stdexcept. + * std/stdexcept.h: Moved exception to exception. Fix all constructor + arguments to take strings to match ANSI. Moved bad_cast and bad_typeid + to typeinfo. + * std/typeinfo.h: Moved bad_cast and bad_typeid from stdexcept. + +Wed Apr 24 10:43:07 1996 Doug Evans <dje@blues.cygnus.com> + + * Makefile.in (newi.o,cstringi.o,stddefi.o,cstdlibi.o,cmathi.o): Add + rules for SunOS VPATH. + +Fri Apr 19 17:24:51 1996 Jason Merrill <jason@yorick.cygnus.com> + + * Version 2.8.0b3. + +Wed Apr 10 14:38:05 1996 Jason Merrill <jason@yorick.cygnus.com> + + * typeinfoi.cc (base_info): Pack the latter three fields into 32 bits. + +Tue Apr 9 15:49:38 1996 Jason Merrill <jason@yorick.cygnus.com> + + * typeinfoi.cc: Add 'const'. + (__class_type_info): Now just one pointer to an array of structs, + rather than four pointers to arrays. + + * typeinfoi.cc (__throw_type_match_rtti): Check for conversion to + void* before conversion to base*. + (dcast): Handle downcasting to X* given other X subobjects in + the most derived type. Ack. + +Mon Apr 8 15:20:32 1996 Ian Lance Taylor <ian@cygnus.com> + + * configure.in: Permit --enable-shared to specify a list of + directories. + +Sun Apr 7 22:50:53 1996 Jason Merrill <jason@yorick.cygnus.com> + + * typeinfoi.cc (__rtti_array): New entry point. + +Sat Apr 6 14:41:18 1996 Jason Merrill <jason@yorick.cygnus.com> + + * exceptioni.cc (__throw_bad_cast): New entry point for compiler. + * typeinfoi.cc: Remove __bad_cast_object. + + * typeinfoi.cc: Add nodes for unsigned builtins. + +Fri Apr 5 18:16:22 1996 Jason Merrill <jason@yorick.cygnus.com> + + * typeinfoi.cc, std/typeinfo.h: Total overhaul. Move most + everything out of the header, move name field into type_info, add + single-inheritance case, rewrite pointer handling, add new + compiler interface. Compare addresses to check for equality. + +Wed Mar 27 11:54:08 1996 Jason Merrill <jason@yorick.cygnus.com> + + * Version 2.8.0b2. + +Fri Mar 8 13:56:18 1996 Jason Merrill <jason@yorick.cygnus.com> + + * std/[cs]inst.h: Remove. + +Thu Mar 7 07:29:00 1996 Lee Iverson <leei@Canada.AI.SRI.COM> + + * Makefile.in (install): Restore deleted chdir to stl subdir. + +Thu Mar 7 15:02:58 1996 Jason Merrill <jason@yorick.cygnus.com> + + * std/complext.h: Fix __attribute__ usage. + +Wed Feb 28 10:00:24 1996 Jason Merrill <jason@yorick.cygnus.com> + + * Version 2.8.0b1. + +Mon Feb 26 17:26:26 1996 Jason Merrill <jason@yorick.cygnus.com> + + * std/cstring.h: New approach to changing signatures of string + manipulation functions. Still disabled. + +Tue Feb 20 18:29:30 1996 Jason Merrill <jason@yorick.cygnus.com> + + * std/complext.h (__doapl, __doami, __doaml, __doadv): Helper + templates to implement +=, -=, *= and /=, respectively, since + member function templates do not apply to class specializations. + * std/{f,d,ld}complex.h, std/complext.cc, cinst.cc: Adjust. + + * std/bastring.h: The representation class is now a nested class. + * std/bastring.cc: Add templates for static data members. + * sinst.cc: Don't provide specializations for static data members. + * std/string.h: Use default template parameters. + + * Makefile.in (CXXFLAGS): Remove -pedantic -ansi. + (CFLAGS): Ditto. + +Wed Feb 14 14:39:07 1996 Jason Merrill <jason@yorick.cygnus.com> + + * std/bastring.cc (check_realloc): Fix for sizeof (charT) > 1. + From John Hickin <hickin@bnr.ca>. + +Wed Jan 10 11:05:04 1996 Jason Merrill <jason@yorick.cygnus.com> + + * std/bastring.h (insert): Fix iterator handling. + From Joe Buck <jbuck@synopsys.com>. + +Mon Jan 8 11:48:03 1996 Jason Merrill <jason@yorick.cygnus.com> + + * std/bastring.h (max_size): Fix for sizeof (charT) > 1. + * std/bastring.cc (replace): Use it. + + * std/bastring.cc (rfind): Fix for n > length (). + +Tue Dec 19 15:13:08 1995 Jason Merrill <jason@yorick.cygnus.com> + + * config/aix.ml (SHFLAGS): Add -Wl,-unix. + +Mon Dec 18 12:48:25 1995 Mike Stump <mrs@cygnus.com> + + * Makefile.in (exceptioni.o): Compile with -fhandle-exceptions, so + we can unwind through unexpected on machines that don't have a + working __unwind_function. + +Sun Dec 17 00:28:31 1995 Jeffrey A Law (law@cygnus.com) + + * Makefile.in (install): Make sure shared libraries + are installed with mode 555. + +Mon Nov 27 15:01:56 1995 Jason Merrill <jason@yorick.cygnus.com> + + * Makefile.in (install): Make shared library links relative. + (install): Break up -sf into -s -f. + ({M,}SHLINK): Ditto. + +Sun Nov 26 22:48:06 1995 Jason Merrill <jason@yorick.cygnus.com> + + * queue: Include <stack.h> instead of <queue.h>. + +Sat Nov 25 11:33:13 1995 Doug Evans <dje@canuck.cygnus.com> + + * Makefile.in (install): Fix setting of rootme. + +Tue Nov 21 14:20:34 1995 Ian Lance Taylor <ian@cygnus.com> + + * configure.in: Check ${with_cross_host} rather than comparing + ${host} and ${target}. + +Tue Nov 14 01:50:52 1995 Doug Evans <dje@canuck.cygnus.com> + + * Makefile.in (IO_DIR): Delete MULTITOP, MULTISUBDIR. + (LIBIBERTY_DIR): Likewise. + (INSTALLDIR): Delete MULTISUBDIR. + * configure.in: Delete call to cfg-ml-com.in. Call config-ml.in + instead of cfg-ml-pos.in. + (XCXXINCLUDES): Delete MULTITOP. + * stl/configure.in (XCXXINCLUDES): Delete MULTITOP. + (config-ml.in): Call instead of cfg-ml-pos.in. + +Sun Nov 12 16:44:25 1995 Per Bothner <bothner@kalessin.cygnus.com> + + * Makefile.in (VERSION): Set to 2.7.1. + +Thu Nov 9 17:39:28 1995 Jason Merrill <jason@yorick.cygnus.com> + + * config/{aix,dec-osf,irix5,linux,sol2shm}.ml: Remove LDLIBS defn; + no longer needed now that make check sets LD_LIBRARY_PATH. + +Wed Nov 8 19:46:35 1995 Brendan Kehoe <brendan@lisa.cygnus.com> + + * std/bastring.h: Wrap with #ifndef/#define/#endif. + * std/cassert.h: Likewise. + * std/cinst.h: Likewise. + * std/complext.h: Likewise. + * std/dcomplex.h: Likewise. + * std/fcomplex.h: Likewise. + * std/ldcomplex.h: Likewise. + * std/sinst.h: Likewise. + +Wed Nov 8 16:15:48 1995 Jason Merrill <jason@yorick.cygnus.com> + + * std/bastring.cc (getline): Update to September 95 WP. Now we + don't set failbit when reading an empty line. + +Tue Nov 7 16:09:04 1995 Jason Merrill <jason@yorick.cygnus.com> + + * std/bastring.cc (new): Fix for sizeof (charT) != 1. + +Sat Nov 4 17:37:16 1995 Jason Merrill <jason@yorick.cygnus.com> + + * std/complext.cc (operator / (FLOAT, const complex<FLOAT>&)): + Reimplement along the lines of the other operator / templates. + From John Eaton <jwe@bevo.che.wisc.edu>. + +Sat Nov 4 13:33:50 1995 Per Bothner <bothner@kalessin.cygnus.com> + + * configure.in (DISTCLEAN): New, to add target-mkfrag. + +Tue Oct 31 13:59:32 1995 Jason Merrill <jason@yorick.cygnus.com> + + * std/bastring.h: Use size_t for the reference count. + * std/bastring.cc (create): Set selfish. + From Joe Buck (jbuck@synopsys.com). + +Mon Oct 30 23:09:48 1995 Per Bothner <bothner@kalessin.cygnus.com> + + * configure.in: Don't bother changing LIBIBERTY for cross, + now that we are using target-libiberty instead. + * Makefile.in (LIBIBERTY_DIR): Simplify. + (LIBIBERTY): Remove. + +Wed Oct 11 14:56:49 1995 Brendan Kehoe <brendan@lisa.cygnus.com> + + * config/sol2shm.ml: New files with -rpath. + * configure (*-*-solaris*): Use sol2shm.ml. + +Thu Sep 28 09:26:52 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * std/straits.h (compare, copy, move, set): Fix for non-char charT's. + * std/bastring.h (basic_string::remove): Fix for non-char charT's. + +Tue Sep 26 15:22:56 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * config/irix5.ml: Pass -rpath to links. + +Fri Sep 15 00:17:47 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * config/linux.ml: Conform to Linux shared library numbering + scheme. + * Makefile.in: Ditto. + +Tue Sep 12 00:28:56 1995 Mike Stump <mrs@cygnus.com> + + * typeinfoi.cc: (__pointer_type_info::__rtti_match): Moved from + the headerfile, include all sorts of pointer conversions from 15.3 + para 2. + * std/typeinfo.h (__pointer_type_info::__rtti_match): Moved from here. + +Mon Sep 11 23:27:59 1995 Mike Stump <mrs@cygnus.com> + + * std/typeinfo.h (__pointer_type_info::__rtti_match): We no longer + have to dereference the object pointer, as the pointer is always + passed directly. + +Mon Sep 11 19:29:51 1995 Mike Stump <mrs@cygnus.com> + + * std/typeinfo.h (__pointer_type_info::__rtti_match): Define so + that pointer conversions can happen on catch type matching. + * typeinfoi.cc (__throw_type_match_rtti): Arrange for __rtti_match + to be used on pointers. + +Tue Sep 5 14:49:19 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * string.h: Remove for now. + +Thu Aug 31 14:14:01 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * std/bastring.cc (operator>>): Simplify and fix. + (resize): Fix order of arguments to append. + (getline): Simplify and fix. + +Thu Aug 24 17:44:09 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * std/cstdlib.h (abs): Provide default implementation for peons + without labs. + +Tue Aug 22 08:43:07 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * std/cstdlib.h: Comment out definition of div(long,long) for now, + since not all targets have ldiv. + +Mon Aug 21 11:46:03 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * std/cmath.h: Wrap abs(double) with #if ! _G_MATH_H_INLINES. + + * stl.h: Add, for compatibility with ObjectSpace STL. + + * std/complext.cc (operator /): Use abs instead of fabs. + + * std/bastring.h (replace): Update single-character replace method + as per my proposal. + + * std/cmath.h: Add abs(float), abs(double) and abs(long double). + Add commented-out declarations for other float and long double + math functions. + + * std/cstdlib.h: Add abs(long) and div(long,long). + + * Makefile.in (install): Make shared library executable and + non-writable. Tidy. + (OBJS): Add cstdlibi.o and cmathi.o. + + * Rename implementation files to have different basenames. + +Mon Aug 21 00:57:03 1995 Jeffrey A. Law <law@rtl.cygnus.com> + + * Makefile.in (install): Use "cd stl"; no need for $(srcdir) + prefix because we're already in $(srcdir). + +Tue Jul 25 18:41:29 1995 Per Bothner <bothner@kalessin.cygnus.com> + + * std/stddef.h: Remove obsolete definition of enum capacity. + +Sat Jul 22 13:37:01 1995 Doug Evans <dje@canuck.cygnus.com> + + * Makefile.in (IO_DIR): Add multilib support. + (LIBIBERTY, LIBIBERTY_OBJS, INSTALLDIR, stdlist): Likewise. + (libiberty.a, install): Likewise. + * configure.in: Likewise. + (XCXXINCLUDES): Likewise. + * stl/configure.in: Likewise. + (XCXXINCLUDES): Likewise. + +Mon Jul 17 09:29:31 1995 Brendan Kehoe <brendan@lisa.cygnus.com> + + * Makefile.in (typeinfo.o, stdexcept.o): Put an else for the if + stmt checking PICFLAG. + (stmp-string, bigstmp-string, stmp-complex, bigstmp-complex): Likewise. + +Wed Jun 28 17:05:29 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * std/*.h: Wrap with extern "C++". + + * std/ciso646.h: Don't worry about #undefing the keywords. + +Mon Jun 26 19:05:38 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * std/bastring.h (operator!=): If they've included the STL + function.h, don't overload the operator templates that it defines. + +Fri Jun 23 16:54:17 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * Makefile.in (SHLINK): Force link. + (install): Ditto. + + * std/bastring.h (terminate): Never reallocate. + (alloc): No longer const. + + * std/bastring.cc (create): Always allocate an extra byte. + (check_realloc): Always leave room for an extra byte. + (*find*): Add missing 'const'. + + * Makefile.in (SHARLIB): Provide a default value. + +Tue Jun 20 16:29:52 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * std/cstring.h: Don't bother tweaking prototypes for now. When + we do, we will use new-style casts. + +Fri Jun 16 13:57:53 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * Makefile.in (VERSION): Update to 2.7.0. + + * config/aix.ml: Build both shared and archive libraries. + +Wed Jun 14 21:44:21 1995 Jason Merrill <jason@python.cygnus.com> + + * configure.in (frags): Use linux.ml for Linux/ELF. + * config/linux.ml: New file. + +Wed Jun 14 17:56:23 1995 Niclas Andersson <nican@ida.liu.se> + + * configure.in: Use xiberty when building cross-compiler. + +Wed Jun 14 12:57:47 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * std/*complex*, std/cinst.h, cinst.cc: Pass by reference to const + rather than by value. + * std/*complex*: Add member functions real() and imag(). + +Sat Jun 10 12:14:38 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * Makefile.in (bigstmp-string): Call main string object cstrmain.o + instead of cstring.o. + +Wed Jun 7 11:15:15 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * std/cstring.h: Use #include_next to pick up <string.h>. + + * string.h: New file. + + * Makefile.in (MOSTLYCLEAN_JUNK): Remove piclist. + + * configure.in (MOSTLYCLEAN): Remove stamp-picdir. + +Mon Jun 5 18:36:39 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * config/*.ml: Build both shared and archive libraries. + + * configure.in (MOSTLYCLEAN): Remove pic. + (frags): Use toplevel pic frags. + + * Makefile.in (piclist): New rule. + (SHLIB): Use it. + (stl.list): Removed. + (typeinfo.o): Also build pic version. + (stdexcept.o): Ditto. + (*stmp-*): Ditto. + +Tue May 30 12:01:14 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * std/{complext,{f,d,ld}complex}.h: To declare specializations, + use friend declarations in the class body... + * std/cinst.h: ...rather than macro hackery. + + * Makefile.in (stdlist): Renamed from list. + + * cstdarg: Don't define __CSTDARG__. + * complex.h: Similarly. + +Tue May 9 19:31:20 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * std/bastring.cc (operator>>): Use an int to store the return value + of streambuf::sbumpc. + (getline): Ditto. + * std/bastring.* (replace): Reverse size_t and charT arguments. + + * configure.in (enable_shared): Support enable_shared under AIX. + + * Makefile.in (SHARLIB): New variable and rule for building an + archive library containing a single shared object (for AIX). + +Mon May 8 01:43:19 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * std/bastring.h (remove): Forgot one. + (empty): And this. + Disable copy-on-write if someone takes an iterator. + + * std/bastring.cc (getline): Avoid resizing down if unnecessary. + (operator>>): Don't use private methods. + +Sun May 7 02:39:56 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * std/bastring.h (insert, replace): Fix. + * std/bastring.cc (find_*_of): Fix. + +Fri May 5 01:45:10 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * std/bastring.h: Add iterator remove fn. Remove evil default + arguments. + + * std/*complex*, std/cinst.h, cinst.cc: s/__complex/complex/g. + complex<float> is now specialized. Lose _*_complex in favor of + 'explicit' constructors. + * std/complex.h: Lose typedef of complex. + * std/fcomplex.h: New file. + * std/complext.cc (operator<<): Accept more input forms. + + * std/bastring.h: Add iterator insert fns. + +Thu May 4 02:30:04 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * std/bastring.*: Update to current draft. + + * std/bastring.*: Reorganize so that the pointer in a string + object points to the data rather than the bsrep object, for + debugging. + +Tue Apr 25 17:15:09 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * configure.in: Update to stay in sync with config.shared. + +Mon Apr 24 13:08:46 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * std/complext.h: Declare hypot. Declare appropriate functions const. + +Wed Apr 12 15:26:25 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * Makefile.in (typeinfo.o): Don't use $<. + (stdexcept.o): Ditto. + +Sat Apr 8 15:35:00 1995 Mike Stump <mrs@cygnus.com> + + * std/typeinfo.h: Move bad_cast, bad_typeid and __bad_cast_object + from here to stdexcept. + * std/stdexcept.h: Ditto. + * Makefile.in (stdexcept.o): Added rule to build typeinfo.o with + -frtti to support matching of thrown objects with rtti info for + bad_cast. + +Mon Apr 3 18:13:14 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * typeinfo: New file. + + * Makefile.in (HEADERS): Add typeinfo. + +Mon Apr 3 15:06:58 1995 Mike Stump <mrs@cygnus.com> + + * Makefile.in (typeinfo.o): Added rule to build typeinfo.o with + -frtti to support matching of thrown objects with rtti info for + bad_cast. + +Wed Mar 29 15:56:06 1995 Mike Stump <mrs@cygnus.com> + + * typeinfo.cc: (__throw_type_match_rtti): Added to support + matching of thrown objects with rtti info. + +Thu Mar 23 18:42:30 1995 Jason Merrill <jason@deneb.cygnus.com> + + * Makefile.in (HEADERS): Add stdexcept. + +Sun Mar 12 01:25:27 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * std/typeinfo.h: Add return statements to dummy methods. + +Wed Mar 8 16:09:50 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * config/dec-osf.ml: Use -rpath flag. + +Fri Feb 17 18:16:46 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * std/typeinfo.h: Add copyright header. + + * Makefile.in (CXXFLAGS): Add a bunch of warning options to keep + me honest. + +Thu Feb 16 00:04:49 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * Makefile.in, config/*.ml: Generate shared library on most hosts + as libstdc++.so.$(VERSION), with a symlink to libstdc++.so, so that + multiple versions can coexist. + +Fri Feb 10 02:59:39 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * std/exception.h: {set_,}{terminate,unexpected} have C++ linkage. + + * Makefile.in: Allow string and complex to be split up either by + individual function or into I/O and non-I/O. Default to the + latter. + +Wed Feb 8 02:39:47 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * std/bastring.h: Start thinking about throwing exceptions. + + * typeinfo.cc: Remove private functions; defining them to call + abort () just delays errors until runtime. Define + __bad_cast_object. + + * std/exception.h: Standard exceptions are now defined in + stdexcept.h. This header now contains declarations of terminate() + et al. + * exception.cc: Move code from libg++/src/except.c here. + * std/typeinfo.h: Define RTTI-related exceptions here. + * stdexcept{,.cc},std/stdexcept.h: New files. + +Mon Feb 6 18:51:31 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * Makefile.in (HEADERS): Resurrect, add new STL header names. + (install): Install extensionless headers again. + * extensionless headers: Resurrect, add new STL headers. + Currently only forward to std/whatever or stl/whatever. + +Mon Jan 30 13:53:22 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * std/bastring.h (basic_string (charT, size_t)): Mark explicit. + + * Makefile.in (install): Set rootme when installing stl headers. + Only install *.* from std. + +Wed Jan 25 02:29:30 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * std/bastring.h (operator=): grab before releasing. + +Mon Jan 23 19:54:02 1995 Ronald F. Guilmette <rfg@segfault.us.com> + + * Makefile.in (install): Also install STL headers. + +Mon Jan 23 04:09:35 1995 Jason Merrill <jason@python.cygnus.com> + + * Makefile.in (list): Set $rootme before calling make. + +Wed Jan 11 19:24:47 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * typeinfo.cc (__rtti_match): Don't try to do pointer arithmetic + with a void *. + + * move all headers into std subdirectory and update files accordingly. + +Thu Jan 5 01:51:49 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * bastring.ccI (basic_string (size_t, capacity)): s/reserve/::reserve/. + +Wed Jan 4 17:27:32 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * exception: s/string/__string/g. + + * configure.in (MOSTLYCLEAN): Add so_locations. + + * bastring.ccI (basic_string (size_t, capacity)): Fix thinko. + (various find functions): Ditto. + +Fri Dec 30 18:04:00 1994 Mike Stump <mrs@cygnus.com> + + * typeinfo.h: Add support for the built-in type bool. + +Fri Dec 30 14:57:02 1994 Mike Stump <mrs@cygnus.com> + + * typeinfo.{cc, h}: Guard against multiple inclusions, and add #p i/i. + +Fri Dec 2 17:56:05 1994 Mike Stump <mrs@cygnus.com> + + * libg++ 2.6.2 released. + + * typeinfo.{cc, h} (__rtti_match): Change interface to compiler + for dynamic_casting to gear up for exception handling's use of + rtti for argument matching. + +Tue Nov 29 16:49:32 1994 Per Bothner <bothner@kalessin.cygnus.com> + + * configure.in (configdirs): Add stl. + * Makefile.in: Build stl, and merge .o files from it. + +Thu Nov 17 15:30:57 1994 Jason Merrill <jason@phydeaux.cygnus.com> + + * bastring.hI: Add iterator, const_iterator, begin() and end() to + basic_string. + +Mon Nov 7 16:50:33 1994 Jason Merrill <jason@phydeaux.cygnus.com> + + * Makefile.in, configure.in, config/*.ml, tests/Makefile.in, + tests/configure.in: Various changes to handle --enable-shared. + +Fri Nov 4 19:13:33 1994 Mike Stump <mrs@cygnus.com> + + * exception{,.cc}: Added to support catching bad_cast's. + +Thu Nov 3 17:42:13 1994 Mike Stump <mrs@cygnus.com> + + * typeinfo.h (type_info::{name, before}): Add to match draft. + +Thu Nov 3 00:56:34 1994 Jason Merrill (jason@phydeaux.cygnus.com) + + * Makefile.in (LIBIBERTY_OBJS): Add strerror.o. + +Mon Oct 31 15:33:06 1994 Kung Hsu (kung@mexican.cygnus.com) + + * typeinfo.cc: Fix a bug in the final return. + * typeinfo.cc: Fix the ANSI header version number. + * typeinfo.h: ditto. + +Fri Oct 28 14:23:12 1994 Mike Stump <mrs@cygnus.com> + + * type_info.{cc,h}: Rename to typeinfo to better match current draft. + +Wed Oct 26 11:13:53 1994 Kung Hsu (kung@mexican.cygnus.com) + + * type_info.h: new header file for rtti. + * type_info.cc: new code file for rtti. + * Makefile.in: change to include type_info.o in libstdc++ for rtti. + +Sat Oct 15 16:09:51 1994 Jason Merrill (jason@phydeaux.cygnus.com) + + * libg++ 2.6.1 released. + + * cinst.hI: Also declare instantiations of out-of-line functions. + +Fri Oct 14 15:00:09 1994 Jason Merrill (jason@phydeaux.cygnus.com) + + * configure.in (CXXINCLUDES): Use {} to wrap variable name. + * tests/configure.in (CXXINCLUDES): Ditto. + + * cinst.hI: Declare instantiations of two-argument functions so + overload resolution will work. + * complext.hI: Always include cinst.hI. + + * bastring.ccI (operator>>): Tweak. + +Tue Oct 11 17:07:49 1994 Jason Merrill (jason@phydeaux.cygnus.com) + + * stddef*: Do the #pragma i/i thang. + + * bastring.hI (basic_string::put_at): Use operator[]. + (basic_string::terminate): Don't necessarily copy the rep. + + * bastring.ccI (operator>>): Avoid shrinking and then re-expanding + the string. + + * bastring.*I, sinst.cc: Only allow allocation policy control if + _G_ALLOC_CONTROL is defined. + + * Makefile.in (libstdc++.a): Depend on iostream.list and libiberty.a. + (../libio/iostream.list): New rule. + (../libiberty/libiberty.a): New rule. + (OBJS): Add stddef.o. + +Sat Oct 8 23:59:45 1994 Jason Merrill (jason@phydeaux.cygnus.com) + + * *: First checkin. diff --git a/contrib/libstdc++/Makefile.in b/contrib/libstdc++/Makefile.in new file mode 100644 index 0000000..77e2ec9 --- /dev/null +++ b/contrib/libstdc++/Makefile.in @@ -0,0 +1,322 @@ +# Copyright (C) 1994, 1995 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. + +VERSION = 2.9.0 + +OBJS = cstringi.o stdexcepti.o cstdlibi.o cmathi.o stlinst.o +SUBLIBS = $(STAMP)-string $(STAMP)-complx + +# C++ headers with no extension +HEADERS= cassert cctype cerrno cfloat ciso646 climits clocale cmath complex \ + csetjmp csignal cstdarg cstddef cstdio cstdlib cstring ctime \ + cwchar cwctype string stdexcept \ + algorithm deque functional hash_map hash_set iterator list map \ + memory numeric pthread_alloc queue rope set slist stack utility \ + vector fstream iomanip iostream strstream iosfwd + +ARLIB = libstdc++.a +SHLIB = libstdc++.so.$(VERSION) +SHARLIB = libstdc++-sh.a +SHLINK = libstdc++.so +MSHLINK = libstdc++.so.`echo $(VERSION) | sed 's/\([0-9][.][0-9]\).*/\1/'` +SHFLAGS = +SHDEPS = + +STAMP = bigstmp + +LIBS = $(ARLIB) + +#### package, host, target, and site dependent Makefile fragments come in here. +## + +IO_DIR = ../libio +LIBIBERTY_DIR = ../libiberty + +LIBIBERTY_OBJS = `cat $(LIBIBERTY_DIR)/needed-list` strerror.o + +tooldir = $(exec_prefix)/$(target) +# This is where the libraries will be installed; note, it will be set +# at make runtime now. See below at target install. +INSTALLDIR = $(libdir) + +MOSTLYCLEAN_JUNK = *stmp-* tlib*.a *.s *.ii stdlist piclist +CLEAN_JUNK = $(LIBS) + +.PHONY: libs +libs: $(LIBS) + +stdlist: $(IO_DIR)/iostream.list $(OBJS) $(SUBLIBS) $(LIBIBERTY_DIR)/libiberty.a + -rm -f tlist + touch tlist + echo *.o >> tlist + for f in `cat $(IO_DIR)/iostream.list` ; do \ + echo "$(IO_DIR)/$$f" >> tlist ; \ + done + for f in $(LIBIBERTY_OBJS) ; do \ + echo "$(LIBIBERTY_DIR)/$$f" >> tlist ; \ + done + mv tlist stdlist + +piclist: stdlist + -rm -f tlist + cp stdlist tlist + if [ x"$(enable_shared)" = xyes ]; then \ + sed 's,\([A-Za-z_]*\.o\),pic/\1,g' tlist > tlist2 ; \ + mv tlist2 tlist ; \ + else true ; fi + mv tlist piclist + +$(ARLIB): stdlist + -rm -f t$(ARLIB) + $(AR) $(AR_FLAGS) t$(ARLIB) `cat stdlist` + mv t$(ARLIB) $(ARLIB) + $(RANLIB) $(ARLIB) + +$(SHLIB): piclist + $(CC) $(LIBCXXFLAGS) $(SHFLAGS) -shared -o $(SHLIB) `cat piclist` $(SHDEPS) + +$(SHARLIB): $(SHLIB) + -rm -f t$(SHARLIB) + $(AR) $(AR_FLAGS) t$(SHARLIB) $(SHLIB) + mv t$(SHARLIB) $(SHARLIB) + $(RANLIB) $(SHARLIB) + +$(SHLINK): + ln -f -s $(SHLIB) $(SHLINK) + +mshlink: + @$(MAKE) $(MSHLINK) "SHLINK=$(MSHLINK)" + +$(IO_DIR)/iostream.list: force + cd $(IO_DIR) ; $(MAKE) $(FLAGS_TO_PASS) iostream.list + +$(LIBIBERTY_DIR)/libiberty.a: + cd $(LIBIBERTY_DIR) ; $(MAKE) $(FLAGS_TO_PASS) + +STRFUNCS = 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 +STRIO = EXTRACT INSERT GETLINE + +# These are here for SunOS VPATH. +cstringi.o: cstringi.cc +cstdlibi.o: cstdlibi.cc +cmathi.o: cmathi.cc +stdexcepti.o: stdexcepti.cc +stlinst.o: stlinst.cc + +# Later do wide strings, too. +stmp-string: ${srcdir}/sinst.cc ${srcdir}/std/bastring.h \ + ${srcdir}/std/bastring.cc ${srcdir}/std/straits.h + for name in $(STRFUNCS) $(STRIO); do \ + echo c$${name}; \ + if [ x"$(enable_shared)" = xyes ]; then \ + $(COMPILE.cc) $(PICFLAG) -DC -D$${name} ${srcdir}/sinst.cc \ + -o pic/c$${name}.o; \ + else true ; fi; \ + if [ $$? -eq 0 ]; then true; else exit 1; fi; \ + $(COMPILE.cc) -DC -D$${name} ${srcdir}/sinst.cc -o c$${name}.o; \ + if [ $$? -eq 0 ]; then true; else exit 1; fi; \ + done + touch stmp-string + +bigstmp-string: ${srcdir}/sinst.cc ${srcdir}/std/bastring.h \ + ${srcdir}/std/bastring.cc ${srcdir}/std/straits.h + echo cstring + if [ x"$(enable_shared)" = xyes ]; then \ + $(COMPILE.cc) $(PICFLAG) -DC \ + `for N in $(STRFUNCS); do echo " -D$${N}"; done` \ + $(srcdir)/sinst.cc -o pic/cstrmain.o; \ + else true ; fi + $(COMPILE.cc) -DC `for N in $(STRFUNCS); do echo " -D$${N}"; done` \ + $(srcdir)/sinst.cc -o cstrmain.o + echo cstrio + if [ x"$(enable_shared)" = xyes ]; then \ + $(COMPILE.cc) $(PICFLAG) -DC \ + `for N in $(STRIO); do echo " -D$${N}"; done` \ + $(srcdir)/sinst.cc -o pic/cstrio.o; \ + else true ; fi + $(COMPILE.cc) -DC `for N in $(STRIO); do echo " -D$${N}"; done` \ + $(srcdir)/sinst.cc -o cstrio.o + touch bigstmp-string + +COMFUNCS = 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 +COMIO = EXTRACT INSERT + +stmp-complx: ${srcdir}/cinst.cc ${srcdir}/std/complext.h \ + ${srcdir}/std/complext.cc ${srcdir}/std/dcomplex.h \ + ${srcdir}/std/ldcomplex.h + for N in $(COMFUNCS) $(COMIO); do \ + echo f$${N}; \ + if [ x"$(enable_shared)" = xyes ]; then \ + $(COMPILE.cc) $(PICFLAG) -DF -D$${N} $(srcdir)/cinst.cc \ + -o pic/f$${N}.o; \ + else true ; fi; \ + if [ $$? -eq 0 ]; then true; else exit 1; fi; \ + $(COMPILE.cc) -DF -D$${N} ${srcdir}/cinst.cc -o f$${N}.o; \ + if [ $$? -eq 0 ]; then true; else exit 1; fi; \ + echo d$${N}; \ + if [ x"$(enable_shared)" = xyes ]; then \ + $(COMPILE.cc) $(PICFLAG) -DD -D$${N} $(srcdir)/cinst.cc \ + -o pic/d$${N}.o; \ + else true ; fi; \ + if [ $$? -eq 0 ]; then true; else exit 1; fi; \ + $(COMPILE.cc) -DD -D$${N} ${srcdir}/cinst.cc -o d$${N}.o; \ + if [ $$? -eq 0 ]; then true; else exit 1; fi; \ + echo ld$${N}; \ + if [ x"$(enable_shared)" = xyes ]; then \ + $(COMPILE.cc) $(PICFLAG) -DLD -D$${N} $(srcdir)/cinst.cc \ + -o pic/ld$${N}.o; \ + else true ; fi; \ + if [ $$? -eq 0 ]; then true; else exit 1; fi; \ + $(COMPILE.cc) -DLD -D$${N} ${srcdir}/cinst.cc -o ld$${N}.o; \ + if [ $$? -eq 0 ]; then true; else exit 1; fi; \ + done + touch stmp-complx + +bigstmp-complx: ${srcdir}/cinst.cc ${srcdir}/std/complext.h \ + ${srcdir}/std/complext.cc ${srcdir}/std/dcomplex.h \ + ${srcdir}/std/ldcomplex.h + echo fcomplex + if [ x"$(enable_shared)" = xyes ]; then \ + $(COMPILE.cc) $(PICFLAG) -DF \ + `for N in $(COMFUNCS); do echo " -D$${N}"; done` \ + $(srcdir)/cinst.cc -o pic/fcomplex.o; \ + else true ; fi + $(COMPILE.cc) -DF `for N in $(COMFUNCS); do echo " -D$${N}"; done` \ + $(srcdir)/cinst.cc -o fcomplex.o + echo fcomio + if [ x"$(enable_shared)" = xyes ]; then \ + $(COMPILE.cc) $(PICFLAG) -DF \ + `for N in $(COMIO); do echo " -D$${N}"; done` \ + $(srcdir)/cinst.cc -o pic/fcomio.o; \ + else true ; fi + $(COMPILE.cc) -DF `for N in $(COMIO); do echo " -D$${N}"; done` \ + $(srcdir)/cinst.cc -o fcomio.o + echo dcomplex + if [ x"$(enable_shared)" = xyes ]; then \ + $(COMPILE.cc) $(PICFLAG) -DD \ + `for N in $(COMFUNCS); do echo " -D$${N}"; done` \ + $(srcdir)/cinst.cc -o pic/dcomplex.o; \ + else true ; fi + $(COMPILE.cc) -DD `for N in $(COMFUNCS); do echo " -D$${N}"; done` \ + $(srcdir)/cinst.cc -o dcomplex.o + echo dcomio + if [ x"$(enable_shared)" = xyes ]; then \ + $(COMPILE.cc) $(PICFLAG) -DD \ + `for N in $(COMIO); do echo " -D$${N}"; done` \ + $(srcdir)/cinst.cc -o pic/dcomio.o; \ + else true ; fi + $(COMPILE.cc) -DD `for N in $(COMIO); do echo " -D$${N}"; done` \ + $(srcdir)/cinst.cc -o dcomio.o + echo ldcomplex + if [ x"$(enable_shared)" = xyes ]; then \ + $(COMPILE.cc) $(PICFLAG) -DLD \ + `for N in $(COMFUNCS); do echo " -D$${N}"; done` \ + $(srcdir)/cinst.cc -o pic/ldcomplex.o; \ + else true ; fi + $(COMPILE.cc) -DLD `for N in $(COMFUNCS); do echo " -D$${N}"; done` \ + $(srcdir)/cinst.cc -o ldcomplex.o + echo ldcomio + if [ x"$(enable_shared)" = xyes ]; then \ + $(COMPILE.cc) $(PICFLAG) -DLD \ + `for N in $(COMIO); do echo " -D$${N}"; done` \ + $(srcdir)/cinst.cc -o pic/ldcomio.o; \ + else true ; fi + $(COMPILE.cc) -DLD `for N in $(COMIO); do echo " -D$${N}"; done` \ + $(srcdir)/cinst.cc -o ldcomio.o + touch bigstmp-complx + +.PHONY: install +install: + rootme=`pwd`/ ; export rootme ; \ + if [ -z "$(MULTISUBDIR)" ]; then \ + cd $(srcdir); \ + for FILE in $(HEADERS); do \ + rm -f $(gxx_include_dir)/$$FILE ; \ + if [ -f stl/$$FILE ]; then \ + $(INSTALL_DATA) stl/$$FILE $(gxx_include_dir)/$$FILE ; \ + else \ + $(INSTALL_DATA) $$FILE $(gxx_include_dir)/$$FILE ; \ + fi ; \ + chmod a-x $(gxx_include_dir)/$$FILE ; \ + done ; \ + for FILE in *.h std/*.*; do \ + rm -f $(gxx_include_dir)/$$FILE ; \ + $(INSTALL_DATA) $$FILE $(gxx_include_dir)/$$FILE ; \ + chmod a-x $(gxx_include_dir)/$$FILE ; \ + done ; \ + cd stl; \ + for FILE in *.h; do \ + rm -f $(gxx_include_dir)/$$FILE ; \ + $(INSTALL_DATA) $$FILE $(gxx_include_dir)/$$FILE ; \ + chmod a-x $(gxx_include_dir)/$$FILE ; \ + done ; \ + else true ; \ + fi + rootme=`pwd`/ ; export rootme ; \ + if [ x$(libsubdir) = x ] || [ x$(enable_version_specific_runtime_libs) != xyes ]; then \ + INSTALLDIR=$(libdir); \ + else \ + INSTALLDIR=$(libsubdir); \ + fi; \ + rm -f $${INSTALLDIR}$(MULTISUBDIR)/$(SHLINK) ; \ + for FILE in $(LIBS) ; do \ + rm -f $${INSTALLDIR}$(MULTISUBDIR)/$$FILE ; \ + if [ $$FILE = $(SHLINK) ] ; then \ + ln -f -s $(SHLIB) $${INSTALLDIR}$(MULTISUBDIR)/$$FILE ; \ + elif [ $$FILE = mshlink ]; then \ + for FILE in $(MSHLINK) ; do \ + rm -f $${INSTALLDIR}$(MULTISUBDIR)/$$FILE ; \ + ln -f -s $(SHLIB) $${INSTALLDIR}$(MULTISUBDIR)/$$FILE ; \ + done; \ + elif [ $$FILE = $(SHLIB) ]; then \ + $(INSTALL_PROGRAM) $$FILE $${INSTALLDIR}$(MULTISUBDIR)/$$FILE ; \ + : On the HP, shared libraries must be mode 555. ;\ + chmod 555 $${INSTALLDIR}$(MULTISUBDIR)/$$FILE ; \ + else \ + $(INSTALL_DATA) $$FILE $${INSTALLDIR}$(MULTISUBDIR)/$$FILE ; \ + $(RANLIB) $${INSTALLDIR}$(MULTISUBDIR)/$$FILE ; \ + chmod a-x $${INSTALLDIR}$(MULTISUBDIR)/$$FILE ; \ + fi ; \ + done + @rootme=`pwd`/ ; export rootme ; \ + $(MULTIDO) $(FLAGS_TO_PASS) multi-do DO=install + +.PHONY: force +force: + +# Remove these for public releases. +MYCXXFLAGS = -g -O2 -Wpointer-arith -Wnested-externs -Woverloaded-virtual -Wbad-function-cast -Winline -Wwrite-strings +MYCFLAGS = -g -O2 -Wpointer-arith -Wnested-externs + +.PHONY: stuff +stuff: + $(MAKE) stuff1 + $(MAKE) stuff2 + +stuff1: + $(MAKE) clean + $(MAKE) -C ../libio c++clean + touch ../../gcc/libgcc2.ready + +stuff2: + -$(MAKE) -C ../../gcc/ libgcc.a + -$(MAKE) check CXXFLAGS="$(MYCXXFLAGS)" CFLAGS="$(MYCFLAGS)" + -$(MAKE) -C ../libio check + -$(MAKE) -C ../../gcc check-g++ diff --git a/contrib/libstdc++/NEWS b/contrib/libstdc++/NEWS new file mode 100644 index 0000000..89e866e --- /dev/null +++ b/contrib/libstdc++/NEWS @@ -0,0 +1,9 @@ +SUMMARY OF RECENT MAJOR CHANGES to LIBSTDC++. +(Also check ../libio/NEWS.) + +*** Noteworthy changes in libstdc++ for EGCS + +* EGCS includes the SGI STL implementation without changes. + +* As a result of these and other changes, libstc++ for EGCS is not binary + compatible with previous releases of libstdc++. diff --git a/contrib/libstdc++/cassert b/contrib/libstdc++/cassert new file mode 100644 index 0000000..b4165bf --- /dev/null +++ b/contrib/libstdc++/cassert @@ -0,0 +1,7 @@ +// -*- C++ -*- forwarding header. +// This file is part of the GNU ANSI C++ Library. + +#ifndef __CASSERT__ +#define __CASSERT__ +#include <assert.h> +#endif diff --git a/contrib/libstdc++/cctype b/contrib/libstdc++/cctype new file mode 100644 index 0000000..e2765ae --- /dev/null +++ b/contrib/libstdc++/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 <ctype.h> +#endif diff --git a/contrib/libstdc++/cerrno b/contrib/libstdc++/cerrno new file mode 100644 index 0000000..ce49346 --- /dev/null +++ b/contrib/libstdc++/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 <errno.h> +#endif diff --git a/contrib/libstdc++/cfloat b/contrib/libstdc++/cfloat new file mode 100644 index 0000000..cf59ead --- /dev/null +++ b/contrib/libstdc++/cfloat @@ -0,0 +1,7 @@ +// -*- C++ -*- forwarding header. +// This file is part of the GNU ANSI C++ Library. + +#ifndef __CFLOAT__ +#define __CFLOAT__ +#include <float.h> +#endif diff --git a/contrib/libstdc++/cinst.cc b/contrib/libstdc++/cinst.cc new file mode 100644 index 0000000..010f3ca --- /dev/null +++ b/contrib/libstdc++/cinst.cc @@ -0,0 +1,155 @@ +// 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 <std/complext.cc> + +typedef complex<f> c; +typedef const c& ccr; + +#ifdef MAIN +template class complex<f>; +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<f>&); +#endif +#ifdef INSERT +template ostream& operator<< (ostream&, const complex<f>&); +#endif diff --git a/contrib/libstdc++/ciso646 b/contrib/libstdc++/ciso646 new file mode 100644 index 0000000..4d8200d --- /dev/null +++ b/contrib/libstdc++/ciso646 @@ -0,0 +1,7 @@ +// -*- C++ -*- forwarding header. +// This file is part of the GNU ANSI C++ Library. + +#ifndef __CISO646__ +#define __CISO646__ +#include <iso646.h> +#endif diff --git a/contrib/libstdc++/climits b/contrib/libstdc++/climits new file mode 100644 index 0000000..1b29b3a --- /dev/null +++ b/contrib/libstdc++/climits @@ -0,0 +1,7 @@ +// -*- C++ -*- forwarding header. +// This file is part of the GNU ANSI C++ Library. + +#ifndef __CLIMITS__ +#define __CLIMITS__ +#include <limits.h> +#endif diff --git a/contrib/libstdc++/clocale b/contrib/libstdc++/clocale new file mode 100644 index 0000000..b67cf31 --- /dev/null +++ b/contrib/libstdc++/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 <locale.h> +#endif diff --git a/contrib/libstdc++/cmath b/contrib/libstdc++/cmath new file mode 100644 index 0000000..b18ea0b --- /dev/null +++ b/contrib/libstdc++/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 <math.h> + +#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/contrib/libstdc++/cmathi.cc b/contrib/libstdc++/cmathi.cc new file mode 100644 index 0000000..afd740f --- /dev/null +++ b/contrib/libstdc++/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 <cmath> diff --git a/contrib/libstdc++/complex b/contrib/libstdc++/complex new file mode 100644 index 0000000..bfdd352 --- /dev/null +++ b/contrib/libstdc++/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 <std/complext.h> + +extern "C++" { +#define __STD_COMPLEX + +// ANSI complex types +typedef complex<float> float_complex; +typedef complex<double> double_complex; +typedef complex<long double> long_double_complex; +} + +#endif diff --git a/contrib/libstdc++/complex.h b/contrib/libstdc++/complex.h new file mode 100644 index 0000000..2e88de8 --- /dev/null +++ b/contrib/libstdc++/complex.h @@ -0,0 +1,6 @@ +// -*- C++ -*- backward compatiblity header. +// Copyright (C) 1994 Free Software Foundation + +#ifndef __COMPLEX_H__ +#include <complex> +#endif diff --git a/contrib/libstdc++/config/aix.ml b/contrib/libstdc++/config/aix.ml new file mode 100644 index 0000000..cd96870 --- /dev/null +++ b/contrib/libstdc++/config/aix.ml @@ -0,0 +1,8 @@ +# AIX has wierd shared/non-shared libraries. + +ARLIB = libstdc++-ar.a +SHLINK = libstdc++.a +LIBS = $(ARLIB) $(SHLIB) $(SHLINK) +DEPLIBS = ../$(SHLIB) +SHDEPS = -lm +SHFLAGS = -Wl,-unix diff --git a/contrib/libstdc++/config/dec-osf.ml b/contrib/libstdc++/config/dec-osf.ml new file mode 100644 index 0000000..618c6c8 --- /dev/null +++ b/contrib/libstdc++/config/dec-osf.ml @@ -0,0 +1,6 @@ +# We don't need -fpic on the alpha, so let's install both the shared and +# non-shared versions. + +LIBS = $(ARLIB) $(SHLIB) $(SHLINK) +DEPLIBS = ../$(SHLIB) +SHDEPS = -lm diff --git a/contrib/libstdc++/config/delta.mt b/contrib/libstdc++/config/delta.mt new file mode 100644 index 0000000..b0b36db --- /dev/null +++ b/contrib/libstdc++/config/delta.mt @@ -0,0 +1,2 @@ +# If FPU instructions are generated by default, we have to use a special libm.a +MLDLIBS = $(LDLIBS) `case "$(CXXFLAGS)" in *-m68000* | *-mc68000* | *-msoft-float* ) echo -lm ;; * ) echo -lm881 ;; esac` diff --git a/contrib/libstdc++/config/elf.ml b/contrib/libstdc++/config/elf.ml new file mode 100644 index 0000000..2a5f336 --- /dev/null +++ b/contrib/libstdc++/config/elf.ml @@ -0,0 +1,8 @@ +# Elf without shared libm -- we have to link with the archive library, even +# for programs that don't use complex. + +LIBS = $(ARLIB) $(SHLIB) $(SHLINK) +SHFLAGS = -h $(SHLIB) +DEPLIBS = ../$(SHLIB) +LDLIBS = -L.. -lstdc++ -lm +MLDLIBS = -L.. -lstdc++ -lm diff --git a/contrib/libstdc++/config/elfshlibm.ml b/contrib/libstdc++/config/elfshlibm.ml new file mode 100644 index 0000000..fe2bf3f --- /dev/null +++ b/contrib/libstdc++/config/elfshlibm.ml @@ -0,0 +1,6 @@ +# Elf with shared libm, so we can link it into the shared libstdc++. + +LIBS = $(ARLIB) $(SHLIB) $(SHLINK) +SHFLAGS = -h $(SHLIB) +SHDEPS = -lm +DEPLIBS = ../$(SHLIB) diff --git a/contrib/libstdc++/config/hpux.ml b/contrib/libstdc++/config/hpux.ml new file mode 100644 index 0000000..1531fe8 --- /dev/null +++ b/contrib/libstdc++/config/hpux.ml @@ -0,0 +1,6 @@ +# HPUX uses the .sl suffix for shared libraries. + +SHLIB = libstdc++.sl +LIBS = $(ARLIB) $(SHLIB) +DEPLIBS = ../$(SHLIB) +SHFLAGS = $(PICFLAG) diff --git a/contrib/libstdc++/config/irix5.ml b/contrib/libstdc++/config/irix5.ml new file mode 100644 index 0000000..6b33445 --- /dev/null +++ b/contrib/libstdc++/config/irix5.ml @@ -0,0 +1,6 @@ +# We don't need -fpic on IRIX, so let's install both the shared and +# non-shared versions. + +LIBS = $(ARLIB) $(SHLIB) $(SHLINK) +DEPLIBS = ../$(SHLIB) +SHDEPS = -lm diff --git a/contrib/libstdc++/config/linux.ml b/contrib/libstdc++/config/linux.ml new file mode 100644 index 0000000..7e6eece --- /dev/null +++ b/contrib/libstdc++/config/linux.ml @@ -0,0 +1,6 @@ +# Elf with shared libm, so we can link it into the shared libstdc++. + +LIBS = $(ARLIB) $(SHLIB) $(SHLINK) mshlink +SHFLAGS = -Wl,-soname,$(MSHLINK) +SHDEPS = -lm +DEPLIBS = ../$(SHLIB) diff --git a/contrib/libstdc++/config/linux.mt b/contrib/libstdc++/config/linux.mt new file mode 100644 index 0000000..5848851 --- /dev/null +++ b/contrib/libstdc++/config/linux.mt @@ -0,0 +1,2 @@ +# tell we want the mt-safe version +MT_CFLAGS = -D_IO_MTSAFE_IO diff --git a/contrib/libstdc++/config/openbsd.ml b/contrib/libstdc++/config/openbsd.ml new file mode 100644 index 0000000..0d278f6 --- /dev/null +++ b/contrib/libstdc++/config/openbsd.ml @@ -0,0 +1,7 @@ +# Base shared lib for OpenBSD i386 + +LIBS = $(ARLIB) $(SHLIB) $(SHLINK) mshlink +SHFLAGS = -nostdlib -Wl,-Bshareable,-Bforcearchive +SHDEPS = -lm +DEPLIBS = ../$(SHLIB) + diff --git a/contrib/libstdc++/config/openbsd.mt b/contrib/libstdc++/config/openbsd.mt new file mode 100644 index 0000000..29da11c --- /dev/null +++ b/contrib/libstdc++/config/openbsd.mt @@ -0,0 +1,3 @@ +# tell we want the mt-safe version +MT_CFLAGS = -D_IO_MTSAFE_IO -D_PTHREADS + diff --git a/contrib/libstdc++/config/sol2shm.ml b/contrib/libstdc++/config/sol2shm.ml new file mode 100644 index 0000000..f02650c --- /dev/null +++ b/contrib/libstdc++/config/sol2shm.ml @@ -0,0 +1,6 @@ +# Solaris2 with shared libm, so we can link it into the shared libstdc++. + +LIBS = $(ARLIB) $(SHLIB) $(SHLINK) +SHFLAGS = -h $(SHLIB) +SHDEPS = -lm +DEPLIBS = ../$(SHLIB) diff --git a/contrib/libstdc++/config/sunos4.ml b/contrib/libstdc++/config/sunos4.ml new file mode 100644 index 0000000..0abc13c --- /dev/null +++ b/contrib/libstdc++/config/sunos4.ml @@ -0,0 +1,9 @@ +# SunOS doesn't provide a shared libm, so we have to link with the archive +# library, even for programs that don't use complex. +# SunOS requires a version number in shared library filenames. + +LIBS = $(ARLIB) $(SHLIB) +SHFLAGS = $(PICFLAG) +DEPLIBS = ../$(SHLIB) +LDLIBS = -L.. -lstdc++ -lm +MLDLIBS = -L.. -lstdc++ -lm diff --git a/contrib/libstdc++/configure.in b/contrib/libstdc++/configure.in new file mode 100644 index 0000000..204d4a8 --- /dev/null +++ b/contrib/libstdc++/configure.in @@ -0,0 +1,119 @@ +# This file is a shell script fragment that supplies the information +# necessary for a configure script to process the program in +# this directory. For more information, look at ../configure. + +if [ "${srcdir}" = "." ] ; then + if [ "${with_target_subdir}" != "." ] ; then + topsrcdir=${with_multisrctop}../.. + else + topsrcdir=${with_multisrctop}.. + fi +else + topsrcdir=${srcdir}/.. +fi + +if [ -d ${topsrcdir}/gcc ] ; then + configdirs="tests testsuite" +else + configdirs="tests" +fi +srctrigger=sinst.cc +srcname="ANSI C++ library" +package_makefile_frag=Make.pack +package_makefile_rules_frag=Make.pack.r + +# per-host: + +# per-target: + +echo "# Warning: this fragment is automatically generated" > temp.mt +frags= + +# If they didn't specify --enable-shared, don't generate shared libs. +case "${enable_shared}" in + yes) shared=yes ;; + no) shared=no ;; + *libstdc++*) shared=yes ;; + *) shared=no ;; +esac + +if [ "${shared}" = "yes" ]; then + case "${target}" in + hppa*-*-*) frags=../../config/mh-papic ;; + i[3456]86-*-*) frags=../../config/mh-x86pic ;; + alpha*-*-linux*) frags=../../config/mh-elfalphapic ;; + + # There doesn't seem to be a simpler way to say all-ppc except AIX + *-*-aix*) ;; + powerpc*-* | ppc*-*) frags=../../config/mh-ppcpic ;; + + *-*-*) frags=../../config/mh-${target_cpu}pic ;; + esac + case "${target}" in + *-dec-osf*) frags="${frags} dec-osf.ml";; + *-*-hpux*) frags="${frags} hpux.ml" ;; + *-*-irix[56]*) frags="${frags} irix5.ml" ;; + *-*-linux*aout*) ;; + *-*-linux*) frags="${frags} linux.ml" ;; + *-*-openbsd*) frags="${frags} openbsd.ml" ;; + *-*-sysv4*) frags="${frags} elf.ml" ;; + *-*-solaris*) frags="${frags} sol2shm.ml" ;; + *-*-sunos4*) frags="${frags} sunos4.ml" ;; + *-*-aix*) frags="${frags} aix.ml" ;; + esac +fi + +# Make sure the right flags are defined for multi-threading. +case "${target}" in + alpha*-*-linux-gnulibc1) frags="${frags} linux.mt" ;; + powerpc*-*-linux-gnulibc1) frags="${frags} linux.mt" ;; + *-*-linux-gnu) frags="${frags} linux.mt" ;; + *-*-openbsd*) + case "x${enable_threads}" in + xyes|xposix) frags="${frags} openbsd.mt" ;; + esac;; + m68k-motorola-sysv) frags="${frags} delta.mt" ;; +esac + +for frag in ${frags}; do + case ${frag} in + ../* ) + if [ ${srcdir} = . ]; then + [ -n "${with_target_subdir}" ] && frag=../${frag} + [ -n "${with_multisrctop}" ] && frag=${with_multisrctop}${frag} + fi + ;; + esac + frag=${srcdir}/config/$frag + if [ -f ${frag} ]; then + echo "Appending ${frag} to target-mkfrag" + echo "# Following fragment copied from ${frag}" >> temp.mt + cat ${frag} >> temp.mt + fi +done + +target_makefile_frag=target-mkfrag +${moveifchange} temp.mt target-mkfrag + +LIBDIR=yes +TO_TOPDIR=../ +ALL='libs' +XCXXINCLUDES="-I${srcdir} -I${srcdir}/stl -I${TO_TOPDIR}libio -I${srcdir}/${TO_TOPDIR}libio" +MOSTLYCLEAN='*.o pic stamp-picdir core so_locations $(MOSTLYCLEAN_JUNK)' +CLEAN='$(CLEAN_JUNK)' +EXTRA_DISTCLEAN='target-mkfrag' + +(. ${srcdir}/${TO_TOPDIR}libio/config.shared) >${package_makefile_frag} 2>${package_makefile_rules_frag} + +# post-target: + +# If cross-compiling, we install in $(tooldir). +if [ -n "${with_cross_host}" ] ; then + rm -f Makefile.tem + sed \ + -e 's|\(INSTALLDIR[ ]*=[ ]*\)[^ ;]*|\1$(tooldir)/lib|' \ + Makefile >Makefile.tem + mv -f Makefile.tem Makefile +fi + +. ${topsrcdir}/config-ml.in diff --git a/contrib/libstdc++/csetjmp b/contrib/libstdc++/csetjmp new file mode 100644 index 0000000..4bba048 --- /dev/null +++ b/contrib/libstdc++/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 <setjmp.h> +#endif + diff --git a/contrib/libstdc++/csignal b/contrib/libstdc++/csignal new file mode 100644 index 0000000..6febfb7 --- /dev/null +++ b/contrib/libstdc++/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 <signal.h> +#endif diff --git a/contrib/libstdc++/cstdarg b/contrib/libstdc++/cstdarg new file mode 100644 index 0000000..324f5a1 --- /dev/null +++ b/contrib/libstdc++/cstdarg @@ -0,0 +1,7 @@ +// -*- C++ -*- forwarding header. +// This file is part of the GNU ANSI C++ Library. + +#ifndef __CSTDARG__ +#define __CSTDARG__ +#include <stdarg.h> +#endif diff --git a/contrib/libstdc++/cstddef b/contrib/libstdc++/cstddef new file mode 100644 index 0000000..db5cbe4 --- /dev/null +++ b/contrib/libstdc++/cstddef @@ -0,0 +1,7 @@ +// -*- C++ -*- forwarding header. +// This file is part of the GNU ANSI C++ Library. + +#ifndef __CSTDDEF__ +#define __CSTDDEF__ +#include <stddef.h> +#endif diff --git a/contrib/libstdc++/cstdio b/contrib/libstdc++/cstdio new file mode 100644 index 0000000..1fe1456 --- /dev/null +++ b/contrib/libstdc++/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 <stdio.h> +#endif diff --git a/contrib/libstdc++/cstdlib b/contrib/libstdc++/cstdlib new file mode 100644 index 0000000..e7c1a51 --- /dev/null +++ b/contrib/libstdc++/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 <stdlib.h> + +#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/contrib/libstdc++/cstdlibi.cc b/contrib/libstdc++/cstdlibi.cc new file mode 100644 index 0000000..abbfa03 --- /dev/null +++ b/contrib/libstdc++/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 <cstdlib> diff --git a/contrib/libstdc++/cstring b/contrib/libstdc++/cstring new file mode 100644 index 0000000..d8d03a7 --- /dev/null +++ b/contrib/libstdc++/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 <string.h> + +#if 0 // Let's not bother with this just yet. +#include <cstddef> + +#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<char *> (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<char *> (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<char *> (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<char *> (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<void *> (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/contrib/libstdc++/cstringi.cc b/contrib/libstdc++/cstringi.cc new file mode 100644 index 0000000..2676feb --- /dev/null +++ b/contrib/libstdc++/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 <cstring> diff --git a/contrib/libstdc++/ctime b/contrib/libstdc++/ctime new file mode 100644 index 0000000..0184da5 --- /dev/null +++ b/contrib/libstdc++/ctime @@ -0,0 +1,7 @@ +// The -*- C++ -*- time header. +// This file is part of the GNU ANSI C++ Library. + +#ifndef __CTIME__ +#define __CTIME__ +#include <time.h> +#endif diff --git a/contrib/libstdc++/cwchar b/contrib/libstdc++/cwchar new file mode 100644 index 0000000..1674c12 --- /dev/null +++ b/contrib/libstdc++/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 <wchar.h> +#endif diff --git a/contrib/libstdc++/cwctype b/contrib/libstdc++/cwctype new file mode 100644 index 0000000..8112201 --- /dev/null +++ b/contrib/libstdc++/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 <wctype.h> +#endif diff --git a/contrib/libstdc++/fstream b/contrib/libstdc++/fstream new file mode 100644 index 0000000..2c35ca9 --- /dev/null +++ b/contrib/libstdc++/fstream @@ -0,0 +1,7 @@ +// -*- C++ -*- forwarding header. +// This file is part of the GNU ANSI C++ Library. + +#ifndef __FSTREAM__ +#define __FSTREAM__ +#include <fstream.h> +#endif diff --git a/contrib/libstdc++/iomanip b/contrib/libstdc++/iomanip new file mode 100644 index 0000000..8179485 --- /dev/null +++ b/contrib/libstdc++/iomanip @@ -0,0 +1,7 @@ +// -*- C++ -*- forwarding header. +// This file is part of the GNU ANSI C++ Library. + +#ifndef __IOMANIP__ +#define __IOMANIP__ +#include <iomanip.h> +#endif diff --git a/contrib/libstdc++/iosfwd b/contrib/libstdc++/iosfwd new file mode 100644 index 0000000..8314cf7 --- /dev/null +++ b/contrib/libstdc++/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/contrib/libstdc++/iostream b/contrib/libstdc++/iostream new file mode 100644 index 0000000..7ecba6e --- /dev/null +++ b/contrib/libstdc++/iostream @@ -0,0 +1,7 @@ +// -*- C++ -*- forwarding header. +// This file is part of the GNU ANSI C++ Library. + +#ifndef __IOSTREAM__ +#define __IOSTREAM__ +#include <iostream.h> +#endif diff --git a/contrib/libstdc++/sinst.cc b/contrib/libstdc++/sinst.cc new file mode 100644 index 0000000..79c31a3 --- /dev/null +++ b/contrib/libstdc++/sinst.cc @@ -0,0 +1,132 @@ +// 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 <string> + +#ifdef C +typedef char c; +#endif +#ifdef W +typedef wchar_t c; +#endif + +#ifdef TRAITS +template class string_char_traits <c>; +#endif + +typedef basic_string <c> s; + +#ifdef MAIN +template class basic_string <c>; +#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/contrib/libstdc++/std/bastring.cc b/contrib/libstdc++/std/bastring.cc new file mode 100644 index 0000000..b5f7a0d --- /dev/null +++ b/contrib/libstdc++/std/bastring.cc @@ -0,0 +1,524 @@ +// Member templates 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. + +extern "C++" { +template <class charT, class traits, class Allocator> +inline void * basic_string <charT, traits, Allocator>::Rep:: +operator new (size_t s, size_t extra) +{ + return Allocator::allocate(s + extra * sizeof (charT)); +} + +template <class charT, class traits, class Allocator> +inline void basic_string <charT, traits, Allocator>::Rep:: +operator delete (void * ptr) +{ + Allocator::deallocate(ptr, sizeof(Rep) + + reinterpret_cast<Rep *>(ptr)->res * + sizeof (charT)); +} + +template <class charT, class traits, class Allocator> +inline size_t basic_string <charT, traits, Allocator>::Rep:: +frob_size (size_t s) +{ + size_t i = 16; + while (i < s) i *= 2; + return i; +} + +template <class charT, class traits, class Allocator> +inline basic_string <charT, traits, Allocator>::Rep * +basic_string <charT, traits, Allocator>::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 <class charT, class traits, class Allocator> +charT * basic_string <charT, traits, Allocator>::Rep:: +clone () +{ + Rep *p = Rep::create (len); + p->copy (0, data (), len); + p->len = len; + return p->data (); +} + +template <class charT, class traits, class Allocator> +inline bool basic_string <charT, traits, Allocator>::Rep:: +excess_slop (size_t s, size_t r) +{ + return 2 * (s <= 16 ? 16 : s) < r; +} + +template <class charT, class traits, class Allocator> +inline bool basic_string <charT, traits, Allocator>:: +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 <class charT, class traits, class Allocator> +void basic_string <charT, traits, Allocator>:: +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 <class charT, class traits, class Allocator> +basic_string <charT, traits, Allocator>& +basic_string <charT, traits, Allocator>:: +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 <class charT, class traits, class Allocator> +inline void basic_string <charT, traits, Allocator>::Rep:: +copy (size_t pos, const charT *s, size_t n) +{ + if (n) + traits::copy (data () + pos, s, n); +} + +template <class charT, class traits, class Allocator> +inline void basic_string <charT, traits, Allocator>::Rep:: +move (size_t pos, const charT *s, size_t n) +{ + if (n) + traits::move (data () + pos, s, n); +} + +template <class charT, class traits, class Allocator> +basic_string <charT, traits, Allocator>& +basic_string <charT, traits, Allocator>:: +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 <class charT, class traits, class Allocator> +inline void basic_string <charT, traits, Allocator>::Rep:: +set (size_t pos, const charT c, size_t n) +{ + traits::set (data () + pos, c, n); +} + +template <class charT, class traits, class Allocator> +basic_string <charT, traits, Allocator>& basic_string <charT, traits, Allocator>:: +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 <class charT, class traits, class Allocator> +void basic_string <charT, traits, Allocator>:: +resize (size_type n, charT c) +{ + LENGTHERROR (n > max_size ()); + + if (n > length ()) + append (n - length (), c); + else + erase (n); +} + +template <class charT, class traits, class Allocator> +basic_string <charT, traits, Allocator>::size_type +basic_string <charT, traits, Allocator>:: +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 <class charT, class traits, class Allocator> +basic_string <charT, traits, Allocator>::size_type +basic_string <charT, traits, Allocator>:: +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 <class charT, class traits, class Allocator> +inline basic_string <charT, traits, Allocator>::size_type +basic_string <charT, traits, Allocator>:: +_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 <class charT, class traits, class Allocator> +basic_string <charT, traits, Allocator>::size_type +basic_string <charT, traits, Allocator>:: +find (charT c, size_type pos) const +{ + return _find (data (), c, pos, length ()); +} + +template <class charT, class traits, class Allocator> +basic_string <charT, traits, Allocator>::size_type +basic_string <charT, traits, Allocator>:: +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 <class charT, class traits, class Allocator> +basic_string <charT, traits, Allocator>::size_type +basic_string <charT, traits, Allocator>:: +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 <class charT, class traits, class Allocator> +basic_string <charT, traits, Allocator>::size_type +basic_string <charT, traits, Allocator>:: +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 <class charT, class traits, class Allocator> +basic_string <charT, traits, Allocator>::size_type +basic_string <charT, traits, Allocator>:: +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 <class charT, class traits, class Allocator> +basic_string <charT, traits, Allocator>::size_type +basic_string <charT, traits, Allocator>:: +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 <class charT, class traits, class Allocator> +basic_string <charT, traits, Allocator>::size_type +basic_string <charT, traits, Allocator>:: +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 <class charT, class traits, class Allocator> +basic_string <charT, traits, Allocator>::size_type +basic_string <charT, traits, Allocator>:: +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 <class charT, class traits, class Allocator> +basic_string <charT, traits, Allocator>::size_type +basic_string <charT, traits, Allocator>:: +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 <class charT, class traits, class Allocator> +int basic_string <charT, traits, Allocator>:: +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 <class charT, class traits, class Allocator> +int basic_string <charT, traits, Allocator>:: +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 <iostream.h> + +template <class charT, class traits, class Allocator> +istream & +operator>> (istream &is, basic_string <charT, traits, Allocator> &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 += ch; + if (--w == 1) + break; + } + } + + is.isfx (); + if (s.length () == 0) + is.setstate (ios::failbit); + + return is; +} + +template <class charT, class traits, class Allocator> +ostream & +operator<< (ostream &o, const basic_string <charT, traits, Allocator>& s) +{ + return o.write (s.data (), s.length ()); +} + +template <class charT, class traits, class Allocator> +istream& +getline (istream &is, basic_string <charT, traits, Allocator>& 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 += 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 <class charT, class traits, class Allocator> +basic_string <charT, traits, Allocator>::Rep +basic_string<charT, traits, Allocator>::nilRep = { 0, 0, 1, false }; + +template <class charT, class traits, class Allocator> +const basic_string <charT, traits, Allocator>::size_type +basic_string <charT, traits, Allocator>::npos; + +} // extern "C++" diff --git a/contrib/libstdc++/std/bastring.h b/contrib/libstdc++/std/bastring.h new file mode 100644 index 0000000..f188628 --- /dev/null +++ b/contrib/libstdc++/std/bastring.h @@ -0,0 +1,620 @@ +// Main templates for the -*- C++ -*- string classes. +// Copyright (C) 1994, 1995 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 <cstddef> +#include <std/straits.h> + +// NOTE : This does NOT conform to the draft standard and is likely to change +#include <alloc.h> + +extern "C++" { +class istream; class ostream; + +#include <iterator> + +#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 <cassert> +#define OUTOFRANGE(cond) assert (!(cond)) +#define LENGTHERROR(cond) assert (!(cond)) + +#endif + +template <class charT, class traits = string_char_traits<charT>, + class Allocator = alloc > +class basic_string +{ +private: + struct Rep { + size_t len, res, ref; + bool selfish; + + charT* data () { return reinterpret_cast<charT *>(this + 1); } + charT& operator[] (size_t s) { return data () [s]; } + charT* grab () { if (selfish) return clone (); ++ref; return data (); } + void release () { if (--ref == 0) delete this; } + + 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<iterator> reverse_iterator; + typedef ::reverse_iterator<const_iterator> const_reverse_iterator; + static const size_type npos = static_cast<size_type>(-1); + +private: + Rep *rep () const { return reinterpret_cast<Rep *>(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<class InputIterator> + 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<class InputIterator> + basic_string& append(InputIterator first, InputIterator last) +#else + basic_string& append(const_iterator first, const_iterator last) +#endif + { return replace (iend (), iend (), first, last); } + + 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<class InputIterator> + 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<class InputIterator> + 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<class InputIterator> + 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 <class charT, class traits, class Allocator> template <class InputIterator> +basic_string <charT, traits, Allocator>& basic_string <charT, traits, Allocator>:: +replace (iterator i1, iterator i2, InputIterator j1, InputIterator j2) +#else +template <class charT, class traits, class Allocator> +basic_string <charT, traits, Allocator>& basic_string <charT, traits, Allocator>:: +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 <class charT, class traits, class Allocator> +inline basic_string <charT, traits, Allocator> +operator+ (const basic_string <charT, traits, Allocator>& lhs, + const basic_string <charT, traits, Allocator>& rhs) +{ + basic_string <charT, traits, Allocator> str (lhs); + str.append (rhs); + return str; +} + +template <class charT, class traits, class Allocator> +inline basic_string <charT, traits, Allocator> +operator+ (const charT* lhs, const basic_string <charT, traits, Allocator>& rhs) +{ + basic_string <charT, traits, Allocator> str (lhs); + str.append (rhs); + return str; +} + +template <class charT, class traits, class Allocator> +inline basic_string <charT, traits, Allocator> +operator+ (charT lhs, const basic_string <charT, traits, Allocator>& rhs) +{ + basic_string <charT, traits, Allocator> str (1, lhs); + str.append (rhs); + return str; +} + +template <class charT, class traits, class Allocator> +inline basic_string <charT, traits, Allocator> +operator+ (const basic_string <charT, traits, Allocator>& lhs, const charT* rhs) +{ + basic_string <charT, traits, Allocator> str (lhs); + str.append (rhs); + return str; +} + +template <class charT, class traits, class Allocator> +inline basic_string <charT, traits, Allocator> +operator+ (const basic_string <charT, traits, Allocator>& lhs, charT rhs) +{ + basic_string <charT, traits, Allocator> str (lhs); + str.append (1, rhs); + return str; +} + +template <class charT, class traits, class Allocator> +inline bool +operator== (const basic_string <charT, traits, Allocator>& lhs, + const basic_string <charT, traits, Allocator>& rhs) +{ + return (lhs.compare (rhs) == 0); +} + +template <class charT, class traits, class Allocator> +inline bool +operator== (const charT* lhs, const basic_string <charT, traits, Allocator>& rhs) +{ + return (rhs.compare (lhs) == 0); +} + +template <class charT, class traits, class Allocator> +inline bool +operator== (const basic_string <charT, traits, Allocator>& lhs, const charT* rhs) +{ + return (lhs.compare (rhs) == 0); +} + +template <class charT, class traits, class Allocator> +inline bool +operator!= (const charT* lhs, const basic_string <charT, traits, Allocator>& rhs) +{ + return (rhs.compare (lhs) != 0); +} + +template <class charT, class traits, class Allocator> +inline bool +operator!= (const basic_string <charT, traits, Allocator>& lhs, const charT* rhs) +{ + return (lhs.compare (rhs) != 0); +} + +template <class charT, class traits, class Allocator> +inline bool +operator< (const basic_string <charT, traits, Allocator>& lhs, + const basic_string <charT, traits, Allocator>& rhs) +{ + return (lhs.compare (rhs) < 0); +} + +template <class charT, class traits, class Allocator> +inline bool +operator< (const charT* lhs, const basic_string <charT, traits, Allocator>& rhs) +{ + return (rhs.compare (lhs) > 0); +} + +template <class charT, class traits, class Allocator> +inline bool +operator< (const basic_string <charT, traits, Allocator>& lhs, const charT* rhs) +{ + return (lhs.compare (rhs) < 0); +} + +template <class charT, class traits, class Allocator> +inline bool +operator> (const charT* lhs, const basic_string <charT, traits, Allocator>& rhs) +{ + return (rhs.compare (lhs) < 0); +} + +template <class charT, class traits, class Allocator> +inline bool +operator> (const basic_string <charT, traits, Allocator>& lhs, const charT* rhs) +{ + return (lhs.compare (rhs) > 0); +} + +template <class charT, class traits, class Allocator> +inline bool +operator<= (const charT* lhs, const basic_string <charT, traits, Allocator>& rhs) +{ + return (rhs.compare (lhs) >= 0); +} + +template <class charT, class traits, class Allocator> +inline bool +operator<= (const basic_string <charT, traits, Allocator>& lhs, const charT* rhs) +{ + return (lhs.compare (rhs) <= 0); +} + +template <class charT, class traits, class Allocator> +inline bool +operator>= (const charT* lhs, const basic_string <charT, traits, Allocator>& rhs) +{ + return (rhs.compare (lhs) <= 0); +} + +template <class charT, class traits, class Allocator> +inline bool +operator>= (const basic_string <charT, traits, Allocator>& lhs, const charT* rhs) +{ + return (lhs.compare (rhs) >= 0); +} + +template <class charT, class traits, class Allocator> +inline bool +operator!= (const basic_string <charT, traits, Allocator>& lhs, + const basic_string <charT, traits, Allocator>& rhs) +{ + return (lhs.compare (rhs) != 0); +} + +template <class charT, class traits, class Allocator> +inline bool +operator> (const basic_string <charT, traits, Allocator>& lhs, + const basic_string <charT, traits, Allocator>& rhs) +{ + return (lhs.compare (rhs) > 0); +} + +template <class charT, class traits, class Allocator> +inline bool +operator<= (const basic_string <charT, traits, Allocator>& lhs, + const basic_string <charT, traits, Allocator>& rhs) +{ + return (lhs.compare (rhs) <= 0); +} + +template <class charT, class traits, class Allocator> +inline bool +operator>= (const basic_string <charT, traits, Allocator>& lhs, + const basic_string <charT, traits, Allocator>& rhs) +{ + return (lhs.compare (rhs) >= 0); +} + +class istream; class ostream; +template <class charT, class traits, class Allocator> istream& +operator>> (istream&, basic_string <charT, traits, Allocator>&); +template <class charT, class traits, class Allocator> ostream& +operator<< (ostream&, const basic_string <charT, traits, Allocator>&); +template <class charT, class traits, class Allocator> istream& +getline (istream&, basic_string <charT, traits, Allocator>&, charT delim = '\n'); + +} // extern "C++" + +#include <std/bastring.cc> + +#endif diff --git a/contrib/libstdc++/std/complext.cc b/contrib/libstdc++/std/complext.cc new file mode 100644 index 0000000..d50bf08 --- /dev/null +++ b/contrib/libstdc++/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 <complex> + +extern "C++" { +template <class FLOAT> complex<FLOAT> +cos (const complex<FLOAT>& x) +{ + return complex<FLOAT> (cos (real (x)) * cosh (imag (x)), + - sin (real (x)) * sinh (imag (x))); +} + +template <class FLOAT> complex<FLOAT> +cosh (const complex<FLOAT>& x) +{ + return complex<FLOAT> (cosh (real (x)) * cos (imag (x)), + sinh (real (x)) * sin (imag (x))); +} + +template <class FLOAT> complex<FLOAT> +exp (const complex<FLOAT>& x) +{ + return polar (FLOAT (exp (real (x))), imag (x)); +} + +template <class FLOAT> complex<FLOAT> +log (const complex<FLOAT>& x) +{ + return complex<FLOAT> (log (abs (x)), arg (x)); +} + +template <class FLOAT> complex<FLOAT> +pow (const complex<FLOAT>& x, const complex<FLOAT>& 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 <class FLOAT> complex<FLOAT> +pow (const complex<FLOAT>& x, FLOAT y) +{ + return exp (FLOAT (y) * log (x)); +} + +template <class FLOAT> complex<FLOAT> +pow (FLOAT x, const complex<FLOAT>& y) +{ + return exp (y * FLOAT (log (x))); +} + +template <class FLOAT> complex<FLOAT> +sin (const complex<FLOAT>& x) +{ + return complex<FLOAT> (sin (real (x)) * cosh (imag (x)), + cos (real (x)) * sinh (imag (x))); +} + +template <class FLOAT> complex<FLOAT> +sinh (const complex<FLOAT>& x) +{ + return complex<FLOAT> (sinh (real (x)) * cos (imag (x)), + cosh (real (x)) * sin (imag (x))); +} + +#include <iostream.h> + +template <class FLOAT> istream& +operator >> (istream& is, complex<FLOAT>& 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<FLOAT> (re, im); + + return is; +} + +template <class FLOAT> ostream& +operator << (ostream& os, const complex<FLOAT>& 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 <class FLOAT> complex<FLOAT>& +__doadv (complex<FLOAT>* ths, const complex<FLOAT>& 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 <class FLOAT> complex<FLOAT> +operator / (const complex<FLOAT>& x, const complex<FLOAT>& 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<FLOAT> (nr, ni); +} + +template <class FLOAT> complex<FLOAT> +operator / (FLOAT x, const complex<FLOAT>& 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<FLOAT> (nr, ni); +} + +template <class FLOAT> complex<FLOAT> +pow (const complex<FLOAT>& xin, int y) +{ + if (y == 0) + return complex<FLOAT> (1.0); + complex<FLOAT> r (1.0); + complex<FLOAT> x (xin); + if (y < 0) + { + y = -y; + x = 1/x; + } + for (;;) + { + if (y & 1) + r *= x; + if (y >>= 1) + x *= x; + else + return r; + } +} + +template <class FLOAT> complex<FLOAT> +sqrt (const complex<FLOAT>& 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<FLOAT> (nr, ni); +} +} // extern "C++" diff --git a/contrib/libstdc++/std/complext.h b/contrib/libstdc++/std/complext.h new file mode 100644 index 0000000..6c55037 --- /dev/null +++ b/contrib/libstdc++/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 <cmath> + +#if ! defined (__GNUG__) && ! defined (__attribute__) +#define __attribute__(foo) /* Ignore. */ +#endif + +class istream; +class ostream; + +extern "C++" { +template <class _FLT> class complex; +template <class _FLT> complex<_FLT>& + __doapl (complex<_FLT>* ths, const complex<_FLT>& r); +template <class _FLT> complex<_FLT>& + __doami (complex<_FLT>* ths, const complex<_FLT>& r); +template <class _FLT> complex<_FLT>& + __doaml (complex<_FLT>* ths, const complex<_FLT>& r); +template <class _FLT> complex<_FLT>& + __doadv (complex<_FLT>* ths, const complex<_FLT>& r); + +template <class _FLT> +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<float>; +class complex<double>; +class complex<long double>; + +template <class _FLT> +inline complex<_FLT>& +__doapl (complex<_FLT>* ths, const complex<_FLT>& r) +{ + ths->re += r.re; + ths->im += r.im; + return *ths; +} +template <class _FLT> +inline complex<_FLT>& +complex<_FLT>::operator += (const complex<_FLT>& r) +{ + return __doapl (this, r); +} + +template <class _FLT> +inline complex<_FLT>& +__doami (complex<_FLT>* ths, const complex<_FLT>& r) +{ + ths->re -= r.re; + ths->im -= r.im; + return *ths; +} +template <class _FLT> +inline complex<_FLT>& +complex<_FLT>::operator -= (const complex<_FLT>& r) +{ + return __doami (this, r); +} + +template <class _FLT> +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 <class _FLT> +inline complex<_FLT>& +complex<_FLT>::operator *= (const complex<_FLT>& r) +{ + return __doaml (this, r); +} + +template <class _FLT> +inline complex<_FLT>& +complex<_FLT>::operator /= (const complex<_FLT>& r) +{ + return __doadv (this, r); +} + +template <class _FLT> inline _FLT +imag (const complex<_FLT>& x) __attribute__ ((const)); + +template <class _FLT> inline _FLT +imag (const complex<_FLT>& x) +{ + return x.imag (); +} + +template <class _FLT> inline _FLT +real (const complex<_FLT>& x) __attribute__ ((const)); + +template <class _FLT> inline _FLT +real (const complex<_FLT>& x) +{ + return x.real (); +} + +template <class _FLT> inline complex<_FLT> +operator + (const complex<_FLT>& x, const complex<_FLT>& y) __attribute__ ((const)); + +template <class _FLT> inline complex<_FLT> +operator + (const complex<_FLT>& x, const complex<_FLT>& y) +{ + return complex<_FLT> (real (x) + real (y), imag (x) + imag (y)); +} + +template <class _FLT> inline complex<_FLT> +operator + (const complex<_FLT>& x, _FLT y) __attribute__ ((const)); + +template <class _FLT> inline complex<_FLT> +operator + (const complex<_FLT>& x, _FLT y) +{ + return complex<_FLT> (real (x) + y, imag (x)); +} + +template <class _FLT> inline complex<_FLT> +operator + (_FLT x, const complex<_FLT>& y) __attribute__ ((const)); + +template <class _FLT> inline complex<_FLT> +operator + (_FLT x, const complex<_FLT>& y) +{ + return complex<_FLT> (x + real (y), imag (y)); +} + +template <class _FLT> inline complex<_FLT> +operator - (const complex<_FLT>& x, const complex<_FLT>& y) __attribute__ ((const)); + +template <class _FLT> inline complex<_FLT> +operator - (const complex<_FLT>& x, const complex<_FLT>& y) +{ + return complex<_FLT> (real (x) - real (y), imag (x) - imag (y)); +} + +template <class _FLT> inline complex<_FLT> +operator - (const complex<_FLT>& x, _FLT y) __attribute__ ((const)); + +template <class _FLT> inline complex<_FLT> +operator - (const complex<_FLT>& x, _FLT y) +{ + return complex<_FLT> (real (x) - y, imag (x)); +} + +template <class _FLT> inline complex<_FLT> +operator - (_FLT x, const complex<_FLT>& y) __attribute__ ((const)); + +template <class _FLT> inline complex<_FLT> +operator - (_FLT x, const complex<_FLT>& y) +{ + return complex<_FLT> (x - real (y), - imag (y)); +} + +template <class _FLT> inline complex<_FLT> +operator * (const complex<_FLT>& x, const complex<_FLT>& y) __attribute__ ((const)); + +template <class _FLT> 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 <class _FLT> inline complex<_FLT> +operator * (const complex<_FLT>& x, _FLT y) __attribute__ ((const)); + +template <class _FLT> inline complex<_FLT> +operator * (const complex<_FLT>& x, _FLT y) +{ + return complex<_FLT> (real (x) * y, imag (x) * y); +} + +template <class _FLT> inline complex<_FLT> +operator * (_FLT x, const complex<_FLT>& y) __attribute__ ((const)); + +template <class _FLT> inline complex<_FLT> +operator * (_FLT x, const complex<_FLT>& y) +{ + return complex<_FLT> (x * real (y), x * imag (y)); +} + +template <class _FLT> complex<_FLT> +operator / (const complex<_FLT>& x, _FLT y) __attribute__ ((const)); + +template <class _FLT> complex<_FLT> +operator / (const complex<_FLT>& x, _FLT y) +{ + return complex<_FLT> (real (x) / y, imag (x) / y); +} + +template <class _FLT> inline complex<_FLT> +operator + (const complex<_FLT>& x) __attribute__ ((const)); + +template <class _FLT> inline complex<_FLT> +operator + (const complex<_FLT>& x) +{ + return x; +} + +template <class _FLT> inline complex<_FLT> +operator - (const complex<_FLT>& x) __attribute__ ((const)); + +template <class _FLT> inline complex<_FLT> +operator - (const complex<_FLT>& x) +{ + return complex<_FLT> (-real (x), -imag (x)); +} + +template <class _FLT> inline bool +operator == (const complex<_FLT>& x, const complex<_FLT>& y) __attribute__ ((const)); + +template <class _FLT> inline bool +operator == (const complex<_FLT>& x, const complex<_FLT>& y) +{ + return real (x) == real (y) && imag (x) == imag (y); +} + +template <class _FLT> inline bool +operator == (const complex<_FLT>& x, _FLT y) __attribute__ ((const)); + +template <class _FLT> inline bool +operator == (const complex<_FLT>& x, _FLT y) +{ + return real (x) == y && imag (x) == 0; +} + +template <class _FLT> inline bool +operator == (_FLT x, const complex<_FLT>& y) __attribute__ ((const)); + +template <class _FLT> inline bool +operator == (_FLT x, const complex<_FLT>& y) +{ + return x == real (y) && imag (y) == 0; +} + +template <class _FLT> inline bool +operator != (const complex<_FLT>& x, const complex<_FLT>& y) __attribute__ ((const)); + +template <class _FLT> inline bool +operator != (const complex<_FLT>& x, const complex<_FLT>& y) +{ + return real (x) != real (y) || imag (x) != imag (y); +} + +template <class _FLT> inline bool +operator != (const complex<_FLT>& x, _FLT y) __attribute__ ((const)); + +template <class _FLT> inline bool +operator != (const complex<_FLT>& x, _FLT y) +{ + return real (x) != y || imag (x) != 0; +} + +template <class _FLT> inline bool +operator != (_FLT x, const complex<_FLT>& y) __attribute__ ((const)); + +template <class _FLT> 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 <class _FLT> inline _FLT +abs (const complex<_FLT>& x) __attribute__ ((const)); + +template <class _FLT> inline _FLT +abs (const complex<_FLT>& x) +{ + return hypot (real (x), imag (x)); +} + +template <class _FLT> inline _FLT +arg (const complex<_FLT>& x) __attribute__ ((const)); + +template <class _FLT> inline _FLT +arg (const complex<_FLT>& x) +{ + return atan2 (imag (x), real (x)); +} + +template <class _FLT> inline complex<_FLT> +polar (_FLT r, _FLT t) __attribute__ ((const)); + +template <class _FLT> inline complex<_FLT> +polar (_FLT r, _FLT t) +{ + return complex<_FLT> (r * cos (t), r * sin (t)); +} + +template <class _FLT> inline complex<_FLT> +conj (const complex<_FLT>& x) __attribute__ ((const)); + +template <class _FLT> inline complex<_FLT> +conj (const complex<_FLT>& x) +{ + return complex<_FLT> (real (x), -imag (x)); +} + +template <class _FLT> inline _FLT +norm (const complex<_FLT>& x) __attribute__ ((const)); + +template <class _FLT> inline _FLT +norm (const complex<_FLT>& x) +{ + return real (x) * real (x) + imag (x) * imag (x); +} + +// Declarations of templates in complext.ccI + +template <class _FLT> complex<_FLT> + operator / (const complex<_FLT>&, const complex<_FLT>&) __attribute__ ((const)); +template <class _FLT> complex<_FLT> + operator / (_FLT, const complex<_FLT>&) __attribute__ ((const)); +template <class _FLT> complex<_FLT> + cos (const complex<_FLT>&) __attribute__ ((const)); +template <class _FLT> complex<_FLT> + cosh (const complex<_FLT>&) __attribute__ ((const)); +template <class _FLT> complex<_FLT> + exp (const complex<_FLT>&) __attribute__ ((const)); +template <class _FLT> complex<_FLT> + log (const complex<_FLT>&) __attribute__ ((const)); +template <class _FLT> complex<_FLT> + pow (const complex<_FLT>&, const complex<_FLT>&) __attribute__ ((const)); +template <class _FLT> complex<_FLT> + pow (const complex<_FLT>&, _FLT) __attribute__ ((const)); +template <class _FLT> complex<_FLT> + pow (const complex<_FLT>&, int) __attribute__ ((const)); +template <class _FLT> complex<_FLT> + pow (_FLT, const complex<_FLT>&) __attribute__ ((const)); +template <class _FLT> complex<_FLT> + sin (const complex<_FLT>&) __attribute__ ((const)); +template <class _FLT> complex<_FLT> + sinh (const complex<_FLT>&) __attribute__ ((const)); +template <class _FLT> complex<_FLT> + sqrt (const complex<_FLT>&) __attribute__ ((const)); + +template <class _FLT> istream& operator >> (istream&, complex<_FLT>&); +template <class _FLT> ostream& operator << (ostream&, const complex<_FLT>&); +} // extern "C++" + +// Specializations and such + +#include <std/fcomplex.h> +#include <std/dcomplex.h> +#include <std/ldcomplex.h> + +#endif diff --git a/contrib/libstdc++/std/dcomplex.h b/contrib/libstdc++/std/dcomplex.h new file mode 100644 index 0000000..5812d9f --- /dev/null +++ b/contrib/libstdc++/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<double> +{ +public: + complex (double r = 0, double i = 0): re (r), im (i) { } + complex (const complex<float>& r): re (r.real ()), im (r.imag ()) { } + explicit complex (const complex<long double>& 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<float>::complex (const complex<double>& r) +: re (r.real ()), im (r.imag ()) +{ } +} // extern "C++" + +#endif diff --git a/contrib/libstdc++/std/fcomplex.h b/contrib/libstdc++/std/fcomplex.h new file mode 100644 index 0000000..cd9af1a --- /dev/null +++ b/contrib/libstdc++/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<float> +{ +public: + complex (float r = 0, float i = 0): re (r), im (i) { } + explicit complex (const complex<double>& r); + explicit complex (const complex<long double>& 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/contrib/libstdc++/std/ldcomplex.h b/contrib/libstdc++/std/ldcomplex.h new file mode 100644 index 0000000..bc91fa4 --- /dev/null +++ b/contrib/libstdc++/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<long double> +{ +public: + complex (long double r = 0, long double i = 0): re (r), im (i) { } + complex (const complex<float>& r): re (r.real ()), im (r.imag ()) { } + complex (const complex<double>& 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<float>::complex (const complex<long double>& r) +: re (r.real ()), im (r.imag ()) +{ } + +inline complex<double>::complex (const complex<long double>& r) +: re (r.real ()), im (r.imag ()) +{ } +} // extern "C++" + +#endif diff --git a/contrib/libstdc++/std/straits.h b/contrib/libstdc++/std/straits.h new file mode 100644 index 0000000..c80e7ab --- /dev/null +++ b/contrib/libstdc++/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 <char> +#pragma interface "std/straits.h" +#endif + +#include <cstddef> + +extern "C++" { +template <class charT> +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 <cctype> +#include <cstring> + +struct string_char_traits <char> { + 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 <cwctype> +struct string_char_traits <wchar_t> { + 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/contrib/libstdc++/stdexcept b/contrib/libstdc++/stdexcept new file mode 100644 index 0000000..c0ac87f --- /dev/null +++ b/contrib/libstdc++/stdexcept @@ -0,0 +1,101 @@ +// 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 <exception> +#include <string> + +extern "C++" { + +#ifdef __HONOR_STD +namespace std { +#endif + +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) { } +}; + +#ifdef __HONOR_STD +} // namespace std +#endif + +} // extern "C++" + +#endif diff --git a/contrib/libstdc++/stdexcepti.cc b/contrib/libstdc++/stdexcepti.cc new file mode 100644 index 0000000..3b03acd --- /dev/null +++ b/contrib/libstdc++/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 <stdexcept> + +// Entry points for string. + +void +__out_of_range (const char *s) +{ + throw out_of_range (s); +} + +void __length_error (const char *s) +{ + throw length_error (s); +} diff --git a/contrib/libstdc++/stl.h b/contrib/libstdc++/stl.h new file mode 100644 index 0000000..4b27074 --- /dev/null +++ b/contrib/libstdc++/stl.h @@ -0,0 +1,15 @@ +// -*- C++ -*- compatibility header. +// This file is part of the GNU ANSI C++ Library. + +#include <algorithm> +#include <deque> +#include <functional> +#include <iterator> +#include <list> +#include <map> +#include <memory> +#include <numeric> +#include <set> +#include <stack> +#include <utility> +#include <vector> diff --git a/contrib/libstdc++/stl/ChangeLog b/contrib/libstdc++/stl/ChangeLog new file mode 100644 index 0000000..4655380 --- /dev/null +++ b/contrib/libstdc++/stl/ChangeLog @@ -0,0 +1,273 @@ +Sun Mar 14 02:38:07 PST 1999 Jeff Law (law@cygnus.com) + + * egcs-1.1.2 Released. + +Fri Jul 10 15:20:09 1998 Klaus-Georg Adams <Klaus-Georg.Adams@chemie.uni-karlsruhe.de> + + * stl_tempbuf.h (temporary_buffer): Add missing typename. + * type_traits.h: update comments. + +Sun Jun 28 00:49:42 1998 Jeffrey A Law (law@cygnus.com) + + * stl_config.h (__STL_PTHREADS): Don't define for glibc 2 if + _G_USING_THUNKS is not defined. + +1998-04-07 18:32 Ulrich Drepper <drepper@cygnus.com> + + * stl_hashtable.h (__stl_prime_list): Mark last two numbers as + unsigned long since they are otherwise too large for long int on + 32bit machines. + +Fri Feb 20 16:15:05 1998 H.J. Lu (hjl@gnu.org) + Jason Merrill <jason@yorick.cygnus.com> + + * ropeimpl.h: Check __STL_PTHREADS instead of _PTHREADS. + * stl_alloc.h: Ditto. + * stl_config.h: Ditto. + * stl_rope.h: Ditto. + + * stl_config.h: include <_G_config.h> if __GNUG__ is defined. + (__STL_PTHREADS): Defined if _PTHREADS is defined or + __GLIBC__ >= 2. + +Tue Jan 27 12:01:25 1998 Jason Merrill <jason@yorick.cygnus.com> + + * stl_algo.h (__lg): Fix for n == 0. + +Sat Nov 8 00:45:17 1997 Jason Merrill <jason@yorick.cygnus.com> + + * stl_hash_set.h (swap): Fix typo. + +Fri Nov 7 10:27:40 1997 Jason Merrill <jason@yorick.cygnus.com> + + * stl_hashtable.h: Fix typo. + +Thu Nov 6 11:19:09 1997 Jason Merrill <jason@yorick.cygnus.com> + + * stl_algo.h, stl_algobase.h, stl_bvector.h, + stl_deque.h: Update to October 28 SGI release. + +Sun Nov 2 12:14:56 1997 Jason Merrill <jason@yorick.cygnus.com> + + * algo.h, algobase.h, alloc.h, bvector.h, defalloc.h, deque.h, + function.h, hash_map.h, hash_set.h, hashtable.h, heap.h, iterator.h, + list.h, map.h, multimap.h, multiset.h, pair.h, pthread_alloc.h, + rope.h, ropeimpl.h, set.h, slist.h, stack.h, stl_config.h, tempbuf.h, + tree.h, type_traits.h, vector.h: Update to October 27 SGI snapshot. + * algorithm, deque, functional, hash_map, hash_set, iterator, list, + map, memory, numeric, pthread_alloc, queue, rope, set, slist, stack, + stl_algo.h, stl_algobase.h, stl_alloc.h, stl_bvector.h, + stl_construct.h, stl_deque.h, stl_function.h, stl_hash_fun.h, + stl_hash_map.h, stl_hash_set.h, stl_hashtable.h, stl_heap.h, + stl_iterator.h, stl_list.h, stl_map.h, stl_multimap.h, stl_multiset.h, + stl_numeric.h, stl_pair.h, stl_queue.h, stl_raw_storage_iter.h, + stl_relops.h, stl_rope.h, stl_set.h, stl_slist.h, stl_stack.h, + stl_tempbuf.h, stl_tree.h, stl_uninitialized.h, stl_vector.h, + utility, vector: New files in October 27 SGI snapshot. + +Fri Oct 17 19:07:42 1997 Jason Merrill <jason@yorick.cygnus.com> + + * tree.h, vector.h: Fix accidental divergence from SGI release. + +Tue Sep 9 19:47:28 1997 Jason Merrill <jason@yorick.cygnus.com> + + * algo.h, algobase.h, alloc.h, bvector.h, deque.h, hashtable.h, + iterator.h, list.h, rope.h, ropeimpl.h, slist.h, stl_config.h, + tree.h, vector.h: Update To September 8 SGI release. + +Tue Sep 9 17:38:47 1997 Mark Mitchell <mmitchell@usa.net> + + * stl_config.h (__STL_MEMBER_TEMPLATES): Enable. + +Tue Aug 5 17:06:01 1997 Jason Merrill <jason@yorick.cygnus.com> + + * deque.h, function.h, hashtable.h, list.h, rope.h, ropeimpl.h, + tree.h: Update to July 31 SGI release. + +Fri Jul 18 10:06:56 1997 Jason Merrill <jason@yorick.cygnus.com> + + * algo.h, defalloc.h, hashtable.h, rope.h, ropeimpl.h, slist.h: + Update to June 30 SGI release. + +Fri Jul 04 02:17:15 1997 Ulrich Drepper <drepper@cygnus.com> + + * tree.h (rb_tree): Reverse order of member initializations + to prevent warnings. + +Sun Jun 15 18:17:21 1997 Jason Merrill <jason@yorick.cygnus.com> + + * *.h: Update to 6/13 SGI release. + +Fri May 23 10:56:18 1997 Jason Merrill <jason@yorick.cygnus.com> + + * stl_config.h: Add support for exceptions with g++. + + * *.h: Update to 5/8 SGI release. + +Thu Apr 24 19:00:23 1997 Jason Merrill <jason@yorick.cygnus.com> + + * *.h: Update to 3/24 SGI release. + +Wed Feb 19 18:19:18 1997 Jason Merrill <jason@yorick.cygnus.com> + + * *.h: Update to 2/18 SGI release. + + * bool.h: Lose. + +Mon Feb 10 16:33:23 1997 Jason Merrill <jason@yorick.cygnus.com> + + * alloc.h: Don't define __USE_MALLOC for g++. + * bool.h: Lose g++ case. + + * *.h: Update to 2/4 SGI release. + +Mon Jan 13 14:39:16 1997 Jason Merrill <jason@yorick.cygnus.com> + + * *.h: Update to 1/8 SGI release. + +Mon Sep 30 17:56:43 1996 Jason Merrill <jason@yorick.cygnus.com> + + * alloc.h (__unlock): Never use __lock_release. + +Fri Sep 27 19:03:06 1996 Jason Merrill <jason@yorick.cygnus.com> + + * alloc.h (__default_alloc_template): lock is a friend. + +Thu Sep 19 20:10:37 1996 Jason Merrill <jason@yorick.cygnus.com> + + Propagate these changes to new STL code: + * tree.h: Rearrange member initializers in rb_tree constructors. + * vector.h (insert): Cast iterator difference to size_type to + avoid warning. + + * *.h: Update to SGI snapshot (fixed). + * *.c, Makefile.in, configure.in: Removed. + +Sat Sep 14 09:43:06 1996 Jason Merrill <jason@yorick.cygnus.com> + + * deque.h, list.h, tree.h: Remove kludge obsoleted by new + overloading code. + +Sat Aug 10 14:59:50 1996 Jason Merrill <jason@yorick.cygnus.com> + + * tempbuf.cc (__stl_temp_buffer): Align like a pointer. + +Wed Jun 26 13:00:44 1996 Jason Merrill <jason@yorick.cygnus.com> + + * iterator.h: Add default template parameters. + +Wed Apr 24 10:45:22 1996 Doug Evans <dje@blues.cygnus.com> + + * Makefile.in (tempbuf.o,random.o): Add rules for SunOS VPATH. + +Fri Apr 5 17:52:31 1996 Per Bothner <bothner@kalessin.cygnus.com> + + * configure.in (EXTRA_MOSTLYCLEAN): New, to remove stl.list. + +Fri Mar 22 14:58:30 1996 Jason Merrill <jason@yorick.cygnus.com> + + Propagate these changes to new STL code: + * tree.h: Rearrange member initializers in rb_tree constructors. + * vector.h (insert): Cast iterator difference to size_type to + avoid warning. + +Sun Mar 10 07:49:03 1996 Jason Merrill <jason@yorick.cygnus.com> + + * deque.h (distance_type): Add overload for g++. + From Joe Buck. + +Thu Feb 22 14:07:12 1996 Jason Merrill <jason@yorick.cygnus.com> + + * bool.h: Revert. + * algo.h bvector.h deque.h function.h iterator.h list.h + pair.h stack.h tree.h vector.h: Wrap #include <bool.h> with + #ifndef __GNUG__. + * defalloc.h list.h deque.h tree.h: Use __GNUG__ to control + workarounds. + +Wed Feb 21 17:13:02 1996 Jason Merrill <jason@yorick.cygnus.com> + + * bool.h (TRUE, FALSE): Define for people expecting the bool.h + from libg++. Is this a good idea? + +Tue Feb 20 18:40:02 1996 Jason Merrill <jason@yorick.cygnus.com> + + * algo.h bool.h bvector.h defalloc.h deque.h function.h heap.h + iterator.h list.h map.h pair.h random.cc stack.h tree.c tree.h + vector.h: Revert to HP release with workarounds for missing + overloading functionality. + * Makefile.in (STL_OBJECTS): Remove tree.o. + +Thu Nov 9 17:05:23 1995 Jason Merrill <jason@yorick.cygnus.com> + + * algo.h algobase.h bvector.h defalloc.h deque.h function.h heap.h + iterator.h list.h map.h multimap.h multiset.h pair.h projectn.h + set.h stack.h tempbuf.h tree.h vector.h: Wrap #include <bool.h> + with #ifndef __GNUG__. + +Thu Nov 2 17:05:44 1995 Jason Merrill <jason@yorick.cygnus.com> + + * deque.h (deque<T>::insert): Fix merge typo. + * vector.h (value_type): Lose. + +Thu Nov 2 14:33:47 1995 Per Bothner <bothner@kalessin.cygnus.com> + + * algo.h, algobase.h, deque.h, function.h, list.h, pair.h, random.cc: + Merge in Oct 31 1995 release from HP. + +Fri Aug 11 17:11:12 1995 Per Bothner <bothner@kalessin.cygnus.com> + + * list.h: Avoid duplicate construction and destruction of list_nodes. + Patch from Klamer Schutte <klamer@ph.tn.tudelft.nl>. + +Fri Aug 11 16:45:18 1995 Per Bothner <bothner@kalessin.cygnus.com> + + * algo.h, algobase.h, deque.h: Merged in Jul 12 1995 release from HP. + +Mon Jun 5 18:38:56 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * Makefile.in (stl.list): Depend on stamp-picdir. + +Wed May 17 02:30:47 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * tree.h: Rearrange member initializers in rb_tree constructors. + + * Update to HP's February 7, 1995 release. + +Fri May 5 10:45:31 1995 Mike Stump <mrs@cygnus.com> + + * random.cc (seed): Move `for' decl out of `for' statement. + +Wed Apr 26 13:09:16 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * configure.in (XCXXINCLUDES): Rename. + +Wed Mar 29 19:24:56 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * tree.h (insert): Return a value. + + * vector.h (insert): Cast iterator difference to size_type to + avoid warning. + +Sun Feb 12 09:12:17 1995 Mike Stump <mrs@cygnus.com> + + * tree.h (rb_tree::max_size): Add definition when using GNU + workaround. + +Thu Jan 12 01:37:42 1995 deanm@medulla.LABS.TEK.COM (Dean Messing) + + * configure.in (LIBDIR): Set to yes. + +Fri Dec 30 18:26:20 1994 Mike Stump <mrs@cygnus.com> + + * iterator.h: Add default template parameters where possible. + +Fri Dec 30 16:29:39 1994 Mike Stump <mrs@cygnus.com> + + * algo.h: Change rand to __rand to fix make check on linux systems. + +Tue Nov 29 15:30:30 1994 Per Bothner <bothner@kalessin.cygnus.com> + + * Initial check-in, based on HP's October 21, 1994. + + diff --git a/contrib/libstdc++/stl/README b/contrib/libstdc++/stl/README new file mode 100644 index 0000000..81bc7cf --- /dev/null +++ b/contrib/libstdc++/stl/README @@ -0,0 +1,16 @@ +This directory contains an SGI release of the C++ Standard Template +Library, slightly modified to work with g++ (version 2.8.0 or newer). + +Note that this is based on a pre-Draft Standard for C++. +Things are likely to change. For example, the header file names +are very likely to change. The Allocator interface will change. Etc, etc. +CYGNUS MAKES NO COMMITTMENT (yet) TO SUPPORT BACKWARD COMPATIBILITY FOR STL. + +For examples if things that should work, look in the ../tests directory. + +DOCUMENTATION: +See http://www.sgi.com/Technology/STL/ or http://www.dinkumware.com/ +on the World-Wide Web. + + --Jason Merrill +Cygnus Support jason@cygnus.com diff --git a/contrib/libstdc++/stl/algo.h b/contrib/libstdc++/stl/algo.h new file mode 100644 index 0000000..1707868 --- /dev/null +++ b/contrib/libstdc++/stl/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 <algobase.h> +#include <tempbuf.h> +#include <stl_algo.h> +#include <stl_numeric.h> + +#ifdef __STL_USE_NAMESPACES + +// Names from <stl_algo.h> +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 <stl_numeric.h> +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/contrib/libstdc++/stl/algobase.h b/contrib/libstdc++/stl/algobase.h new file mode 100644 index 0000000..f35e7af --- /dev/null +++ b/contrib/libstdc++/stl/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 <pair.h> +#endif +#ifndef __SGI_STL_ITERATOR_H +#include <iterator.h> +#endif +#ifndef __SGI_STL_INTERNAL_ALGOBASE_H +#include <stl_algobase.h> +#endif +#ifndef __SGI_STL_INTERNAL_UNINITIALIZED_H +#include <stl_uninitialized.h> +#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/contrib/libstdc++/stl/algorithm b/contrib/libstdc++/stl/algorithm new file mode 100644 index 0000000..515e9bd --- /dev/null +++ b/contrib/libstdc++/stl/algorithm @@ -0,0 +1,39 @@ +/* + * + * 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 <stl_algobase.h> +#include <stl_construct.h> +#include <stl_tempbuf.h> +#include <stl_algo.h> + +#endif /* __SGI_STL_ALGORITHM */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/alloc.h b/contrib/libstdc++/stl/alloc.h new file mode 100644 index 0000000..7cc9610 --- /dev/null +++ b/contrib/libstdc++/stl/alloc.h @@ -0,0 +1,44 @@ +/* + * 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 <stl_config.h> +#endif +#ifndef __SGI_STL_INTERNAL_ALLOC_H +#include <stl_alloc.h> +#endif + +#ifdef __STL_USE_NAMESPACES + +using __STD::__malloc_alloc_template; +using __STD::malloc_alloc; +using __STD::simple_alloc; +using __STD::debug_alloc; +using __STD::__default_alloc_template; +using __STD::alloc; +using __STD::single_client_alloc; +#ifdef __STL_STATIC_TEMPLATE_MEMBER_BUG +using __STD::__malloc_alloc_oom_handler; +#endif /* __STL_STATIC_TEMPLATE_MEMBER_BUG */ + + +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_ALLOC_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/bvector.h b/contrib/libstdc++/stl/bvector.h new file mode 100644 index 0000000..03a3fb1 --- /dev/null +++ b/contrib/libstdc++/stl/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 <vector.h> +#else +#include <algobase.h> +#include <alloc.h> +#endif + +#include <stl_bvector.h> + +#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/contrib/libstdc++/stl/defalloc.h b/contrib/libstdc++/stl/defalloc.h new file mode 100644 index 0000000..49690f8 --- /dev/null +++ b/contrib/libstdc++/stl/defalloc.h @@ -0,0 +1,86 @@ +/* + * + * 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. +// +// DO NOT USE THIS FILE unless you have an old container implementation +// that requires an allocator with the HP-style interface. SGI STL +// uses a different allocator interface. SGI-style allocators are not +// parametrized with respect to the object type; they traffic in void * +// pointers. This file is not included by any other SGI STL header. + +#ifndef DEFALLOC_H +#define DEFALLOC_H + +#include <new.h> +#include <stddef.h> +#include <stdlib.h> +#include <limits.h> +#include <iostream.h> +#include <algobase.h> + + +template <class T> +inline T* allocate(ptrdiff_t size, T*) { + set_new_handler(0); + T* tmp = (T*)(::operator new((size_t)(size * sizeof(T)))); + if (tmp == 0) { + cerr << "out of memory" << endl; + exit(1); + } + return tmp; +} + + +template <class T> +inline void deallocate(T* buffer) { + ::operator delete(buffer); +} + +template <class T> +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<void> { +public: + typedef void* pointer; +}; + + + +#endif diff --git a/contrib/libstdc++/stl/deque b/contrib/libstdc++/stl/deque new file mode 100644 index 0000000..61654ac --- /dev/null +++ b/contrib/libstdc++/stl/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 <stl_algobase.h> +#include <stl_alloc.h> +#include <stl_construct.h> +#include <stl_uninitialized.h> +#include <stl_deque.h> + +#endif /* __SGI_STL_DEQUE */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/deque.h b/contrib/libstdc++/stl/deque.h new file mode 100644 index 0000000..ede38b1 --- /dev/null +++ b/contrib/libstdc++/stl/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 <algobase.h> +#include <alloc.h> +#include <stl_deque.h> + +#ifdef __STL_USE_NAMESPACES +using __STD::deque; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_DEQUE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/function.h b/contrib/libstdc++/stl/function.h new file mode 100644 index 0000000..6474dd9 --- /dev/null +++ b/contrib/libstdc++/stl/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 <stl_config.h> +#endif +#ifndef __SGI_STL_INTERNAL_RELOPS +#include <stl_relops.h> +#endif +#include <stddef.h> +#ifndef __SGI_STL_INTERNAL_FUNCTION_H +#include <stl_function.h> +#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/contrib/libstdc++/stl/functional b/contrib/libstdc++/stl/functional new file mode 100644 index 0000000..d046dbb --- /dev/null +++ b/contrib/libstdc++/stl/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 <stl_config.h> +#include <stddef.h> +#include <stl_function.h> + +#endif /* __SGI_STL_FUNCTIONAL */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/hash_map b/contrib/libstdc++/stl/hash_map new file mode 100644 index 0000000..f7421e0 --- /dev/null +++ b/contrib/libstdc++/stl/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 <stl_hashtable.h> +#endif + +#include <stl_hash_map.h> + +#endif /* __SGI_STL_HASH_MAP */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/hash_map.h b/contrib/libstdc++/stl/hash_map.h new file mode 100644 index 0000000..81cb578 --- /dev/null +++ b/contrib/libstdc++/stl/hash_map.h @@ -0,0 +1,48 @@ +/* + * 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 <stl_hashtable.h> +#endif + +#include <stl_hash_map.h> + +#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/contrib/libstdc++/stl/hash_set b/contrib/libstdc++/stl/hash_set new file mode 100644 index 0000000..2244f47 --- /dev/null +++ b/contrib/libstdc++/stl/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 <stl_hashtable.h> +#endif + +#include <stl_hash_set.h> + +#endif /* __SGI_STL_HASH_SET */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/hash_set.h b/contrib/libstdc++/stl/hash_set.h new file mode 100644 index 0000000..c938ccc --- /dev/null +++ b/contrib/libstdc++/stl/hash_set.h @@ -0,0 +1,43 @@ +/* + * 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 <stl_hashtable.h> +#endif + +#include <stl_hash_set.h> + +#ifdef __STL_USE_NAMESPACES +using __STD::hash; +using __STD::hashtable; +using __STD::hash_set; +using __STD::hash_multiset; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_HASH_SET_H */ diff --git a/contrib/libstdc++/stl/hashtable.h b/contrib/libstdc++/stl/hashtable.h new file mode 100644 index 0000000..15dbfc9 --- /dev/null +++ b/contrib/libstdc++/stl/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 <stl_hashtable.h> +#include <algo.h> +#include <alloc.h> +#include <vector.h> + +#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/contrib/libstdc++/stl/heap.h b/contrib/libstdc++/stl/heap.h new file mode 100644 index 0000000..2ec93c0 --- /dev/null +++ b/contrib/libstdc++/stl/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 <stl_config.h> +#include <stl_heap.h> + +#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/contrib/libstdc++/stl/iterator b/contrib/libstdc++/stl/iterator new file mode 100644 index 0000000..90e6c9c --- /dev/null +++ b/contrib/libstdc++/stl/iterator @@ -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_ITERATOR +#define __SGI_STL_ITERATOR + +#include <stl_config.h> +#include <stl_relops.h> +#include <stddef.h> +#include <iostream.h> +#include <stl_iterator.h> + +#endif /* __SGI_STL_ITERATOR */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/iterator.h b/contrib/libstdc++/stl/iterator.h new file mode 100644 index 0000000..f8a0237 --- /dev/null +++ b/contrib/libstdc++/stl/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 <function.h> +#endif +#include <stddef.h> +#include <iostream.h> +#ifndef __SGI_STL_INTERNAL_ITERATOR_H +#include <stl_iterator.h> +#endif +#ifndef __TYPE_TRAITS_H +#include <type_traits.h> +#endif +#ifndef __SGI_STL_INTERNAL_CONSTRUCT_H +#include <stl_construct.h> +#endif +#ifndef __SGI_STL_INTERNAL_RAW_STORAGE_ITERATOR_H +#include <stl_raw_storage_iter.h> +#endif + +#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/contrib/libstdc++/stl/list b/contrib/libstdc++/stl/list new file mode 100644 index 0000000..5294f39 --- /dev/null +++ b/contrib/libstdc++/stl/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 <stl_algobase.h> +#include <stl_alloc.h> +#include <stl_construct.h> +#include <stl_uninitialized.h> +#include <stl_list.h> + +#endif /* __SGI_STL_LIST */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/list.h b/contrib/libstdc++/stl/list.h new file mode 100644 index 0000000..4e6ee0b --- /dev/null +++ b/contrib/libstdc++/stl/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 <algobase.h> +#include <alloc.h> +#include <stl_list.h> + +#ifdef __STL_USE_NAMESPACES +using __STD::list; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_LIST_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/map b/contrib/libstdc++/stl/map new file mode 100644 index 0000000..4cfb765 --- /dev/null +++ b/contrib/libstdc++/stl/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 <stl_tree.h> +#endif +#include <stl_map.h> +#include <stl_multimap.h> + +#endif /* __SGI_STL_MAP */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/map.h b/contrib/libstdc++/stl/map.h new file mode 100644 index 0000000..a89bd31 --- /dev/null +++ b/contrib/libstdc++/stl/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 <tree.h> +#include <stl_map.h> + +#ifdef __STL_USE_NAMESPACES +using __STD::map; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_MAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/memory b/contrib/libstdc++/stl/memory new file mode 100644 index 0000000..a806588 --- /dev/null +++ b/contrib/libstdc++/stl/memory @@ -0,0 +1,89 @@ +/* + * 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 <stl_algobase.h> +#include <stl_alloc.h> +#include <stl_construct.h> +#include <stl_tempbuf.h> +#include <stl_uninitialized.h> +#include <stl_raw_storage_iter.h> + +// Note: auto_ptr is commented out in this release because the details +// of the interface are still being discussed by the C++ standardization +// committee. It will be included once the iterface is finalized. + +#if 0 +#if defined(_MUTABLE_IS_KEYWORD) && defined(_EXPLICIT_IS_KEYWORD) && \ + defined(__STL_MEMBER_TEMPLATES) + +__STL_BEGIN_NAMESPACE + +template <class X> class auto_ptr { +private: + X* ptr; + mutable bool owns; +public: + typedef X element_type; + explicit auto_ptr(X* p = 0) __STL_NOTHROW : ptr(p), owns(p) {} + auto_ptr(const auto_ptr& a) __STL_NOTHROW : ptr(a.ptr), owns(a.owns) { + a.owns = 0; + } + template <class T> auto_ptr(const auto_ptr<T>& a) __STL_NOTHROW + : ptr(a.ptr), owns(a.owns) { + a.owns = 0; + } + + auto_ptr& operator=(const auto_ptr& a) __STL_NOTHROW { + if (&a != this) { + if (owns) + delete ptr; + owns = a.owns; + ptr = a.ptr; + a.owns = 0; + } + } + template <class T> auto_ptr& operator=(const auto_ptr<T>& a) __STL_NOTHROW { + if (&a != this) { + if (owns) + delete ptr; + owns = a.owns; + ptr = a.ptr; + a.owns = 0; + } + } + ~auto_ptr() { + if (owns) + delete ptr; + } + + X& operator*() const __STL_NOTHROW { return *ptr; } + X* operator->() const __STL_NOTHROW { return ptr; } + X* get() const __STL_NOTHROW { return ptr; } + X* release const __STL_NOTHROW { owns = false; return ptr } +}; + +__STL_END_NAMESPACE +#endif /* mutable && explicit && member templates */ +#endif /* 0 */ + + +#endif /* __SGI_STL_MEMORY */ + + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/multimap.h b/contrib/libstdc++/stl/multimap.h new file mode 100644 index 0000000..1a8ec4a --- /dev/null +++ b/contrib/libstdc++/stl/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 <tree.h> +#include <stl_multimap.h> + +#ifdef __STL_USE_NAMESPACES +using __STD::multimap; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_MULTIMAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/multiset.h b/contrib/libstdc++/stl/multiset.h new file mode 100644 index 0000000..3024fd7 --- /dev/null +++ b/contrib/libstdc++/stl/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 <tree.h> +#include <stl_multiset.h> + +#ifdef __STL_USE_NAMESPACES +using __STD::multiset; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_MULTISET_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/numeric b/contrib/libstdc++/stl/numeric new file mode 100644 index 0000000..7f048e1 --- /dev/null +++ b/contrib/libstdc++/stl/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 <stl_config.h> +#include <stl_relops.h> +#include <stddef.h> +#include <iostream.h> +#include <stl_iterator.h> +#include <stl_function.h> +#include <stl_numeric.h> + +#endif /* __SGI_STL_NUMERIC */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/pair.h b/contrib/libstdc++/stl/pair.h new file mode 100644 index 0000000..00f5cad --- /dev/null +++ b/contrib/libstdc++/stl/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 <stl_config.h> +#endif +#ifndef __SGI_STL_INTERNAL_RELOPS +#include <stl_relops.h> +#endif +#ifndef __SGI_STL_INTERNAL_PAIR_H +#include <stl_pair.h> +#endif + +#ifdef __STL_USE_NAMESPACES + +using __STD::pair; +using __STD::make_pair; + +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_PAIR_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/pthread_alloc b/contrib/libstdc++/stl/pthread_alloc new file mode 100644 index 0000000..4ca9d9e --- /dev/null +++ b/contrib/libstdc++/stl/pthread_alloc @@ -0,0 +1,347 @@ +/* + * 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 n thread B. But this effectively transfers ownership of the memory, +// so that it can only be reallocated by thread B. Thus this can effectively +// result in a storage leak if it's done on a regular basis. +// It can also result in frequent sharing of +// cache lines among processors, with potentially serious performance +// consequences. + +#include <stl_config.h> +#include <stl_alloc.h> +#ifndef __RESTRICT +# define __RESTRICT +#endif + +__STL_BEGIN_NAMESPACE + +// Note that this class has nonstatic members. We instantiate it once +// per thread. +template <bool dummy> +class __pthread_alloc_template { + +private: + enum {ALIGN = 8}; + enum {MAX_BYTES = 128}; // power of 2 + enum {NFREELISTS = MAX_BYTES/ALIGN}; + + union obj { + union obj * free_list_link; + char client_data[ALIGN]; /* The client sees this. */ + }; + + // Per instance state + obj* volatile free_list[NFREELISTS]; + __pthread_alloc_template<dummy>* next; // Free list link + + static size_t ROUND_UP(size_t bytes) { + return (((bytes) + ALIGN-1) & ~(ALIGN - 1)); + } + static size_t FREELIST_INDEX(size_t bytes) { + return (((bytes) + ALIGN-1)/ALIGN - 1); + } + + // Returns an object of size n, and optionally adds to size n free list. + void *refill(size_t n); + // Allocates a chunk for nobjs of size "size". nobjs may be reduced + // if it is inconvenient to allocate the requested number. + static char *chunk_alloc(size_t size, int &nobjs); + + // Chunk allocation state. And other shared state. + // Protected by chunk_allocator_lock. + static pthread_mutex_t chunk_allocator_lock; + static char *start_free; + static char *end_free; + static size_t heap_size; + static __pthread_alloc_template<dummy>* free_allocators; + static pthread_key_t key; + static bool key_initialized; + // Pthread key under which allocator is stored. + // Allocator instances that are currently unclaimed by any thread. + static void destructor(void *instance); + // Function to be called on thread exit to reclaim allocator + // instance. + static __pthread_alloc_template<dummy> *new_allocator(); + // Return a recycled or new allocator instance. + static __pthread_alloc_template<dummy> *get_allocator_instance(); + // ensure that the current thread has an associated + // allocator instance. + class lock { + public: + lock () { pthread_mutex_lock(&chunk_allocator_lock); } + ~lock () { pthread_mutex_unlock(&chunk_allocator_lock); } + }; + friend class lock; + + +public: + + __pthread_alloc_template() : next(0) + { + memset((void *)free_list, 0, NFREELISTS * sizeof(obj *)); + } + + /* n must be > 0 */ + static void * allocate(size_t n) + { + obj * volatile * my_free_list; + obj * __RESTRICT result; + __pthread_alloc_template<dummy>* a; + + if (n > MAX_BYTES) { + return(malloc(n)); + } + if (!key_initialized || + !(a = (__pthread_alloc_template<dummy>*) + pthread_getspecific(key))) { + a = get_allocator_instance(); + } + my_free_list = a -> free_list + FREELIST_INDEX(n); + result = *my_free_list; + if (result == 0) { + void *r = a -> refill(ROUND_UP(n)); + return r; + } + *my_free_list = result -> free_list_link; + return (result); + }; + + /* p may not be 0 */ + static void deallocate(void *p, size_t n) + { + obj *q = (obj *)p; + obj * volatile * my_free_list; + __pthread_alloc_template<dummy>* a; + + if (n > MAX_BYTES) { + free(p); + return; + } + if (!key_initialized || + !(a = (__pthread_alloc_template<dummy>*) + pthread_getspecific(key))) { + a = get_allocator_instance(); + } + my_free_list = a->free_list + FREELIST_INDEX(n); + q -> free_list_link = *my_free_list; + *my_free_list = q; + } + + static void * reallocate(void *p, size_t old_sz, size_t new_sz); + +} ; + +typedef __pthread_alloc_template<false> pthread_alloc; + + +template <bool dummy> +void __pthread_alloc_template<dummy>::destructor(void * instance) +{ + __pthread_alloc_template<dummy>* a = + (__pthread_alloc_template<dummy>*)instance; + a -> next = free_allocators; + free_allocators = a; +} + +template <bool dummy> +__pthread_alloc_template<dummy>* +__pthread_alloc_template<dummy>::new_allocator() +{ + if (0 != free_allocators) { + __pthread_alloc_template<dummy>* result = free_allocators; + free_allocators = free_allocators -> next; + return result; + } else { + return new __pthread_alloc_template<dummy>; + } +} + +template <bool dummy> +__pthread_alloc_template<dummy>* +__pthread_alloc_template<dummy>::get_allocator_instance() +{ + __pthread_alloc_template<dummy>* result; + if (!key_initialized) { + /*REFERENCED*/ + lock lock_instance; + if (!key_initialized) { + if (pthread_key_create(&key, destructor)) { + abort(); // failed + } + key_initialized = true; + } + } + result = new_allocator(); + if (pthread_setspecific(key, result)) abort(); + return result; +} + +/* We allocate memory in large chunks in order to avoid fragmenting */ +/* the malloc heap too much. */ +/* We assume that size is properly aligned. */ +template <bool dummy> +char *__pthread_alloc_template<dummy> +::chunk_alloc(size_t size, int &nobjs) +{ + { + char * result; + size_t total_bytes; + size_t bytes_left; + /*REFERENCED*/ + lock lock_instance; // Acquire lock for this routine + + total_bytes = size * nobjs; + bytes_left = end_free - start_free; + if (bytes_left >= total_bytes) { + result = start_free; + start_free += total_bytes; + return(result); + } else if (bytes_left >= size) { + nobjs = bytes_left/size; + total_bytes = size * nobjs; + result = start_free; + start_free += total_bytes; + return(result); + } else { + size_t bytes_to_get = 2 * total_bytes + ROUND_UP(heap_size >> 4); + // Try to make use of the left-over piece. + if (bytes_left > 0) { + __pthread_alloc_template<dummy>* a = + (__pthread_alloc_template<dummy>*)pthread_getspecific(key); + obj * volatile * my_free_list = + a->free_list + FREELIST_INDEX(bytes_left); + + ((obj *)start_free) -> free_list_link = *my_free_list; + *my_free_list = (obj *)start_free; + } +# ifdef _SGI_SOURCE + // Try to get memory that's aligned on something like a + // cache line boundary, so as to avoid parceling out + // parts of the same line to different threads and thus + // possibly different processors. + { + const int cache_line_size = 128; // probable upper bound + bytes_to_get &= ~(cache_line_size-1); + start_free = (char *)memalign(cache_line_size, bytes_to_get); + if (0 == start_free) { + start_free = (char *)malloc_alloc::allocate(bytes_to_get); + } + } +# else /* !SGI_SOURCE */ + start_free = (char *)malloc_alloc::allocate(bytes_to_get); +# endif + heap_size += bytes_to_get; + end_free = start_free + bytes_to_get; + } + } + // lock is released here + return(chunk_alloc(size, nobjs)); +} + + +/* Returns an object of size n, and optionally adds to size n free list.*/ +/* We assume that n is properly aligned. */ +/* We hold the allocation lock. */ +template <bool dummy> +void *__pthread_alloc_template<dummy> +::refill(size_t n) +{ + int nobjs = 128; + char * chunk = chunk_alloc(n, nobjs); + obj * volatile * my_free_list; + obj * result; + obj * current_obj, * next_obj; + int i; + + if (1 == nobjs) { + return(chunk); + } + my_free_list = free_list + FREELIST_INDEX(n); + + /* Build free list in chunk */ + result = (obj *)chunk; + *my_free_list = next_obj = (obj *)(chunk + n); + for (i = 1; ; i++) { + current_obj = next_obj; + next_obj = (obj *)((char *)next_obj + n); + if (nobjs - 1 == i) { + current_obj -> free_list_link = 0; + break; + } else { + current_obj -> free_list_link = next_obj; + } + } + return(result); +} + +template <bool dummy> +void *__pthread_alloc_template<dummy> +::reallocate(void *p, size_t old_sz, size_t new_sz) +{ + void * result; + size_t copy_sz; + + if (old_sz > MAX_BYTES && new_sz > MAX_BYTES) { + return(realloc(p, new_sz)); + } + if (ROUND_UP(old_sz) == ROUND_UP(new_sz)) return(p); + result = allocate(new_sz); + copy_sz = new_sz > old_sz? old_sz : new_sz; + memcpy(result, p, copy_sz); + deallocate(p, old_sz); + return(result); +} + +template <bool dummy> +__pthread_alloc_template<dummy> * +__pthread_alloc_template<dummy>::free_allocators = 0; + +template <bool dummy> +pthread_key_t __pthread_alloc_template<dummy>::key; + +template <bool dummy> +bool __pthread_alloc_template<dummy>::key_initialized = false; + +template <bool dummy> +pthread_mutex_t __pthread_alloc_template<dummy>::chunk_allocator_lock += PTHREAD_MUTEX_INITIALIZER; + +template <bool dummy> +char *__pthread_alloc_template<dummy> +::start_free = 0; + +template <bool dummy> +char *__pthread_alloc_template<dummy> +::end_free = 0; + +template <bool dummy> +size_t __pthread_alloc_template<dummy> +::heap_size = 0; + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_PTHREAD_ALLOC */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/pthread_alloc.h b/contrib/libstdc++/stl/pthread_alloc.h new file mode 100644 index 0000000..0a2debb --- /dev/null +++ b/contrib/libstdc++/stl/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 <pthread_alloc> + +#ifdef __STL_USE_NAMESPACES + +using __STD::__pthread_alloc_template; +using __STL::pthread_alloc; + +#endif /* __STL_USE_NAMESPACES */ + + +#endif /* __SGI_STL_PTHREAD_ALLOC_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/queue b/contrib/libstdc++/stl/queue new file mode 100644 index 0000000..f9417fb --- /dev/null +++ b/contrib/libstdc++/stl/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 <stl_algobase.h> +#include <stl_alloc.h> +#include <stl_construct.h> +#include <stl_uninitialized.h> +#include <stl_vector.h> +#include <stl_bvector.h> +#include <stl_heap.h> +#include <stl_deque.h> +#include <stl_function.h> +#include <stl_queue.h> + +#endif /* __SGI_STL_QUEUE */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/rope b/contrib/libstdc++/stl/rope new file mode 100644 index 0000000..9ef7382 --- /dev/null +++ b/contrib/libstdc++/stl/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 <stl_algobase.h> +#include <tempbuf.h> +#include <stl_algo.h> +#include <stl_function.h> +#include <stl_numeric.h> +#include <stl_alloc.h> +#include <stl_construct.h> +#include <stl_uninitialized.h> +#include <stl_hash_fun.h> +#include <stl_rope.h> + +#endif /* __SGI_STL_ROPE */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/rope.h b/contrib/libstdc++/stl/rope.h new file mode 100644 index 0000000..d767fa3 --- /dev/null +++ b/contrib/libstdc++/stl/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 <hashtable.h> +#include <stl_rope.h> + +#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/contrib/libstdc++/stl/ropeimpl.h b/contrib/libstdc++/stl/ropeimpl.h new file mode 100644 index 0000000..b4af525 --- /dev/null +++ b/contrib/libstdc++/stl/ropeimpl.h @@ -0,0 +1,1537 @@ +/* + * 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 <stdio.h> +# include <iostream.h> + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1174 +#endif + +// Set buf_start, buf_end, and buf_ptr appropriately, filling tmp_buf +// if necessary. Assumes path_end[leaf_index] and leaf_pos are correct. +// Results in a valid buf_ptr if the iterator can be legitimately +// dereferenced. +template <class charT, class Alloc> +void __rope_iterator_base<charT,Alloc>::setbuf +(__rope_iterator_base<charT,Alloc> &x) +{ + const RopeBase * leaf = x.path_end[x.leaf_index]; + size_t leaf_pos = x.leaf_pos; + size_t pos = x.current_pos; + + switch(leaf -> tag) { + case RopeBase::leaf: + x.buf_start = ((__rope_RopeLeaf<charT,Alloc> *)leaf) -> data; + x.buf_ptr = x.buf_start + (pos - leaf_pos); + x.buf_end = x.buf_start + leaf -> size; + break; + case RopeBase::function: + case RopeBase::substringfn: + { + size_t len = iterator_buf_len; + size_t buf_start_pos = leaf_pos; + size_t leaf_end = leaf_pos + leaf -> size; + char_producer<charT> *fn = + ((__rope_RopeFunction<charT,Alloc> *)leaf) -> fn; + + if (buf_start_pos + len <= pos) { + buf_start_pos = pos - len/4; + if (buf_start_pos + len > leaf_end) { + buf_start_pos = leaf_end - len; + } + } + if (buf_start_pos + len > leaf_end) { + len = leaf_end - buf_start_pos; + } + (*fn)(buf_start_pos - leaf_pos, len, x.tmp_buf); + x.buf_ptr = x.tmp_buf + (pos - buf_start_pos); + x.buf_start = x.tmp_buf; + x.buf_end = x.tmp_buf + len; + } + break; + default: + __stl_assert(0); + } +} + +// Set path and buffer inside a rope iterator. We assume that +// pos and root are already set. +template <class charT, class Alloc> +void __rope_iterator_base<charT,Alloc>::setcache +(__rope_iterator_base<charT,Alloc> &x) +{ + const RopeBase * path[RopeBase::max_rope_depth+1]; + const RopeBase * curr_rope; + int curr_depth = -1; /* index into path */ + size_t curr_start_pos = 0; + size_t pos = x.current_pos; + unsigned char dirns = 0; // Bit vector indicating right turns in the path + + __stl_assert(pos <= x.root -> size); + if (pos >= x.root -> size) { + x.buf_ptr = 0; + return; + } + curr_rope = x.root; + if (0 != curr_rope -> c_string) { + /* Treat the root as a leaf. */ + x.buf_start = curr_rope -> c_string; + x.buf_end = curr_rope -> c_string + curr_rope -> size; + x.buf_ptr = curr_rope -> c_string + pos; + x.path_end[0] = curr_rope; + x.leaf_index = 0; + x.leaf_pos = 0; + return; + } + for(;;) { + ++curr_depth; + __stl_assert(curr_depth <= RopeBase::max_rope_depth); + path[curr_depth] = curr_rope; + switch(curr_rope -> tag) { + case RopeBase::leaf: + case RopeBase::function: + case RopeBase::substringfn: + x.leaf_pos = curr_start_pos; + goto done; + case RopeBase::concat: + { + __rope_RopeConcatenation<charT,Alloc> *c = + (__rope_RopeConcatenation<charT,Alloc> *)curr_rope; + RopeBase * left = c -> left; + size_t left_len = left -> size; + + dirns <<= 1; + if (pos >= curr_start_pos + left_len) { + dirns |= 1; + curr_rope = c -> right; + curr_start_pos += left_len; + } else { + curr_rope = left; + } + } + break; + } + } + done: + // Copy last section of path into path_end. + { + int i = -1; + int j = curr_depth + 1 - path_cache_len; + + if (j < 0) j = 0; + while (j <= curr_depth) { + x.path_end[++i] = path[j++]; + } + x.leaf_index = i; + } + x.path_directions = dirns; + setbuf(x); +} + +// Specialized version of the above. Assumes that +// the path cache is valid for the previous position. +template <class charT, class Alloc> +void __rope_iterator_base<charT,Alloc>::setcache_for_incr +(__rope_iterator_base<charT,Alloc> &x) +{ + int current_index = x.leaf_index; + const RopeBase * current_node = x.path_end[current_index]; + size_t len = current_node -> size; + size_t node_start_pos = x.leaf_pos; + unsigned char dirns = x.path_directions; + __rope_RopeConcatenation<charT,Alloc> * c; + + __stl_assert(x.current_pos <= x.root -> size); + if (x.current_pos - node_start_pos < len) { + /* More stuff in this leaf, we just didn't cache it. */ + setbuf(x); + return; + } + __stl_assert(node_start_pos + len == x.current_pos); + // node_start_pos is starting position of last_node. + while (--current_index >= 0) { + if (!(dirns & 1) /* Path turned left */) break; + current_node = x.path_end[current_index]; + c = (__rope_RopeConcatenation<charT,Alloc> *)current_node; + // Otherwise we were in the right child. Thus we should pop + // the concatenation node. + node_start_pos -= c -> left -> size; + dirns >>= 1; + } + if (current_index < 0) { + // We underflowed the cache. Punt. + setcache(x); + return; + } + current_node = x.path_end[current_index]; + c = (__rope_RopeConcatenation<charT,Alloc> *)current_node; + // current_node is a concatenation node. We are positioned on the first + // character in its right child. + // node_start_pos is starting position of current_node. + node_start_pos += c -> left -> size; + current_node = c -> right; + x.path_end[++current_index] = current_node; + dirns |= 1; + while (RopeBase::concat == current_node -> tag) { + ++current_index; + if (path_cache_len == current_index) { + int i; + for (i = 0; i < path_cache_len-1; i++) { + x.path_end[i] = x.path_end[i+1]; + } + --current_index; + } + current_node = + ((__rope_RopeConcatenation<charT,Alloc> *)current_node) -> left; + x.path_end[current_index] = current_node; + dirns <<= 1; + // node_start_pos is unchanged. + } + x.leaf_index = current_index; + x.leaf_pos = node_start_pos; + x.path_directions = dirns; + setbuf(x); +} + +template <class charT, class Alloc> +void __rope_iterator_base<charT,Alloc>::incr(size_t n) { + current_pos += n; + if (0 != buf_ptr) { + size_t chars_left = buf_end - buf_ptr; + if (chars_left > n) { + buf_ptr += n; + } else if (chars_left == n) { + buf_ptr += n; + setcache_for_incr(*this); + } else { + buf_ptr = 0; + } + } +} + +template <class charT, class Alloc> +void __rope_iterator_base<charT,Alloc>::decr(size_t n) { + if (0 != buf_ptr) { + size_t chars_left = buf_ptr - buf_start; + if (chars_left >= n) { + buf_ptr -= n; + } else { + buf_ptr = 0; + } + } + current_pos -= n; +} + +template <class charT, class Alloc> +void __rope_iterator<charT,Alloc>::check() { + if (root_rope -> tree_ptr != root) { + // Rope was modified. Get things fixed up. + RopeBase::unref(root); + root = root_rope -> tree_ptr; + RopeBase::ref(root); + buf_ptr = 0; + } +} + +template <class charT, class Alloc> +inline __rope_const_iterator<charT, Alloc>::__rope_const_iterator +(const __rope_iterator<charT,Alloc> & x) +: __rope_iterator_base<charT,Alloc>(x) { } + +template <class charT, class Alloc> +inline __rope_iterator<charT,Alloc>::__rope_iterator +(rope<charT,Alloc>& r, size_t pos) + : __rope_iterator_base<charT,Alloc>(r.tree_ptr, pos), root_rope(&r) { + RopeBase::ref(root); +} + +template <class charT, class Alloc> +inline size_t rope<charT,Alloc>::char_ptr_len(const charT *s) +{ + const charT *p = s; + + while (!is0(*p)) { ++p; } + return(p - s); +} + +template <class charT, class Alloc> +rope<charT,Alloc>::RopeLeaf * +rope<charT,Alloc>::RopeLeaf_from_char_ptr(__GC_CONST charT *s, size_t size) +{ + RopeLeaf *t = LAlloc::allocate(); + + t -> tag = RopeBase::leaf; + if (__is_basic_char_type((charT *)0)) { + // already eos terminated. + t -> c_string = s; + } else { + t -> c_string = 0; + } + t -> is_balanced = true; + t -> depth = 0; + t -> size = size; + t -> data = s; +# ifndef __GC + t -> refcount = 1; + t -> init_refcount_lock(); +# endif + return (t); +} + +# ifdef __GC +template <class charT, class Alloc> +void __rope_RopeBase<charT,Alloc>::fn_finalization_proc(void * tree, void *) +{ + delete ((__rope_RopeFunction<charT,Alloc> *)tree) -> fn; +} +# endif + +template <class charT, class Alloc> +rope<charT,Alloc>::RopeFunction * +rope<charT,Alloc>::RopeFunction_from_fn +(char_producer<charT> *fn, size_t size, bool delete_fn) +{ + if (0 == size) return 0; + RopeFunction *t = FAlloc::allocate(); + t -> tag = RopeBase::function; + t -> c_string = 0; + t -> is_balanced = true; + t -> depth = 0; + t -> size = size; + t -> fn = fn; +# ifdef __GC + if (delete_fn) { + GC_REGISTER_FINALIZER(t, RopeBase::fn_finalization_proc, 0, 0, 0); + } +# else + t -> delete_when_done = delete_fn; + t -> refcount = 1; + t -> init_refcount_lock(); +# endif + return (t); +} + +#ifndef __GC + +template <class charT, class Alloc> +inline void __rope_RopeBase<charT,Alloc>::free_c_string() +{ + charT * cstr = c_string; + if (0 != cstr) { + size_t sz = size + 1; + destroy(cstr, cstr + sz); + DataAlloc::deallocate(cstr, sz); + } +} + +template <class charT, class Alloc> +inline void __rope_RopeBase<charT,Alloc>::free_string(charT* s, size_t n) +{ + if (!__is_basic_char_type((charT *)0)) { + destroy(s, s + n); + } + DataAlloc::deallocate(s, rounded_up_size(n)); +} + +template <class charT, class Alloc> +void __rope_RopeBase<charT,Alloc>::free_tree() +{ + switch(tag) { + case leaf: + { + __rope_RopeLeaf<charT,Alloc> * l = + (__rope_RopeLeaf<charT,Alloc> *)this; + charT * d = l -> data; + + if (d != c_string) { + free_c_string(); + } + free_string(d, size); + LAlloc::deallocate(l); + } + break; + case concat: + { + __rope_RopeConcatenation<charT,Alloc> * c = + (__rope_RopeConcatenation<charT,Alloc> *)this; + __rope_RopeBase * left = c -> left; + __rope_RopeBase * right = c -> right; + free_c_string(); + left -> unref_nonnil(); + right -> unref_nonnil(); + CAlloc::deallocate(c); + } + break; + case function: + { + __rope_RopeFunction<charT,Alloc> * fn = + (__rope_RopeFunction<charT,Alloc> *)this; + free_c_string(); + if ( fn -> delete_when_done) { + delete fn -> fn; + } + FAlloc::deallocate(fn); + break; + } + case substringfn: + { + __rope_RopeSubstring<charT,Alloc> * ss = + (__rope_RopeSubstring<charT,Alloc> *)this; + __rope_RopeBase *base = ss -> base; + free_c_string(); + base -> unref_nonnil(); + SAlloc::deallocate(ss); + break; + } + } +} +#else + +template <class charT, class Alloc> +inline void __rope_RopeBase<charT,Alloc>::free_string(charT* s, size_t n) +{} + +#endif + + +// Concatenate a C string onto a leaf rope by copying the rope data. +// Used for short ropes. +template <class charT, class Alloc> +rope<charT,Alloc>::RopeLeaf * +rope<charT,Alloc>::leaf_concat_char_iter + (RopeLeaf * r, const charT * iter, size_t len) +{ + size_t old_len = r -> size; + charT * new_data = (charT *) + DataAlloc::allocate(rounded_up_size(old_len + len)); + RopeLeaf * result; + + uninitialized_copy_n(r -> data, old_len, new_data); + uninitialized_copy_n(iter, len, new_data + old_len); + __cond_store_eos(new_data[old_len + len]); + __STL_TRY { + result = RopeLeaf_from_char_ptr(new_data, old_len + len); + } + __STL_UNWIND(RopeBase::free_string(new_data, old_len + len)); + return result; +} + +#ifndef __GC +// As above, but it's OK to clobber original if refcount is 1 +template <class charT, class Alloc> +rope<charT,Alloc>::RopeLeaf * +rope<charT,Alloc>::destr_leaf_concat_char_iter + (RopeLeaf * r, const charT * iter, size_t len) +{ + __stl_assert(r -> refcount >= 1); + if (r -> refcount > 1) return leaf_concat_char_iter(r, iter, len); + size_t old_len = r -> size; + if (allocated_capacity(old_len) >= old_len + len) { + // The space has been partially initialized for the standard + // character types. But that doesn't matter for those types. + uninitialized_copy_n(iter, len, r -> data + old_len); + if (__is_basic_char_type((charT *)0)) { + __cond_store_eos(r -> data[old_len + len]); + __stl_assert(r -> c_string == r -> data); + } else if (r -> c_string != r -> data && 0 != r -> c_string) { + r -> free_c_string(); + r -> c_string = 0; + } + r -> size = old_len + len; + __stl_assert(r -> refcount == 1); + r -> refcount = 2; + return r; + } else { + RopeLeaf * result = leaf_concat_char_iter(r, iter, len); + __stl_assert(result -> 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 <class charT, class Alloc> +rope<charT,Alloc>::RopeBase * +rope<charT,Alloc>::tree_concat (RopeBase * left, RopeBase * right) +{ + RopeConcatenation * result = CAlloc::allocate(); + unsigned char child_depth = left -> depth; + size_t rsize; + + result -> tag = RopeBase::concat; + result -> c_string = 0; + result -> is_balanced = false; + result -> size = rsize = left -> size + right -> size; + if (right -> depth > child_depth) child_depth = right -> depth; + unsigned char depth = (unsigned char)(child_depth + 1); + result -> depth = depth; + result -> left = left; + result -> right = right; +# ifndef __GC + result -> refcount = 1; + result -> init_refcount_lock(); +# endif + if (depth > 20 && (rsize < 1000 || depth > RopeBase::max_rope_depth)) { + RopeBase * balanced; + + __STL_TRY { + balanced = balance(result); +# ifndef __GC + if (result != balanced) { + __stl_assert(1 == result -> refcount + && 1 == balanced -> refcount); + } +# endif + result -> unref_nonnil(); + } + __STL_UNWIND(CAlloc::deallocate(result)); + // In case of exception, we need to deallocate + // otherwise dangling result node. But caller + // still owns its children. Thus unref is + // inappropriate. + return balanced; + } else { + return result; + } +} + +template <class charT, class Alloc> +rope<charT,Alloc>::RopeBase * rope<charT,Alloc>::concat_char_iter + (RopeBase * r, const charT *s, size_t slen) +{ + RopeBase *result; + if (0 == slen) { + ref(r); + return r; + } + if (0 == r) return RopeLeaf_from_unowned_char_ptr(s, slen); + if (RopeBase::leaf == r -> tag && r -> size + slen <= copy_max) { + result = leaf_concat_char_iter((RopeLeaf *)r, s, slen); +# ifndef __GC + __stl_assert(1 == result -> refcount); +# endif + return result; + } + if (RopeBase::concat == r -> tag + && RopeBase::leaf == ((RopeConcatenation *)r) -> right -> tag) { + RopeLeaf *right = (RopeLeaf *)(((RopeConcatenation *)r) -> right); + if (right -> size + slen <= copy_max) { + RopeBase * left = ((RopeConcatenation *)r) -> left; + RopeBase * nright = leaf_concat_char_iter((RopeLeaf *)right, s, slen); + left -> ref_nonnil(); + __STL_TRY { + result = tree_concat(left, nright); + } + __STL_UNWIND(unref(left); unref(nright)); +# ifndef __GC + __stl_assert(1 == result -> refcount); +# endif + return result; + } + } + RopeBase * nright = RopeLeaf_from_unowned_char_ptr(s, slen); + __STL_TRY { + r -> ref_nonnil(); + result = tree_concat(r, nright); + } + __STL_UNWIND(unref(r); unref(nright)); +# ifndef __GC + __stl_assert(1 == result -> refcount); +# endif + return result; +} + +#ifndef __GC +template <class charT, class Alloc> +rope<charT,Alloc>::RopeBase * rope<charT,Alloc> +::destr_concat_char_iter + (RopeBase * r, const charT *s, size_t slen) +{ + RopeBase *result; + if (0 == r) return RopeLeaf_from_unowned_char_ptr(s, slen); + size_t count = r -> refcount; + size_t orig_size = r -> size; + __stl_assert(count >= 1); + if (count > 1) return concat_char_iter(r, s, slen); + if (0 == slen) { + r -> refcount = 2; // One more than before + return r; + } + if (orig_size + slen <= copy_max && RopeBase::leaf == r -> tag) { + result = destr_leaf_concat_char_iter((RopeLeaf *)r, s, slen); + return result; + } + if (RopeBase::concat == r -> tag) { + RopeLeaf *right = (RopeLeaf *)(((RopeConcatenation *)r) -> right); + if (RopeBase::leaf == right -> tag + && right -> size + slen <= copy_max) { + RopeBase * new_right = destr_leaf_concat_char_iter(right, s, slen); + if (right == new_right) { + __stl_assert(new_right -> refcount == 2); + new_right -> refcount = 1; + } else { + __stl_assert(new_right -> refcount >= 1); + right -> unref_nonnil(); + } + __stl_assert(r -> refcount == 1); + r -> refcount = 2; // One more than before. + ((RopeConcatenation *)r) -> right = new_right; + r -> size = orig_size + slen; + if (0 != r -> c_string) { + r -> free_c_string(); + r -> c_string = 0; + } + return r; + } + } + RopeBase *right = RopeLeaf_from_unowned_char_ptr(s, slen); + r -> ref_nonnil(); + __STL_TRY { + result = tree_concat(r, right); + } + __STL_UNWIND(unref(r); unref(right)) + __stl_assert(1 == result -> refcount); + return result; +} +#endif /* !__GC */ + +template <class charT, class Alloc> +rope<charT,Alloc>::RopeBase * +rope<charT,Alloc>::concat(RopeBase * left, RopeBase * right) +{ + if (0 == left) { + ref(right); + return right; + } + if (0 == right) { + left -> ref_nonnil(); + return left; + } + if (RopeBase::leaf == right -> tag) { + if (RopeBase::leaf == left -> tag) { + if (right -> size + left -> size <= copy_max) { + return leaf_concat_char_iter((RopeLeaf *)left, + ((RopeLeaf *)right) -> data, + right -> size); + } + } else if (RopeBase::concat == left -> tag + && RopeBase::leaf == + ((RopeConcatenation *)left) -> right -> tag) { + RopeLeaf * leftright = + (RopeLeaf *)(((RopeConcatenation *)left) -> right); + if (leftright -> size + right -> size <= copy_max) { + RopeBase * leftleft = ((RopeConcatenation *)left) -> left; + RopeBase * rest = leaf_concat_char_iter(leftright, + ((RopeLeaf *)right) -> data, + right -> size); + leftleft -> ref_nonnil(); + __STL_TRY { + return(tree_concat(leftleft, rest)); + } + __STL_UNWIND(unref(leftleft); unref(rest)) + } + } + } + left -> ref_nonnil(); + right -> ref_nonnil(); + __STL_TRY { + return(tree_concat(left, right)); + } + __STL_UNWIND(unref(left); unref(right)); +} + +template <class charT, class Alloc> +rope<charT,Alloc>::RopeBase * +rope<charT,Alloc>::substring(RopeBase * base, size_t start, size_t endp1) +{ + if (0 == base) return 0; + size_t len = base -> size; + size_t adj_endp1; + const size_t lazy_threshold = 128; + + if (endp1 >= len) { + if (0 == start) { + base -> ref_nonnil(); + return base; + } else { + adj_endp1 = len; + } + } else { + adj_endp1 = endp1; + } + switch(base -> tag) { + case RopeBase::concat: + { + RopeConcatenation *c = (RopeConcatenation *)base; + RopeBase *left = c -> left; + RopeBase *right = c -> right; + size_t left_len = left -> size; + RopeBase * result; + + if (adj_endp1 <= left_len) { + return substring(left, start, endp1); + } else if (start >= left_len) { + return substring(right, start - left_len, + adj_endp1 - left_len); + } + self_destruct_ptr left_result(substring(left, start, + left_len)); + self_destruct_ptr right_result( + substring(right, 0, endp1 - left_len)); + result = concat(left_result, right_result); +# ifndef __GC + __stl_assert(1 == result -> refcount); +# endif + return result; + } + case RopeBase::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 -> data + start; + result = RopeLeaf_from_char_ptr(section, result_len); + result -> c_string = 0; // Not eos terminated. +# else + // We should sometimes create substring node instead. + result = RopeLeaf_from_unowned_char_ptr( + l -> data + start, result_len); +# endif + return result; + } + case RopeBase::substringfn: + // Avoid introducing mutiple layers of substring nodes. + { + RopeSubstring *old = (RopeSubstring *)base; + size_t result_len; + if (start >= adj_endp1) return 0; + result_len = adj_endp1 - start; + if (result_len > lazy_threshold) { + RopeSubstring * space = SAlloc::allocate(); + RopeSubstring * result = + new(space) RopeSubstring(old -> base, + start + old -> start, + adj_endp1 - start); + return result; + } // else fall through: + } + case RopeBase::function: + { + RopeFunction * f = (RopeFunction *)base; + charT *section; + size_t result_len; + if (start >= adj_endp1) return 0; + result_len = adj_endp1 - start; + + if (result_len > lazy_threshold) goto lazy; + section = (charT *) + DataAlloc::allocate(rounded_up_size(result_len)); + __STL_TRY { + (*(f -> fn))(start, result_len, section); + } + __STL_UNWIND(RopeBase::free_string(section, result_len)); + __cond_store_eos(section[result_len]); + return RopeLeaf_from_char_ptr(section, result_len); + } + } + /*NOTREACHED*/ + __stl_assert(false); + lazy: + { + // Create substring node. + RopeSubstring * space = SAlloc::allocate(); + RopeSubstring * result = new(space) RopeSubstring(base, start, + adj_endp1 - start); + return result; + } +} + +template<class charT> +class __rope_flatten_char_consumer : public __rope_char_consumer<charT> { + private: + charT * buf_ptr; + public: + charT * buffer; + __rope_flatten_char_consumer(charT * buffer) { + buf_ptr = buffer; + }; + ~__rope_flatten_char_consumer() {} + bool operator() (const charT* leaf, size_t n) { + uninitialized_copy_n(leaf, n, buf_ptr); + buf_ptr += n; + return true; + } +}; + +template<class charT> +class __rope_find_char_char_consumer : public __rope_char_consumer<charT> { + private: + charT pattern; + public: + size_t count; // Number of nonmatching characters + __rope_find_char_char_consumer(charT p) : pattern(p), count(0) {} + ~__rope_find_char_char_consumer() {} + bool operator() (const charT* leaf, size_t n) { + size_t i; + for (i = 0; i < n; i++) { + if (leaf[i] == pattern) { + count += i; return false; + } + } + count += n; return true; + } +}; + +template<class charT> +class __rope_insert_char_consumer : public __rope_char_consumer<charT> { + private: + typedef ostream insert_ostream; + insert_ostream & o; + public: + charT * buffer; + __rope_insert_char_consumer(insert_ostream & writer) : o(writer) {}; + ~__rope_insert_char_consumer() { }; + // Caller is presumed to own the ostream + bool operator() (const charT* leaf, size_t n); + // Returns true to continue traversal. +}; + +template<class charT> +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++) o << leaf[i]; + return true; +} + +inline bool __rope_insert_char_consumer<char>::operator() + (const char * leaf, size_t n) +{ + size_t i; + for (i = 0; i < n; i++) o.put(leaf[i]); + return true; +} + +#if !defined(_MSC_VER) && !defined(__BORLANDC__) +// I couldn't get this to work with the VC++ version of basic_ostream. +inline bool __rope_insert_char_consumer<wchar_t>::operator() + (const wchar_t * leaf, size_t n) +{ + size_t i; + for (i = 0; i < n; i++) o.put(leaf[i]); + return true; +} +#endif /* !_MSC_VER && !BORLAND */ + +template <class charT, class Alloc> +bool rope<charT, Alloc>::apply_to_pieces( + __rope_char_consumer<charT>& c, + const RopeBase * r, + size_t begin, size_t end) +{ + if (0 == r) return true; + switch(r -> tag) { + case RopeBase::concat: + { + RopeConcatenation *conc = (RopeConcatenation *)r; + RopeBase *left = conc -> left; + size_t left_len = left -> size; + if (begin < left_len) { + size_t left_end = min(left_len, end); + if (!apply_to_pieces(c, left, begin, left_end)) { + return false; + } + } + if (end > left_len) { + RopeBase *right = conc -> right; + size_t right_start = max(left_len, begin); + if (!apply_to_pieces(c, right, + right_start - left_len, + end - left_len)) { + return false; + } + } + } + return true; + case RopeBase::leaf: + { + RopeLeaf * l = (RopeLeaf *)r; + return c(l -> data + begin, end - begin); + } + case RopeBase::function: + case RopeBase::substringfn: + { + RopeFunction * f = (RopeFunction *)r; + size_t len = end - begin; + bool result; + charT * buffer = DataAlloc::allocate(len); + __STL_TRY { + (*(f -> fn))(begin, end, buffer); + result = c(buffer, len); + DataAlloc::deallocate(buffer, len); + } + __STL_UNWIND(DataAlloc::deallocate(buffer, len)) + 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 <class charT> inline bool __rope_is_simple(charT *) { return false; } +inline bool __rope_is_simple(char *) { return true; } +inline bool __rope_is_simple(wchar_t *) { return true; } + + +template<class charT, class Alloc> +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 <class charT, class Alloc> +charT * +rope<charT,Alloc>::flatten(RopeBase * r, + size_t start, size_t len, + charT * buffer) +{ + __rope_flatten_char_consumer<charT> c(buffer); + apply_to_pieces(c, r, start, start + len); + return(buffer + len); +} + +template <class charT, class Alloc> +size_t +rope<charT,Alloc>::find(charT pattern, size_t start) const +{ + __rope_find_char_char_consumer<charT> c(pattern); + apply_to_pieces(c, tree_ptr, start, size()); + return start + c.count; +} + +template <class charT, class Alloc> +charT * +rope<charT,Alloc>::flatten(RopeBase * r, charT * buffer) +{ + if (0 == r) return buffer; + switch(r -> tag) { + case RopeBase::concat: + { + RopeConcatenation *c = (RopeConcatenation *)r; + RopeBase *left = c -> left; + RopeBase *right = c -> right; + charT * rest = flatten(left, buffer); + return flatten(right, rest); + } + case RopeBase::leaf: + { + RopeLeaf * l = (RopeLeaf *)r; + return copy_n(l -> data, l -> size, buffer).second; + } + case RopeBase::function: + case RopeBase::substringfn: + // We dont yet do anything with substring nodes. + // This needs to be fixed before ropefiles will work well. + { + RopeFunction * f = (RopeFunction *)r; + (*(f -> fn))(0, f -> size, buffer); + return buffer + f -> size; + } + default: + __stl_assert(false); + /*NOTREACHED*/ + return 0; + } +} + + +// This needs work for charT != char +template <class charT, class Alloc> +void +rope<charT,Alloc>::dump(RopeBase * r, int indent) +{ + for (int i = 0; i < indent; i++) putchar(' '); + if (0 == r) { + printf("NULL\n"); return; + } + if (RopeBase::concat == r -> tag) { + RopeConcatenation *c = (RopeConcatenation *)r; + RopeBase *left = c -> left; + RopeBase *right = c -> right; + +# ifdef __GC + printf("Concatenation %p (depth = %d, len = %ld, %s balanced)\n", + r, r -> depth, r -> size, r -> is_balanced? "" : "not"); +# else + printf("Concatenation %p (rc = %ld, depth = %d, len = %ld, %s balanced)\n", + r, r -> refcount, r -> depth, r -> size, + r -> is_balanced? "" : "not"); +# endif + dump(left, indent + 2); + dump(right, indent + 2); + return; + } else { + char * kind; + + switch (r -> tag) { + case RopeBase::leaf: + kind = "Leaf"; + break; + case RopeBase::function: + kind = "Function"; + break; + case RopeBase::substringfn: + kind = "Function representing substring"; + break; + default: + kind = "(corrupted kind field!)"; + } +# ifdef __GC + printf("%s %p (depth = %d, len = %ld) ", + kind, r, r -> depth, r -> size); +# else + printf("%s %p (rc = %ld, depth = %d, len = %ld) ", + kind, r, r -> refcount, r -> depth, r -> size); +# endif + if (__is_one_byte_char_type((charT *)0)) { + const int max_len = 40; + self_destruct_ptr prefix(substring(r, 0, max_len)); + charT buffer[max_len + 1]; + bool too_big = r -> size > prefix-> size; + + flatten(prefix, buffer); + buffer[prefix -> size] = __eos((charT *)0); + printf("%s%s\n", (char *)buffer, too_big? "...\n" : "\n"); + } else { + printf("\n"); + } + } +} + +template <class charT, class Alloc> +const unsigned long +rope<charT,Alloc>::min_len[__rope_RopeBase<charT,Alloc>::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 */2971215073 }; +// These are Fibonacci numbers < 2**32. + +template <class charT, class Alloc> +rope<charT,Alloc>::RopeBase * +rope<charT,Alloc>::balance(RopeBase *r) +{ + RopeBase * forest[RopeBase::max_rope_depth + 1]; + RopeBase * result = 0; + int i; + // Inariant: + // The concatenation of forest in descending order is equal to r. + // forest[i].size >= min_len[i] + // forest[i].depth = i + // References from forest are included in refcount. + + for (i = 0; i <= RopeBase::max_rope_depth; ++i) forest[i] = 0; + __STL_TRY { + add_to_forest(r, forest); + for (i = 0; i <= RopeBase::max_rope_depth; ++i) if (0 != forest[i]) { +# ifndef __GC + self_destruct_ptr old(result); +# endif + result = concat(forest[i], result); + forest[i] -> unref_nonnil(); +# if !defined(__GC) && defined(__STL_USE_EXCEPTIONS) + forest[i] = 0; +# endif + } + } + __STL_UNWIND(for(i = 0; i <= RopeBase::max_rope_depth; i++) + unref(forest[i])) + if (result -> depth > RopeBase::max_rope_depth) abort(); + return(result); +} + + +template <class charT, class Alloc> +void +rope<charT,Alloc>::add_to_forest(RopeBase *r, RopeBase **forest) +{ + if (r -> is_balanced) { + add_leaf_to_forest(r, forest); + return; + } + __stl_assert(r -> tag == RopeBase::concat); + { + RopeConcatenation *c = (RopeConcatenation *)r; + + add_to_forest(c -> left, forest); + add_to_forest(c -> right, forest); + } +} + + +template <class charT, class Alloc> +void +rope<charT,Alloc>::add_leaf_to_forest(RopeBase *r, RopeBase **forest) +{ + RopeBase * insertee; // included in refcount + RopeBase * too_tiny = 0; // included in refcount + int i; // forest[0..i-1] is empty + size_t s = r -> size; + + for (i = 0; s >= min_len[i+1]/* not this bucket */; ++i) { + if (0 != forest[i]) { +# ifndef __GC + self_destruct_ptr old(too_tiny); +# endif + too_tiny = concat_and_set_balanced(forest[i], too_tiny); + forest[i] -> unref_nonnil(); + forest[i] = 0; + } + } + { +# ifndef __GC + self_destruct_ptr old(too_tiny); +# endif + insertee = concat_and_set_balanced(too_tiny, r); + } + // Too_tiny dead, and no longer included in refcount. + // Insertee is live and included. + __stl_assert(is_almost_balanced(insertee)); + __stl_assert(insertee -> depth <= r -> depth + 1); + for (;; ++i) { + if (0 != forest[i]) { +# ifndef __GC + self_destruct_ptr old(insertee); +# endif + insertee = concat_and_set_balanced(forest[i], insertee); + forest[i] -> unref_nonnil(); + forest[i] = 0; + __stl_assert(is_almost_balanced(insertee)); + } + __stl_assert(min_len[i] <= insertee -> size); + __stl_assert(forest[i] == 0); + if (i == RopeBase::max_rope_depth + || insertee -> size < min_len[i+1]) { + forest[i] = insertee; + // refcount is OK since insertee is now dead. + return; + } + } +} + +template <class charT, class Alloc> +charT +rope<charT,Alloc>::fetch(RopeBase *r, size_type i) +{ + __GC_CONST charT * cstr = r -> c_string; + + __stl_assert(i < r -> size); + if (0 != cstr) return cstr[i]; + for(;;) { + switch(r -> tag) { + case RopeBase::concat: + { + RopeConcatenation *c = (RopeConcatenation *)r; + RopeBase *left = c -> left; + size_t left_len = left -> size; + + if (i >= left_len) { + i -= left_len; + r = c -> right; + } else { + r = left; + } + } + break; + case RopeBase::leaf: + { + RopeLeaf * l = (RopeLeaf *)r; + return l -> data[i]; + } + case RopeBase::function: + case RopeBase::substringfn: + { + RopeFunction * f = (RopeFunction *)r; + charT result; + + (*(f -> fn))(i, 1, &result); + return result; + } + } + } +} + +# ifndef __GC +// Return a uniquely referenced character slot for the given +// position, or 0 if that's not possible. +template <class charT, class Alloc> +charT* +rope<charT,Alloc>::fetch_ptr(RopeBase *r, size_type i) +{ + RopeBase * clrstack[RopeBase::max_rope_depth]; + size_t csptr = 0; + + for(;;) { + if (r -> refcount > 1) return 0; + switch(r -> tag) { + case RopeBase::concat: + { + RopeConcatenation *c = (RopeConcatenation *)r; + RopeBase *left = c -> left; + size_t left_len = left -> size; + + if (c -> c_string != 0) clrstack[csptr++] = c; + if (i >= left_len) { + i -= left_len; + r = c -> right; + } else { + r = left; + } + } + break; + case RopeBase::leaf: + { + RopeLeaf * l = (RopeLeaf *)r; + if (l -> c_string != l -> data && l -> c_string != 0) + clrstack[csptr++] = l; + while (csptr > 0) { + -- csptr; + RopeBase * d = clrstack[csptr]; + d -> free_c_string(); + d -> c_string = 0; + } + return l -> data + i; + } + case RopeBase::function: + case RopeBase::substringfn: + return 0; + } + } +} +# endif /* __GC */ + +// The following could be implemented trivially using +// lexicographical_compare_3way. +// We do a little more work to avoid dealing with rope iterators for +// flat strings. +template <class charT, class Alloc> +int +rope<charT,Alloc>::compare (const RopeBase *left, const RopeBase *right) +{ + size_t left_len; + size_t right_len; + + if (0 == right) return 0 != left; + if (0 == left) return -1; + left_len = left -> size; + right_len = right -> size; + if (RopeBase::leaf == left -> tag) { + RopeLeaf *l = (RopeLeaf *) left; + if (RopeBase::leaf == right -> tag) { + RopeLeaf *r = (RopeLeaf *) right; + return lexicographical_compare_3way( + l -> data, l -> data + left_len, + r -> data, r -> data + right_len); + } else { + const_iterator rstart(right, 0); + const_iterator rend(right, right_len); + return lexicographical_compare_3way( + l -> data, l -> data + left_len, + rstart, rend); + } + } else { + const_iterator lstart(left, 0); + const_iterator lend(left, left_len); + if (RopeBase::leaf == right -> tag) { + RopeLeaf *r = (RopeLeaf *) right; + return lexicographical_compare_3way( + lstart, lend, + r -> data, r -> data + right_len); + } else { + const_iterator rstart(right, 0); + const_iterator rend(right, right_len); + return lexicographical_compare_3way( + lstart, lend, + rstart, rend); + } + } +} + +// Assignment to reference proxies. +template <class charT, class Alloc> +__rope_charT_ref_proxy<charT, Alloc>& +__rope_charT_ref_proxy<charT, Alloc>::operator= (charT c) { + RopeBase * old = root -> tree_ptr; +# ifndef __GC + // First check for the case in which everything is uniquely + // referenced. In that case we can do this destructively. + charT * charT_ptr = my_rope::fetch_ptr(old, pos); + if (0 != charT_ptr) { + *charT_ptr = c; + return *this; + } +# endif + self_destruct_ptr left(my_rope::substring(old, 0, pos)); + self_destruct_ptr right(my_rope::substring(old, pos+1, old -> size)); + self_destruct_ptr result_left(my_rope::destr_concat_char_iter(left, &c, 1)); +# ifndef __GC + __stl_assert(left == result_left || 1 == result_left -> refcount); +# endif + RopeBase * result = + my_rope::concat(result_left, right); +# ifndef __GC + __stl_assert(1 <= result -> refcount); + RopeBase::unref(old); +# endif + root -> tree_ptr = result; + return *this; +} + +template <class charT, class Alloc> +inline __rope_charT_ref_proxy<charT, Alloc>::operator charT () const +{ + if (current_valid) { + return current; + } else { + return my_rope::fetch(root->tree_ptr, pos); + } +} +template <class charT, class Alloc> +__rope_charT_ptr_proxy<charT, Alloc> +__rope_charT_ref_proxy<charT, Alloc>::operator& () const { + return __rope_charT_ptr_proxy<charT, Alloc>(*this); +} + +template <class charT, class Alloc> +rope<charT, Alloc>::rope(size_t n, charT c) +{ + rope result; + const size_t exponentiate_threshold = 32; + size_t exponent; + size_t rest; + charT *rest_buffer; + RopeBase * remainder; + rope remainder_rope; + + if (0 == n) { tree_ptr = 0; return; } + exponent = n / exponentiate_threshold; + rest = n % exponentiate_threshold; + if (0 == rest) { + remainder = 0; + } else { + rest_buffer = DataAlloc::allocate(rounded_up_size(rest)); + uninitialized_fill_n(rest_buffer, rest, c); + __cond_store_eos(rest_buffer[rest]); + __STL_TRY { + remainder = RopeLeaf_from_char_ptr(rest_buffer, rest); + } + __STL_UNWIND(RopeBase::free_string(rest_buffer, rest)) + } + remainder_rope.tree_ptr = remainder; + if (exponent != 0) { + charT * base_buffer = + DataAlloc::allocate(rounded_up_size(exponentiate_threshold)); + RopeLeaf * base_leaf; + rope base_rope; + uninitialized_fill_n(base_buffer, exponentiate_threshold, c); + __cond_store_eos(base_buffer[exponentiate_threshold]); + __STL_TRY { + base_leaf = RopeLeaf_from_char_ptr(base_buffer, + exponentiate_threshold); + } + __STL_UNWIND(RopeBase::free_string(base_buffer, exponentiate_threshold)) + base_rope.tree_ptr = base_leaf; + if (1 == exponent) { + result = base_rope; +# ifndef __GC + __stl_assert(1 == result -> tree_ptr -> refcount); +# endif + } else { + result = power(base_rope, exponent, concat_fn()); + } + if (0 != remainder) { + result += remainder_rope; + } + } else { + result = remainder_rope; + } + tree_ptr = result.tree_ptr; + tree_ptr -> ref_nonnil(); +} + +template<class charT, class Alloc> charT rope<charT,Alloc>::empty_c_str[1]; + +# ifdef __STL_PTHREADS + template<class charT, class Alloc> + pthread_mutex_t rope<charT,Alloc>::swap_lock = PTHREAD_MUTEX_INITIALIZER; +# endif + +template<class charT, class Alloc> +const charT * rope<charT,Alloc>::c_str() const { + if (0 == tree_ptr) { + empty_c_str[0] = __eos((charT *)0); // Possibly redundant, + // but probably fast. + return empty_c_str; + } + __GC_CONST charT * old_c_string = tree_ptr -> c_string; + if (0 != old_c_string) return(old_c_string); + size_t s = size(); + charT * result = DataAlloc::allocate(s + 1); + flatten(tree_ptr, result); + result[s] = __eos((charT *)0); +# ifdef __GC + tree_ptr -> c_string = result; +# else + if ((old_c_string = atomic_swap(&(tree_ptr -> c_string), result)) != 0) { + // It must have been added in the interim. Hence it had to have been + // separately allocated. Deallocate the old copy, since we just + // replaced it. + destroy(old_c_string, old_c_string + s + 1); + DataAlloc::deallocate(old_c_string, s + 1); + } +# endif + return(result); +} + +template<class charT, class Alloc> +const charT * rope<charT,Alloc>::replace_with_c_str() { + if (0 == tree_ptr) { + empty_c_str[0] = __eos((charT *)0); + return empty_c_str; + } + __GC_CONST charT * old_c_string = tree_ptr -> c_string; + if (RopeBase::leaf == tree_ptr -> tag && 0 != old_c_string) { + return(old_c_string); + } + size_t s = size(); + charT * result = DataAlloc::allocate(rounded_up_size(s)); + flatten(tree_ptr, result); + result[s] = __eos((charT *)0); + tree_ptr -> unref_nonnil(); + tree_ptr = RopeLeaf_from_char_ptr(result, s); + return(result); +} + +// Algorithm specializations. More should be added. + +#ifndef _MSC_VER +// I couldn't get this to work with VC++ +template<class charT,class Alloc> +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; +} + +inline void rotate(__rope_iterator<char,__ALLOC> first, + __rope_iterator<char,__ALLOC> middle, + __rope_iterator<char,__ALLOC> last) { + __rope_rotate(first, middle, last); +} + +# if 0 +// Probably not useful for several reasons: +// - for SGIs 7.1 compiler and probably some others, +// this forces lots of rope<wchar_t, ...> instantiations, creating a +// code bloat and compile time problem. (Fixed in 7.2.) +// - wchar_t is 4 bytes wide on most UNIX platforms, making it unattractive +// for unicode strings. Unsigned short may be a better character +// type. +inline void rotate(__rope_iterator<wchar_t,__ALLOC> first, + __rope_iterator<wchar_t,__ALLOC> middle, + __rope_iterator<wchar_t,__ALLOC> 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/contrib/libstdc++/stl/set b/contrib/libstdc++/stl/set new file mode 100644 index 0000000..c836c45 --- /dev/null +++ b/contrib/libstdc++/stl/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 <stl_tree.h> +#endif +#include <stl_set.h> +#include <stl_multiset.h> + +#endif /* __SGI_STL_SET */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/set.h b/contrib/libstdc++/stl/set.h new file mode 100644 index 0000000..9004d2e --- /dev/null +++ b/contrib/libstdc++/stl/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 <tree.h> +#include <stl_set.h> + +#ifdef __STL_USE_NAMESPACES +using __STD::set; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_SET_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/slist b/contrib/libstdc++/stl/slist new file mode 100644 index 0000000..c3ec742 --- /dev/null +++ b/contrib/libstdc++/stl/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 <stl_algobase.h> +#include <stl_alloc.h> +#include <stl_construct.h> +#include <stl_uninitialized.h> +#include <stl_slist.h> + +#endif /* __SGI_STL_SLIST */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/slist.h b/contrib/libstdc++/stl/slist.h new file mode 100644 index 0000000..d2377b0 --- /dev/null +++ b/contrib/libstdc++/stl/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 <algobase.h> +#include <alloc.h> +#include <stl_slist.h> + +#ifdef __STL_USE_NAMESPACES +using __STD::slist; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_SLIST_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/stack b/contrib/libstdc++/stl/stack new file mode 100644 index 0000000..36461d9 --- /dev/null +++ b/contrib/libstdc++/stl/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 <stl_algobase.h> +#include <stl_alloc.h> +#include <stl_construct.h> +#include <stl_uninitialized.h> +#include <stl_deque.h> +#include <stl_stack.h> + +#endif /* __SGI_STL_STACK */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/stack.h b/contrib/libstdc++/stl/stack.h new file mode 100644 index 0000000..89beca8 --- /dev/null +++ b/contrib/libstdc++/stl/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 <vector.h> +#include <deque.h> +#include <heap.h> +#include <stl_stack.h> +#include <stl_queue.h> + +#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/contrib/libstdc++/stl/stl_algo.h b/contrib/libstdc++/stl/stl_algo.h new file mode 100644 index 0000000..5cde42c --- /dev/null +++ b/contrib/libstdc++/stl/stl_algo.h @@ -0,0 +1,2674 @@ +/* + * + * 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_heap.h> + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1209 +#endif + +template <class T> +inline const T& __median(const T& a, const T& b, const T& c) { + if (a < b) + if (b < c) + return b; + else if (a < c) + return c; + else + return a; + else if (a < c) + return a; + else if (b < c) + return c; + else + return b; +} + +template <class T, class Compare> +inline const T& __median(const T& a, const T& b, const T& c, Compare comp) { + if (comp(a, b)) + if (comp(b, c)) + return b; + else if (comp(a, c)) + return c; + else + return a; + else if (comp(a, c)) + return a; + else if (comp(b, c)) + return c; + else + return b; +} + +template <class InputIterator, class Function> +Function for_each(InputIterator first, InputIterator last, Function f) { + for ( ; first != last; ++first) + f(*first); + return f; +} + +template <class InputIterator, class T> +InputIterator find(InputIterator first, InputIterator last, const T& value) { + while (first != last && *first != value) ++first; + return first; +} + +template <class InputIterator, class Predicate> +InputIterator find_if(InputIterator first, InputIterator last, + Predicate pred) { + while (first != last && !pred(*first)) ++first; + return first; +} + +template <class ForwardIterator> +ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last) { + if (first == last) return last; + ForwardIterator next = first; + while(++next != last) { + if (*first == *next) return first; + first = next; + } + return last; +} + +template <class ForwardIterator, class BinaryPredicate> +ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last, + BinaryPredicate binary_pred) { + if (first == last) return last; + ForwardIterator next = first; + while(++next != last) { + if (binary_pred(*first, *next)) return first; + first = next; + } + return last; +} + +template <class InputIterator, class T, class Size> +void count(InputIterator first, InputIterator last, const T& value, + Size& n) { + for ( ; first != last; ++first) + if (*first == value) + ++n; +} + +template <class InputIterator, class Predicate, class Size> +void count_if(InputIterator first, InputIterator last, Predicate pred, + Size& n) { + for ( ; first != last; ++first) + if (pred(*first)) + ++n; +} + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + +template <class InputIterator, class T> +typename iterator_traits<InputIterator>::difference_type +count(InputIterator first, InputIterator last, const T& value) { + typename iterator_traits<InputIterator>::difference_type n = 0; + for ( ; first != last; ++first) + if (*first == value) + ++n; + return n; +} + +template <class InputIterator, class Predicate> +typename iterator_traits<InputIterator>::difference_type +count_if(InputIterator first, InputIterator last, Predicate pred) { + typename iterator_traits<InputIterator>::difference_type n = 0; + for ( ; first != last; ++first) + if (pred(*first)) + ++n; + return n; +} + + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template <class ForwardIterator1, class ForwardIterator2, class Distance1, + class Distance2> +ForwardIterator1 __search(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + Distance1*, Distance2*) { + Distance1 d1 = 0; + distance(first1, last1, d1); + Distance2 d2 = 0; + distance(first2, last2, d2); + + if (d1 < d2) return last1; + + ForwardIterator1 current1 = first1; + ForwardIterator2 current2 = first2; + + while (current2 != last2) + if (*current1 == *current2) { + ++current1; + ++current2; + } + else { + if (d1 == d2) + return last1; + else { + current1 = ++first1; + current2 = first2; + --d1; + } + } + return first1; +} + +template <class ForwardIterator1, class ForwardIterator2> +inline ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2) +{ + return __search(first1, last1, first2, last2, distance_type(first1), + distance_type(first2)); +} + +template <class ForwardIterator1, class ForwardIterator2, + class BinaryPredicate, class Distance1, class Distance2> +ForwardIterator1 __search(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate binary_pred, Distance1*, Distance2*) { + Distance1 d1 = 0; + distance(first1, last1, d1); + Distance2 d2 = 0; + distance(first2, last2, d2); + + if (d1 < d2) return last1; + + ForwardIterator1 current1 = first1; + ForwardIterator2 current2 = first2; + + while (current2 != last2) + if (binary_pred(*current1, *current2)) { + ++current1; + ++current2; + } + else { + if (d1 == d2) + return last1; + else { + current1 = ++first1; + current2 = first2; + --d1; + } + } + return first1; +} + +template <class ForwardIterator1, class ForwardIterator2, + class BinaryPredicate> +inline ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate binary_pred) { + return __search(first1, last1, first2, last2, binary_pred, + distance_type(first1), distance_type(first2)); +} + +template <class ForwardIterator, class Integer, class T> +ForwardIterator search_n(ForwardIterator first, ForwardIterator last, + Integer count, const T& value) { + if (count <= 0) + return first; + else { + first = find(first, last, value); + while (first != last) { + Integer n = count - 1; + ForwardIterator i = first; + ++i; + while (i != last && n != 0 && *i == value) { + ++i; + --n; + } + if (n == 0) + return first; + else + first = find(i, last, value); + } + return last; + } +} + +template <class ForwardIterator, class Integer, class T, class BinaryPredicate> +ForwardIterator search_n(ForwardIterator first, ForwardIterator last, + Integer count, const T& value, + BinaryPredicate binary_pred) { + if (count <= 0) + return first; + else { + while (first != last) { + if (binary_pred(*first, value)) break; + ++first; + } + while (first != last) { + Integer n = count - 1; + ForwardIterator i = first; + ++i; + while (i != last && n != 0 && binary_pred(*i, value)) { + ++i; + --n; + } + if (n == 0) + return first; + else { + while (i != last) { + if (binary_pred(*i, value)) break; + ++i; + } + first = i; + } + } + return last; + } +} + +template <class ForwardIterator1, class ForwardIterator2> +ForwardIterator2 swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2) { + for ( ; first1 != last1; ++first1, ++first2) + iter_swap(first1, first2); + return first2; +} + +template <class InputIterator, class OutputIterator, class UnaryOperation> +OutputIterator transform(InputIterator first, InputIterator last, + OutputIterator result, UnaryOperation op) { + for ( ; first != last; ++first, ++result) + *result = op(*first); + return result; +} + +template <class InputIterator1, class InputIterator2, class OutputIterator, + class BinaryOperation> +OutputIterator transform(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, OutputIterator result, + BinaryOperation binary_op) { + for ( ; first1 != last1; ++first1, ++first2, ++result) + *result = binary_op(*first1, *first2); + return result; +} + +template <class ForwardIterator, class T> +void replace(ForwardIterator first, ForwardIterator last, const T& old_value, + const T& new_value) { + for ( ; first != last; ++first) + if (*first == old_value) *first = new_value; +} + +template <class ForwardIterator, class Predicate, class T> +void replace_if(ForwardIterator first, ForwardIterator last, Predicate pred, + const T& new_value) { + for ( ; first != last; ++first) + if (pred(*first)) *first = new_value; +} + +template <class InputIterator, class OutputIterator, class T> +OutputIterator replace_copy(InputIterator first, InputIterator last, + OutputIterator result, const T& old_value, + const T& new_value) { + for ( ; first != last; ++first, ++result) + *result = *first == old_value ? new_value : *first; + return result; +} + +template <class Iterator, class OutputIterator, class Predicate, class T> +OutputIterator replace_copy_if(Iterator first, Iterator last, + OutputIterator result, Predicate pred, + const T& new_value) { + for ( ; first != last; ++first, ++result) + *result = pred(*first) ? new_value : *first; + return result; +} + +template <class ForwardIterator, class Generator> +void generate(ForwardIterator first, ForwardIterator last, Generator gen) { + for ( ; first != last; ++first) + *first = gen(); +} + +template <class OutputIterator, class Size, class Generator> +OutputIterator generate_n(OutputIterator first, Size n, Generator gen) { + for ( ; n > 0; --n, ++first) + *first = gen(); + return first; +} + +template <class InputIterator, class OutputIterator, class T> +OutputIterator remove_copy(InputIterator first, InputIterator last, + OutputIterator result, const T& value) { + for ( ; first != last; ++first) + if (*first != value) { + *result = *first; + ++result; + } + return result; +} + +template <class InputIterator, class OutputIterator, class Predicate> +OutputIterator remove_copy_if(InputIterator first, InputIterator last, + OutputIterator result, Predicate pred) { + for ( ; first != last; ++first) + if (!pred(*first)) { + *result = *first; + ++result; + } + return result; +} + +template <class ForwardIterator, class T> +ForwardIterator remove(ForwardIterator first, ForwardIterator last, + const T& value) { + first = find(first, last, value); + ForwardIterator next = first; + return first == last ? first : remove_copy(++next, last, first, value); +} + +template <class ForwardIterator, class Predicate> +ForwardIterator remove_if(ForwardIterator first, ForwardIterator last, + Predicate pred) { + first = find_if(first, last, pred); + ForwardIterator next = first; + return first == last ? first : remove_copy_if(++next, last, first, pred); +} + +template <class InputIterator, class ForwardIterator> +ForwardIterator __unique_copy(InputIterator first, InputIterator last, + ForwardIterator result, forward_iterator_tag) { + *result = *first; + while (++first != last) + if (*result != *first) *++result = *first; + return ++result; +} + + +template <class InputIterator, class OutputIterator, class T> +OutputIterator __unique_copy(InputIterator first, InputIterator last, + OutputIterator result, T*) { + T value = *first; + *result = value; + while (++first != last) + if (value != *first) { + value = *first; + *++result = value; + } + return ++result; +} + +template <class InputIterator, class OutputIterator> +inline OutputIterator __unique_copy(InputIterator first, InputIterator last, + OutputIterator result, + output_iterator_tag) { + return __unique_copy(first, last, result, value_type(first)); +} + +template <class InputIterator, class OutputIterator> +inline OutputIterator unique_copy(InputIterator first, InputIterator last, + OutputIterator result) { + if (first == last) return result; + return __unique_copy(first, last, result, iterator_category(result)); +} +template <class InputIterator, class ForwardIterator, class BinaryPredicate> +ForwardIterator __unique_copy(InputIterator first, InputIterator last, + ForwardIterator result, + BinaryPredicate binary_pred, + forward_iterator_tag) { + *result = *first; + while (++first != last) + if (!binary_pred(*result, *first)) *++result = *first; + return ++result; +} + +template <class InputIterator, class OutputIterator, class BinaryPredicate, + class T> +OutputIterator __unique_copy(InputIterator first, InputIterator last, + OutputIterator result, + BinaryPredicate binary_pred, T*) { + T value = *first; + *result = value; + while (++first != last) + if (!binary_pred(value, *first)) { + value = *first; + *++result = value; + } + return ++result; +} + +template <class InputIterator, class OutputIterator, class BinaryPredicate> +inline OutputIterator __unique_copy(InputIterator first, InputIterator last, + OutputIterator result, + BinaryPredicate binary_pred, + output_iterator_tag) { + return __unique_copy(first, last, result, binary_pred, value_type(first)); +} + +template <class InputIterator, class OutputIterator, class BinaryPredicate> +inline OutputIterator unique_copy(InputIterator first, InputIterator last, + OutputIterator result, + BinaryPredicate binary_pred) { + if (first == last) return result; + return __unique_copy(first, last, result, binary_pred, + iterator_category(result)); +} + +template <class ForwardIterator> +ForwardIterator unique(ForwardIterator first, ForwardIterator last) { + first = adjacent_find(first, last); + return unique_copy(first, last, first); +} + +template <class ForwardIterator, class BinaryPredicate> +ForwardIterator unique(ForwardIterator first, ForwardIterator last, + BinaryPredicate binary_pred) { + first = adjacent_find(first, last, binary_pred); + return unique_copy(first, last, first, binary_pred); +} + +template <class BidirectionalIterator> +void __reverse(BidirectionalIterator first, BidirectionalIterator last, + bidirectional_iterator_tag) { + while (true) + if (first == last || first == --last) + return; + else + iter_swap(first++, last); +} + +template <class RandomAccessIterator> +void __reverse(RandomAccessIterator first, RandomAccessIterator last, + random_access_iterator_tag) { + while (first < last) iter_swap(first++, --last); +} + +template <class BidirectionalIterator> +inline void reverse(BidirectionalIterator first, BidirectionalIterator last) { + __reverse(first, last, iterator_category(first)); +} + +template <class BidirectionalIterator, class OutputIterator> +OutputIterator reverse_copy(BidirectionalIterator first, + BidirectionalIterator last, + OutputIterator result) { + while (first != last) { + --last; + *result = *last; + ++result; + } + return result; +} + +template <class ForwardIterator, class Distance> +void __rotate(ForwardIterator first, ForwardIterator middle, + ForwardIterator last, Distance*, forward_iterator_tag) { + for (ForwardIterator i = middle; ;) { + iter_swap(first, i); + ++first; + ++i; + if (first == middle) { + if (i == last) return; + middle = i; + } + else if (i == last) + i = middle; + } +} + +template <class BidirectionalIterator, class Distance> +void __rotate(BidirectionalIterator first, BidirectionalIterator middle, + BidirectionalIterator last, Distance*, + bidirectional_iterator_tag) { + reverse(first, middle); + reverse(middle, last); + reverse(first, last); +} + +template <class EuclideanRingElement> +EuclideanRingElement __gcd(EuclideanRingElement m, EuclideanRingElement n) +{ + while (n != 0) { + EuclideanRingElement t = m % n; + m = n; + n = t; + } + return m; +} + +template <class RandomAccessIterator, class Distance, class T> +void __rotate_cycle(RandomAccessIterator first, RandomAccessIterator last, + RandomAccessIterator initial, Distance shift, T*) { + T value = *initial; + RandomAccessIterator ptr1 = initial; + RandomAccessIterator ptr2 = ptr1 + shift; + while (ptr2 != initial) { + *ptr1 = *ptr2; + ptr1 = ptr2; + if (last - ptr2 > shift) + ptr2 += shift; + else + ptr2 = first + (shift - (last - ptr2)); + } + *ptr1 = value; +} + +template <class RandomAccessIterator, class Distance> +void __rotate(RandomAccessIterator first, RandomAccessIterator middle, + RandomAccessIterator last, Distance*, + random_access_iterator_tag) { + Distance n = __gcd(last - first, middle - first); + while (n--) + __rotate_cycle(first, last, first + n, middle - first, + value_type(first)); +} + +template <class ForwardIterator> +inline void rotate(ForwardIterator first, ForwardIterator middle, + ForwardIterator last) { + if (first == middle || middle == last) return; + __rotate(first, middle, last, distance_type(first), + iterator_category(first)); +} + +template <class ForwardIterator, class OutputIterator> +OutputIterator rotate_copy(ForwardIterator first, ForwardIterator middle, + ForwardIterator last, OutputIterator result) { + return copy(first, middle, copy(middle, last, result)); +} + +template <class RandomAccessIterator, class Distance> +void __random_shuffle(RandomAccessIterator first, RandomAccessIterator last, + Distance*) { + if (first == last) return; + for (RandomAccessIterator i = first + 1; i != last; ++i) +#ifdef __STL_NO_DRAND48 + iter_swap(i, first + Distance(rand() % ((i - first) + 1))); +#else + iter_swap(i, first + Distance(lrand48() % ((i - first) + 1))); +#endif +} + +template <class RandomAccessIterator> +inline void random_shuffle(RandomAccessIterator first, + RandomAccessIterator last) { + __random_shuffle(first, last, distance_type(first)); +} + +template <class RandomAccessIterator, class RandomNumberGenerator> +void random_shuffle(RandomAccessIterator first, RandomAccessIterator last, + RandomNumberGenerator& rand) { + if (first == last) return; + for (RandomAccessIterator i = first + 1; i != last; ++i) + iter_swap(i, first + rand((i - first) + 1)); +} + +template <class ForwardIterator, class OutputIterator, class Distance> +OutputIterator random_sample_n(ForwardIterator first, ForwardIterator last, + OutputIterator out, const Distance n) +{ + Distance remaining = 0; + distance(first, last, remaining); + Distance m = min(n, remaining); + + while (m > 0) { +#ifdef __STL_NO_DRAND48 + if (rand() % remaining < m) { +#else + if (lrand48() % remaining < m) { +#endif + *out = *first; + ++out; + --m; + } + + --remaining; + ++first; + } + return out; +} + +template <class ForwardIterator, class OutputIterator, class Distance, + class RandomNumberGenerator> +OutputIterator random_sample_n(ForwardIterator first, ForwardIterator last, + OutputIterator 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 <class InputIterator, class RandomAccessIterator, class Distance> +RandomAccessIterator __random_sample(InputIterator first, InputIterator last, + RandomAccessIterator out, + const Distance n) +{ + Distance m = 0; + Distance t = n; + for ( ; first != last && m < n; ++m, ++first) + out[m] = *first; + + while (first != last) { + ++t; +#ifdef __STL_NO_DRAND48 + Distance M = rand() % t; +#else + Distance M = lrand48() % t; +#endif + if (M < n) + out[M] = *first; + ++first; + } + + return out + m; +} + +template <class InputIterator, class RandomAccessIterator, + class RandomNumberGenerator, class Distance> +RandomAccessIterator __random_sample(InputIterator first, InputIterator last, + RandomAccessIterator 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 <class InputIterator, class RandomAccessIterator> +inline RandomAccessIterator +random_sample(InputIterator first, InputIterator last, + RandomAccessIterator out_first, RandomAccessIterator out_last) +{ + return __random_sample(first, last, out_first, out_last - out_first); +} + +template <class InputIterator, class RandomAccessIterator, + class RandomNumberGenerator> +inline RandomAccessIterator +random_sample(InputIterator first, InputIterator last, + RandomAccessIterator out_first, RandomAccessIterator out_last, + RandomNumberGenerator& rand) +{ + return __random_sample(first, last, out_first, rand, out_last - out_first); +} + + + +template <class BidirectionalIterator, class Predicate> +BidirectionalIterator partition(BidirectionalIterator first, + BidirectionalIterator last, Predicate pred) { + 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 <class ForwardIterator, class Predicate, class Distance> +ForwardIterator __inplace_stable_partition(ForwardIterator first, + ForwardIterator last, + Predicate pred, Distance len) { + if (len == 1) return pred(*first) ? last : first; + ForwardIterator middle = first; + advance(middle, len / 2); + ForwardIterator + first_cut = __inplace_stable_partition(first, middle, pred, len / 2); + ForwardIterator + second_cut = __inplace_stable_partition(middle, last, pred, + len - len / 2); + rotate(first_cut, middle, second_cut); + len = 0; + distance(middle, second_cut, len); + advance(first_cut, len); + return first_cut; +} + +template <class ForwardIterator, class Pointer, class Predicate, + class Distance> +ForwardIterator __stable_partition_adaptive(ForwardIterator first, + ForwardIterator last, + Predicate pred, Distance len, + Pointer buffer, + Distance buffer_size) { + if (len <= buffer_size) { + ForwardIterator result1 = first; + Pointer result2 = buffer; + for ( ; first != last ; ++first) + if (pred(*first)) { + *result1 = *first; + ++result1; + } + else { + *result2 = *first; + ++result2; + } + copy(buffer, result2, result1); + return result1; + } + else { + ForwardIterator middle = first; + advance(middle, len / 2); + ForwardIterator first_cut = + __stable_partition_adaptive(first, middle, pred, len / 2, + buffer, buffer_size); + ForwardIterator second_cut = + __stable_partition_adaptive(middle, last, pred, len - len / 2, + buffer, buffer_size); + + rotate(first_cut, middle, second_cut); + len = 0; + distance(middle, second_cut, len); + advance(first_cut, len); + return first_cut; + } +} + +template <class ForwardIterator, class Predicate, class T, class Distance> +inline ForwardIterator __stable_partition_aux(ForwardIterator first, + ForwardIterator last, + Predicate pred, T*, Distance*) { + temporary_buffer<ForwardIterator, T> 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 <class ForwardIterator, class Predicate> +inline ForwardIterator stable_partition(ForwardIterator first, + ForwardIterator last, + Predicate pred) { + if (first == last) + return first; + else + return __stable_partition_aux(first, last, pred, + value_type(first), distance_type(first)); +} + +template <class RandomAccessIterator, class T> +RandomAccessIterator __unguarded_partition(RandomAccessIterator first, + RandomAccessIterator last, + T pivot) { + while (true) { + while (*first < pivot) ++first; + --last; + while (pivot < *last) --last; + if (!(first < last)) return first; + iter_swap(first, last); + ++first; + } +} + +template <class RandomAccessIterator, class T, class Compare> +RandomAccessIterator __unguarded_partition(RandomAccessIterator first, + RandomAccessIterator last, + T pivot, Compare comp) { + while (1) { + while (comp(*first, pivot)) ++first; + --last; + while (comp(pivot, *last)) --last; + if (!(first < last)) return first; + iter_swap(first, last); + ++first; + } +} + +const int __stl_threshold = 16; + + +template <class RandomAccessIterator, class T> +void __unguarded_linear_insert(RandomAccessIterator last, T value) { + RandomAccessIterator next = last; + --next; + while (value < *next) { + *last = *next; + last = next; + --next; + } + *last = value; +} + +template <class RandomAccessIterator, class T, class Compare> +void __unguarded_linear_insert(RandomAccessIterator last, T value, + Compare comp) { + RandomAccessIterator next = last; + --next; + while (comp(value , *next)) { + *last = *next; + last = next; + --next; + } + *last = value; +} + +template <class RandomAccessIterator, class T> +inline void __linear_insert(RandomAccessIterator first, + RandomAccessIterator last, T*) { + T value = *last; + if (value < *first) { + copy_backward(first, last, last + 1); + *first = value; + } + else + __unguarded_linear_insert(last, value); +} + +template <class RandomAccessIterator, class T, class Compare> +inline void __linear_insert(RandomAccessIterator first, + RandomAccessIterator last, T*, Compare comp) { + T value = *last; + if (comp(value, *first)) { + copy_backward(first, last, last + 1); + *first = value; + } + else + __unguarded_linear_insert(last, value, comp); +} + +template <class RandomAccessIterator> +void __insertion_sort(RandomAccessIterator first, RandomAccessIterator last) { + if (first == last) return; + for (RandomAccessIterator i = first + 1; i != last; ++i) + __linear_insert(first, i, value_type(first)); +} + +template <class RandomAccessIterator, class Compare> +void __insertion_sort(RandomAccessIterator first, + RandomAccessIterator last, Compare comp) { + if (first == last) return; + for (RandomAccessIterator i = first + 1; i != last; ++i) + __linear_insert(first, i, value_type(first), comp); +} + +template <class RandomAccessIterator, class T> +void __unguarded_insertion_sort_aux(RandomAccessIterator first, + RandomAccessIterator last, T*) { + for (RandomAccessIterator i = first; i != last; ++i) + __unguarded_linear_insert(i, T(*i)); +} + +template <class RandomAccessIterator> +inline void __unguarded_insertion_sort(RandomAccessIterator first, + RandomAccessIterator last) { + __unguarded_insertion_sort_aux(first, last, value_type(first)); +} + +template <class RandomAccessIterator, class T, class Compare> +void __unguarded_insertion_sort_aux(RandomAccessIterator first, + RandomAccessIterator last, + T*, Compare comp) { + for (RandomAccessIterator i = first; i != last; ++i) + __unguarded_linear_insert(i, T(*i), comp); +} + +template <class RandomAccessIterator, class Compare> +inline void __unguarded_insertion_sort(RandomAccessIterator first, + RandomAccessIterator last, + Compare comp) { + __unguarded_insertion_sort_aux(first, last, value_type(first), comp); +} + +template <class RandomAccessIterator> +void __final_insertion_sort(RandomAccessIterator first, + RandomAccessIterator last) { + if (last - first > __stl_threshold) { + __insertion_sort(first, first + __stl_threshold); + __unguarded_insertion_sort(first + __stl_threshold, last); + } + else + __insertion_sort(first, last); +} + +template <class RandomAccessIterator, class Compare> +void __final_insertion_sort(RandomAccessIterator first, + RandomAccessIterator last, Compare comp) { + if (last - first > __stl_threshold) { + __insertion_sort(first, first + __stl_threshold, comp); + __unguarded_insertion_sort(first + __stl_threshold, last, comp); + } + else + __insertion_sort(first, last, comp); +} + +template <class Size> +inline Size __lg(Size n) { + Size k; + for (k = 0; n > 1; n >>= 1) ++k; + return k; +} + +template <class RandomAccessIterator, class T, class Size> +void __introsort_loop(RandomAccessIterator first, + RandomAccessIterator last, T*, + Size depth_limit) { + while (last - first > __stl_threshold) { + if (depth_limit == 0) { + partial_sort(first, last, last); + return; + } + --depth_limit; + RandomAccessIterator cut = __unguarded_partition + (first, last, T(__median(*first, *(first + (last - first)/2), + *(last - 1)))); + __introsort_loop(cut, last, value_type(first), depth_limit); + last = cut; + } +} + +template <class RandomAccessIterator, class T, class Size, class Compare> +void __introsort_loop(RandomAccessIterator first, + RandomAccessIterator last, T*, + Size depth_limit, Compare comp) { + while (last - first > __stl_threshold) { + if (depth_limit == 0) { + partial_sort(first, last, last, comp); + return; + } + --depth_limit; + RandomAccessIterator cut = __unguarded_partition + (first, last, T(__median(*first, *(first + (last - first)/2), + *(last - 1), comp)), comp); + __introsort_loop(cut, last, value_type(first), depth_limit, comp); + last = cut; + } +} + +template <class RandomAccessIterator> +inline void sort(RandomAccessIterator first, RandomAccessIterator last) { + if (first != last) { + __introsort_loop(first, last, value_type(first), __lg(last - first) * 2); + __final_insertion_sort(first, last); + } +} + +template <class RandomAccessIterator, class Compare> +inline void sort(RandomAccessIterator first, RandomAccessIterator last, + Compare comp) { + if (first != last) { + __introsort_loop(first, last, value_type(first), __lg(last - first) * 2, + comp); + __final_insertion_sort(first, last, comp); + } +} + + +template <class RandomAccessIterator> +void __inplace_stable_sort(RandomAccessIterator first, + RandomAccessIterator last) { + if (last - first < 15) { + __insertion_sort(first, last); + return; + } + RandomAccessIterator middle = first + (last - first) / 2; + __inplace_stable_sort(first, middle); + __inplace_stable_sort(middle, last); + __merge_without_buffer(first, middle, last, middle - first, last - middle); +} + +template <class RandomAccessIterator, class Compare> +void __inplace_stable_sort(RandomAccessIterator first, + RandomAccessIterator last, Compare comp) { + if (last - first < 15) { + __insertion_sort(first, last, comp); + return; + } + RandomAccessIterator middle = first + (last - first) / 2; + __inplace_stable_sort(first, middle, comp); + __inplace_stable_sort(middle, last, comp); + __merge_without_buffer(first, middle, last, middle - first, + last - middle, comp); +} + +template <class RandomAccessIterator1, class RandomAccessIterator2, + class Distance> +void __merge_sort_loop(RandomAccessIterator1 first, + RandomAccessIterator1 last, + RandomAccessIterator2 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 <class RandomAccessIterator1, class RandomAccessIterator2, + class Distance, class Compare> +void __merge_sort_loop(RandomAccessIterator1 first, + RandomAccessIterator1 last, + RandomAccessIterator2 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 <class RandomAccessIterator, class Distance> +void __chunk_insertion_sort(RandomAccessIterator first, + RandomAccessIterator last, Distance chunk_size) { + while (last - first >= chunk_size) { + __insertion_sort(first, first + chunk_size); + first += chunk_size; + } + __insertion_sort(first, last); +} + +template <class RandomAccessIterator, class Distance, class Compare> +void __chunk_insertion_sort(RandomAccessIterator first, + RandomAccessIterator last, + Distance chunk_size, Compare comp) { + while (last - first >= chunk_size) { + __insertion_sort(first, first + chunk_size, comp); + first += chunk_size; + } + __insertion_sort(first, last, comp); +} + +template <class RandomAccessIterator, class Pointer, class Distance> +void __merge_sort_with_buffer(RandomAccessIterator first, + RandomAccessIterator last, + Pointer buffer, Distance*) { + Distance len = last - first; + Pointer buffer_last = buffer + len; + + Distance step_size = __stl_chunk_size; + __chunk_insertion_sort(first, last, step_size); + + while (step_size < len) { + __merge_sort_loop(first, last, buffer, step_size); + step_size *= 2; + __merge_sort_loop(buffer, buffer_last, first, step_size); + step_size *= 2; + } +} + +template <class RandomAccessIterator, class Pointer, class Distance, + class Compare> +void __merge_sort_with_buffer(RandomAccessIterator first, + RandomAccessIterator last, Pointer buffer, + Distance*, Compare comp) { + Distance len = last - first; + Pointer buffer_last = buffer + len; + + Distance step_size = __stl_chunk_size; + __chunk_insertion_sort(first, last, step_size, comp); + + while (step_size < len) { + __merge_sort_loop(first, last, buffer, step_size, comp); + step_size *= 2; + __merge_sort_loop(buffer, buffer_last, first, step_size, comp); + step_size *= 2; + } +} + +template <class RandomAccessIterator, class Pointer, class Distance> +void __stable_sort_adaptive(RandomAccessIterator first, + RandomAccessIterator last, Pointer buffer, + Distance buffer_size) { + Distance len = (last - first + 1) / 2; + RandomAccessIterator middle = first + len; + if (len > buffer_size) { + __stable_sort_adaptive(first, middle, buffer, buffer_size); + __stable_sort_adaptive(middle, last, buffer, buffer_size); + } else { + __merge_sort_with_buffer(first, middle, buffer, (Distance*)0); + __merge_sort_with_buffer(middle, last, buffer, (Distance*)0); + } + __merge_adaptive(first, middle, last, Distance(middle - first), + Distance(last - middle), buffer, buffer_size); +} + +template <class RandomAccessIterator, class Pointer, class Distance, + class Compare> +void __stable_sort_adaptive(RandomAccessIterator first, + RandomAccessIterator last, Pointer buffer, + Distance buffer_size, Compare comp) { + Distance len = (last - first + 1) / 2; + RandomAccessIterator middle = first + len; + if (len > buffer_size) { + __stable_sort_adaptive(first, middle, buffer, buffer_size, + comp); + __stable_sort_adaptive(middle, last, buffer, buffer_size, + comp); + } else { + __merge_sort_with_buffer(first, middle, buffer, (Distance*)0, comp); + __merge_sort_with_buffer(middle, last, buffer, (Distance*)0, comp); + } + __merge_adaptive(first, middle, last, Distance(middle - first), + Distance(last - middle), buffer, buffer_size, + comp); +} + +template <class RandomAccessIterator, class T, class Distance> +inline void __stable_sort_aux(RandomAccessIterator first, + RandomAccessIterator last, T*, Distance*) { + temporary_buffer<RandomAccessIterator, T> buf(first, last); + if (buf.begin() == 0) + __inplace_stable_sort(first, last); + else + __stable_sort_adaptive(first, last, buf.begin(), Distance(buf.size())); +} + +template <class RandomAccessIterator, class T, class Distance, class Compare> +inline void __stable_sort_aux(RandomAccessIterator first, + RandomAccessIterator last, T*, Distance*, + Compare comp) { + temporary_buffer<RandomAccessIterator, T> 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 <class RandomAccessIterator> +inline void stable_sort(RandomAccessIterator first, + RandomAccessIterator last) { + __stable_sort_aux(first, last, value_type(first), distance_type(first)); +} + +template <class RandomAccessIterator, class Compare> +inline void stable_sort(RandomAccessIterator first, + RandomAccessIterator last, Compare comp) { + __stable_sort_aux(first, last, value_type(first), distance_type(first), + comp); +} + +template <class RandomAccessIterator, class T> +void __partial_sort(RandomAccessIterator first, RandomAccessIterator middle, + RandomAccessIterator last, T*) { + make_heap(first, middle); + for (RandomAccessIterator i = middle; i < last; ++i) + if (*i < *first) + __pop_heap(first, middle, i, T(*i), distance_type(first)); + sort_heap(first, middle); +} + +template <class RandomAccessIterator> +inline void partial_sort(RandomAccessIterator first, + RandomAccessIterator middle, + RandomAccessIterator last) { + __partial_sort(first, middle, last, value_type(first)); +} + +template <class RandomAccessIterator, class T, class Compare> +void __partial_sort(RandomAccessIterator first, RandomAccessIterator middle, + RandomAccessIterator last, T*, Compare comp) { + make_heap(first, middle, comp); + for (RandomAccessIterator i = middle; i < last; ++i) + if (comp(*i, *first)) + __pop_heap(first, middle, i, T(*i), comp, distance_type(first)); + sort_heap(first, middle, comp); +} + +template <class RandomAccessIterator, class Compare> +inline void partial_sort(RandomAccessIterator first, + RandomAccessIterator middle, + RandomAccessIterator last, Compare comp) { + __partial_sort(first, middle, last, value_type(first), comp); +} + +template <class InputIterator, class RandomAccessIterator, class Distance, + class T> +RandomAccessIterator __partial_sort_copy(InputIterator first, + InputIterator last, + RandomAccessIterator result_first, + RandomAccessIterator result_last, + Distance*, T*) { + if (result_first == result_last) return result_last; + RandomAccessIterator result_real_last = result_first; + while(first != last && result_real_last != result_last) { + *result_real_last = *first; + ++result_real_last; + ++first; + } + make_heap(result_first, result_real_last); + while (first != last) { + if (*first < *result_first) + __adjust_heap(result_first, Distance(0), + Distance(result_real_last - result_first), T(*first)); + ++first; + } + sort_heap(result_first, result_real_last); + return result_real_last; +} + +template <class InputIterator, class RandomAccessIterator> +inline RandomAccessIterator +partial_sort_copy(InputIterator first, InputIterator last, + RandomAccessIterator result_first, + RandomAccessIterator result_last) { + return __partial_sort_copy(first, last, result_first, result_last, + distance_type(result_first), value_type(first)); +} + +template <class InputIterator, class RandomAccessIterator, class Compare, + class Distance, class T> +RandomAccessIterator __partial_sort_copy(InputIterator first, + InputIterator last, + RandomAccessIterator result_first, + RandomAccessIterator result_last, + Compare comp, Distance*, T*) { + if (result_first == result_last) return result_last; + RandomAccessIterator result_real_last = result_first; + while(first != last && result_real_last != result_last) { + *result_real_last = *first; + ++result_real_last; + ++first; + } + make_heap(result_first, result_real_last, comp); + while (first != last) { + if (comp(*first, *result_first)) + __adjust_heap(result_first, Distance(0), + Distance(result_real_last - result_first), T(*first), + comp); + ++first; + } + sort_heap(result_first, result_real_last, comp); + return result_real_last; +} + +template <class InputIterator, class RandomAccessIterator, class Compare> +inline RandomAccessIterator +partial_sort_copy(InputIterator first, InputIterator last, + RandomAccessIterator result_first, + RandomAccessIterator result_last, Compare comp) { + return __partial_sort_copy(first, last, result_first, result_last, comp, + distance_type(result_first), value_type(first)); +} + +template <class RandomAccessIterator, class T> +void __nth_element(RandomAccessIterator first, RandomAccessIterator nth, + RandomAccessIterator last, T*) { + while (last - first > 3) { + RandomAccessIterator cut = __unguarded_partition + (first, last, T(__median(*first, *(first + (last - first)/2), + *(last - 1)))); + if (cut <= nth) + first = cut; + else + last = cut; + } + __insertion_sort(first, last); +} + +template <class RandomAccessIterator> +inline void nth_element(RandomAccessIterator first, RandomAccessIterator nth, + RandomAccessIterator last) { + __nth_element(first, nth, last, value_type(first)); +} + +template <class RandomAccessIterator, class T, class Compare> +void __nth_element(RandomAccessIterator first, RandomAccessIterator nth, + RandomAccessIterator last, T*, Compare comp) { + while (last - first > 3) { + RandomAccessIterator cut = __unguarded_partition + (first, last, T(__median(*first, *(first + (last - first)/2), + *(last - 1), comp)), comp); + if (cut <= nth) + first = cut; + else + last = cut; + } + __insertion_sort(first, last, comp); +} + +template <class RandomAccessIterator, class Compare> +inline void nth_element(RandomAccessIterator first, RandomAccessIterator nth, + RandomAccessIterator last, Compare comp) { + __nth_element(first, nth, last, value_type(first), comp); +} + +template <class ForwardIterator, class T, class Distance> +ForwardIterator __lower_bound(ForwardIterator first, ForwardIterator last, + const T& value, Distance*, + forward_iterator_tag) { + Distance len = 0; + distance(first, last, len); + Distance half; + ForwardIterator middle; + + while (len > 0) { + half = len >> 1; + middle = first; + advance(middle, half); + if (*middle < value) { + first = middle; + ++first; + len = len - half - 1; + } + else + len = half; + } + return first; +} + +template <class RandomAccessIterator, class T, class Distance> +RandomAccessIterator __lower_bound(RandomAccessIterator first, + RandomAccessIterator last, const T& value, + Distance*, random_access_iterator_tag) { + Distance len = last - first; + Distance half; + RandomAccessIterator middle; + + while (len > 0) { + half = len >> 1; + middle = first + half; + if (*middle < value) { + first = middle + 1; + len = len - half - 1; + } + else + len = half; + } + return first; +} + +template <class ForwardIterator, class T> +inline ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, + const T& value) { + return __lower_bound(first, last, value, distance_type(first), + iterator_category(first)); +} + +template <class ForwardIterator, class T, class Compare, class Distance> +ForwardIterator __lower_bound(ForwardIterator first, ForwardIterator last, + const T& value, Compare comp, Distance*, + forward_iterator_tag) { + Distance len = 0; + distance(first, last, len); + Distance half; + ForwardIterator middle; + + while (len > 0) { + half = len >> 1; + middle = first; + advance(middle, half); + if (comp(*middle, value)) { + first = middle; + ++first; + len = len - half - 1; + } + else + len = half; + } + return first; +} + +template <class RandomAccessIterator, class T, class Compare, class Distance> +RandomAccessIterator __lower_bound(RandomAccessIterator first, + RandomAccessIterator last, + const T& value, Compare comp, Distance*, + random_access_iterator_tag) { + Distance len = last - first; + Distance half; + RandomAccessIterator middle; + + while (len > 0) { + half = len >> 1; + middle = first + half; + if (comp(*middle, value)) { + first = middle + 1; + len = len - half - 1; + } + else + len = half; + } + return first; +} + +template <class ForwardIterator, class T, class Compare> +inline ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, + const T& value, Compare comp) { + return __lower_bound(first, last, value, comp, distance_type(first), + iterator_category(first)); +} + +template <class ForwardIterator, class T, class Distance> +ForwardIterator __upper_bound(ForwardIterator first, ForwardIterator last, + const T& value, Distance*, + forward_iterator_tag) { + Distance len = 0; + distance(first, last, len); + Distance half; + ForwardIterator middle; + + while (len > 0) { + half = len >> 1; + middle = first; + advance(middle, half); + if (value < *middle) + len = half; + else { + first = middle; + ++first; + len = len - half - 1; + } + } + return first; +} + +template <class RandomAccessIterator, class T, class Distance> +RandomAccessIterator __upper_bound(RandomAccessIterator first, + RandomAccessIterator last, const T& value, + Distance*, random_access_iterator_tag) { + Distance len = last - first; + Distance half; + RandomAccessIterator middle; + + while (len > 0) { + half = len >> 1; + middle = first + half; + if (value < *middle) + len = half; + else { + first = middle + 1; + len = len - half - 1; + } + } + return first; +} + +template <class ForwardIterator, class T> +inline ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last, + const T& value) { + return __upper_bound(first, last, value, distance_type(first), + iterator_category(first)); +} + +template <class ForwardIterator, class T, class Compare, class Distance> +ForwardIterator __upper_bound(ForwardIterator first, ForwardIterator last, + const T& value, Compare comp, Distance*, + forward_iterator_tag) { + Distance len = 0; + distance(first, last, len); + Distance half; + ForwardIterator middle; + + while (len > 0) { + half = len >> 1; + middle = first; + advance(middle, half); + if (comp(value, *middle)) + len = half; + else { + first = middle; + ++first; + len = len - half - 1; + } + } + return first; +} + +template <class RandomAccessIterator, class T, class Compare, class Distance> +RandomAccessIterator __upper_bound(RandomAccessIterator first, + RandomAccessIterator last, + const T& value, Compare comp, Distance*, + random_access_iterator_tag) { + Distance len = last - first; + Distance half; + RandomAccessIterator middle; + + while (len > 0) { + half = len >> 1; + middle = first + half; + if (comp(value, *middle)) + len = half; + else { + first = middle + 1; + len = len - half - 1; + } + } + return first; +} + +template <class ForwardIterator, class T, class Compare> +inline ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last, + const T& value, Compare comp) { + return __upper_bound(first, last, value, comp, distance_type(first), + iterator_category(first)); +} + +template <class ForwardIterator, class T, class Distance> +pair<ForwardIterator, ForwardIterator> +__equal_range(ForwardIterator first, ForwardIterator last, const T& value, + Distance*, forward_iterator_tag) { + Distance len = 0; + distance(first, last, len); + Distance half; + ForwardIterator middle, left, right; + + while (len > 0) { + half = len >> 1; + middle = first; + advance(middle, half); + if (*middle < value) { + first = middle; + ++first; + len = len - half - 1; + } + else if (value < *middle) + len = half; + else { + left = lower_bound(first, middle, value); + advance(first, len); + right = upper_bound(++middle, first, value); + return pair<ForwardIterator, ForwardIterator>(left, right); + } + } + return pair<ForwardIterator, ForwardIterator>(first, first); +} + +template <class RandomAccessIterator, class T, class Distance> +pair<RandomAccessIterator, RandomAccessIterator> +__equal_range(RandomAccessIterator first, RandomAccessIterator last, + const T& value, Distance*, random_access_iterator_tag) { + Distance len = last - first; + Distance half; + RandomAccessIterator middle, left, right; + + while (len > 0) { + half = len >> 1; + middle = first + half; + if (*middle < value) { + first = middle + 1; + len = len - half - 1; + } + else if (value < *middle) + len = half; + else { + left = lower_bound(first, middle, value); + right = upper_bound(++middle, first + len, value); + return pair<RandomAccessIterator, RandomAccessIterator>(left, + right); + } + } + return pair<RandomAccessIterator, RandomAccessIterator>(first, first); +} + +template <class ForwardIterator, class T> +inline pair<ForwardIterator, ForwardIterator> +equal_range(ForwardIterator first, ForwardIterator last, const T& value) { + return __equal_range(first, last, value, distance_type(first), + iterator_category(first)); +} + +template <class ForwardIterator, class T, class Compare, class Distance> +pair<ForwardIterator, ForwardIterator> +__equal_range(ForwardIterator first, ForwardIterator last, const T& value, + Compare comp, Distance*, forward_iterator_tag) { + Distance len = 0; + distance(first, last, len); + Distance half; + ForwardIterator middle, left, right; + + while (len > 0) { + half = len >> 1; + middle = first; + advance(middle, half); + if (comp(*middle, value)) { + first = middle; + ++first; + len = len - half - 1; + } + else if (comp(value, *middle)) + len = half; + else { + left = lower_bound(first, middle, value, comp); + advance(first, len); + right = upper_bound(++middle, first, value, comp); + return pair<ForwardIterator, ForwardIterator>(left, right); + } + } + return pair<ForwardIterator, ForwardIterator>(first, first); +} + +template <class RandomAccessIterator, class T, class Compare, class Distance> +pair<RandomAccessIterator, RandomAccessIterator> +__equal_range(RandomAccessIterator first, RandomAccessIterator last, + const T& value, Compare comp, Distance*, + random_access_iterator_tag) { + Distance len = last - first; + Distance half; + RandomAccessIterator middle, left, right; + + while (len > 0) { + half = len >> 1; + middle = first + half; + if (comp(*middle, value)) { + first = middle + 1; + len = len - half - 1; + } + else if (comp(value, *middle)) + len = half; + else { + left = lower_bound(first, middle, value, comp); + right = upper_bound(++middle, first + len, value, comp); + return pair<RandomAccessIterator, RandomAccessIterator>(left, + right); + } + } + return pair<RandomAccessIterator, RandomAccessIterator>(first, first); +} + +template <class ForwardIterator, class T, class Compare> +inline pair<ForwardIterator, ForwardIterator> +equal_range(ForwardIterator first, ForwardIterator last, const T& value, + Compare comp) { + return __equal_range(first, last, value, comp, distance_type(first), + iterator_category(first)); +} + +template <class ForwardIterator, class T> +bool binary_search(ForwardIterator first, ForwardIterator last, + const T& value) { + ForwardIterator i = lower_bound(first, last, value); + return i != last && !(value < *i); +} + +template <class ForwardIterator, class T, class Compare> +bool binary_search(ForwardIterator first, ForwardIterator last, const T& value, + Compare comp) { + ForwardIterator i = lower_bound(first, last, value, comp); + return i != last && !comp(value, *i); +} + +template <class InputIterator1, class InputIterator2, class OutputIterator> +OutputIterator merge(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator 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 <class InputIterator1, class InputIterator2, class OutputIterator, + class Compare> +OutputIterator merge(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result, Compare comp) { + while (first1 != last1 && first2 != last2) { + if (comp(*first2, *first1)) { + *result = *first2; + ++first2; + } + else { + *result = *first1; + ++first1; + } + ++result; + } + return copy(first2, last2, copy(first1, last1, result)); +} + +template <class BidirectionalIterator, class Distance> +void __merge_without_buffer(BidirectionalIterator first, + BidirectionalIterator middle, + BidirectionalIterator last, + Distance len1, Distance len2) { + if (len1 == 0 || len2 == 0) return; + if (len1 + len2 == 2) { + if (*middle < *first) iter_swap(first, middle); + return; + } + BidirectionalIterator first_cut = first; + BidirectionalIterator second_cut = middle; + Distance len11 = 0; + Distance len22 = 0; + if (len1 > len2) { + len11 = len1 / 2; + advance(first_cut, len11); + second_cut = lower_bound(middle, last, *first_cut); + distance(middle, second_cut, len22); + } + else { + len22 = len2 / 2; + advance(second_cut, len22); + first_cut = upper_bound(first, middle, *second_cut); + distance(first, first_cut, len11); + } + rotate(first_cut, middle, second_cut); + BidirectionalIterator new_middle = first_cut; + advance(new_middle, len22); + __merge_without_buffer(first, first_cut, new_middle, len11, len22); + __merge_without_buffer(new_middle, second_cut, last, len1 - len11, + len2 - len22); +} + +template <class BidirectionalIterator, class Distance, class Compare> +void __merge_without_buffer(BidirectionalIterator first, + BidirectionalIterator middle, + BidirectionalIterator last, + Distance len1, Distance len2, Compare comp) { + if (len1 == 0 || len2 == 0) return; + if (len1 + len2 == 2) { + if (comp(*middle, *first)) iter_swap(first, middle); + return; + } + BidirectionalIterator first_cut = first; + BidirectionalIterator second_cut = middle; + Distance len11 = 0; + Distance len22 = 0; + if (len1 > len2) { + len11 = len1 / 2; + advance(first_cut, len11); + second_cut = lower_bound(middle, last, *first_cut, comp); + distance(middle, second_cut, len22); + } + else { + len22 = len2 / 2; + advance(second_cut, len22); + first_cut = upper_bound(first, middle, *second_cut, comp); + distance(first, first_cut, len11); + } + rotate(first_cut, middle, second_cut); + BidirectionalIterator new_middle = first_cut; + advance(new_middle, len22); + __merge_without_buffer(first, first_cut, new_middle, len11, len22, comp); + __merge_without_buffer(new_middle, second_cut, last, len1 - len11, + len2 - len22, comp); +} + +template <class BidirectionalIterator1, class BidirectionalIterator2, + class Distance> +BidirectionalIterator1 __rotate_adaptive(BidirectionalIterator1 first, + BidirectionalIterator1 middle, + BidirectionalIterator1 last, + Distance len1, Distance len2, + BidirectionalIterator2 buffer, + Distance buffer_size) { + BidirectionalIterator2 buffer_end; + if (len1 > len2 && len2 <= buffer_size) { + buffer_end = copy(middle, last, buffer); + copy_backward(first, middle, last); + return copy(buffer, buffer_end, first); + } else if (len1 <= buffer_size) { + buffer_end = copy(first, middle, buffer); + copy(middle, last, first); + return copy_backward(buffer, buffer_end, last); + } else { + rotate(first, middle, last); + advance(first, len2); + return first; + } +} + +template <class BidirectionalIterator1, class BidirectionalIterator2, + class BidirectionalIterator3> +BidirectionalIterator3 __merge_backward(BidirectionalIterator1 first1, + BidirectionalIterator1 last1, + BidirectionalIterator2 first2, + BidirectionalIterator2 last2, + BidirectionalIterator3 result) { + if (first1 == last1) return copy_backward(first2, last2, result); + if (first2 == last2) return copy_backward(first1, last1, result); + --last1; + --last2; + 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 <class BidirectionalIterator1, class BidirectionalIterator2, + class BidirectionalIterator3, class Compare> +BidirectionalIterator3 __merge_backward(BidirectionalIterator1 first1, + BidirectionalIterator1 last1, + BidirectionalIterator2 first2, + BidirectionalIterator2 last2, + BidirectionalIterator3 result, + Compare comp) { + if (first1 == last1) return copy_backward(first2, last2, result); + if (first2 == last2) return copy_backward(first1, last1, result); + --last1; + --last2; + 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 <class BidirectionalIterator, class Distance, class Pointer> +void __merge_adaptive(BidirectionalIterator first, + BidirectionalIterator middle, + BidirectionalIterator last, Distance len1, Distance len2, + Pointer buffer, Distance buffer_size) { + if (len1 <= len2 && len1 <= buffer_size) { + Pointer end_buffer = copy(first, middle, buffer); + merge(buffer, end_buffer, middle, last, first); + } + else if (len2 <= buffer_size) { + Pointer end_buffer = copy(middle, last, buffer); + __merge_backward(first, middle, buffer, end_buffer, last); + } + else { + BidirectionalIterator first_cut = first; + BidirectionalIterator second_cut = middle; + Distance len11 = 0; + Distance len22 = 0; + if (len1 > len2) { + len11 = len1 / 2; + advance(first_cut, len11); + second_cut = lower_bound(middle, last, *first_cut); + distance(middle, second_cut, len22); + } + else { + len22 = len2 / 2; + advance(second_cut, len22); + first_cut = upper_bound(first, middle, *second_cut); + distance(first, first_cut, len11); + } + BidirectionalIterator new_middle = + __rotate_adaptive(first_cut, middle, second_cut, len1 - len11, + len22, buffer, buffer_size); + __merge_adaptive(first, first_cut, new_middle, len11, len22, buffer, + buffer_size); + __merge_adaptive(new_middle, second_cut, last, len1 - len11, + len2 - len22, buffer, buffer_size); + } +} + +template <class BidirectionalIterator, class Distance, class Pointer, + class Compare> +void __merge_adaptive(BidirectionalIterator first, + BidirectionalIterator middle, + BidirectionalIterator last, Distance len1, Distance len2, + Pointer buffer, Distance buffer_size, Compare comp) { + if (len1 <= len2 && len1 <= buffer_size) { + Pointer end_buffer = copy(first, middle, buffer); + merge(buffer, end_buffer, middle, last, first, comp); + } + else if (len2 <= buffer_size) { + Pointer end_buffer = copy(middle, last, buffer); + __merge_backward(first, middle, buffer, end_buffer, last, comp); + } + else { + BidirectionalIterator first_cut = first; + BidirectionalIterator second_cut = middle; + Distance len11 = 0; + Distance len22 = 0; + if (len1 > len2) { + len11 = len1 / 2; + advance(first_cut, len11); + second_cut = lower_bound(middle, last, *first_cut, comp); + distance(middle, second_cut, len22); + } + else { + len22 = len2 / 2; + advance(second_cut, len22); + first_cut = upper_bound(first, middle, *second_cut, comp); + distance(first, first_cut, len11); + } + BidirectionalIterator new_middle = + __rotate_adaptive(first_cut, middle, second_cut, len1 - len11, + len22, buffer, buffer_size); + __merge_adaptive(first, first_cut, new_middle, len11, len22, buffer, + buffer_size, comp); + __merge_adaptive(new_middle, second_cut, last, len1 - len11, + len2 - len22, buffer, buffer_size, comp); + } +} + +template <class BidirectionalIterator, class T, class Distance> +inline void __inplace_merge_aux(BidirectionalIterator first, + BidirectionalIterator middle, + BidirectionalIterator last, T*, Distance*) { + Distance len1 = 0; + distance(first, middle, len1); + Distance len2 = 0; + distance(middle, last, len2); + + temporary_buffer<BidirectionalIterator, T> 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 <class BidirectionalIterator, class T, class Distance, class Compare> +inline void __inplace_merge_aux(BidirectionalIterator first, + BidirectionalIterator middle, + BidirectionalIterator last, T*, Distance*, + Compare comp) { + Distance len1 = 0; + distance(first, middle, len1); + Distance len2 = 0; + distance(middle, last, len2); + + temporary_buffer<BidirectionalIterator, T> 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 <class BidirectionalIterator> +inline void inplace_merge(BidirectionalIterator first, + BidirectionalIterator middle, + BidirectionalIterator last) { + if (first == middle || middle == last) return; + __inplace_merge_aux(first, middle, last, value_type(first), + distance_type(first)); +} + +template <class BidirectionalIterator, class Compare> +inline void inplace_merge(BidirectionalIterator first, + BidirectionalIterator middle, + BidirectionalIterator last, Compare comp) { + if (first == middle || middle == last) return; + __inplace_merge_aux(first, middle, last, value_type(first), + distance_type(first), comp); +} + +template <class InputIterator1, class InputIterator2> +bool includes(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2) { + while (first1 != last1 && first2 != last2) + if (*first2 < *first1) + return false; + else if(*first1 < *first2) + ++first1; + else + ++first1, ++first2; + + return first2 == last2; +} + +template <class InputIterator1, class InputIterator2, class Compare> +bool includes(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 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 <class InputIterator1, class InputIterator2, class OutputIterator> +OutputIterator set_union(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator 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 <class InputIterator1, class InputIterator2, class OutputIterator, + class Compare> +OutputIterator set_union(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result, Compare comp) { + while (first1 != last1 && first2 != last2) { + if (comp(*first1, *first2)) { + *result = *first1; + ++first1; + } + else if (comp(*first2, *first1)) { + *result = *first2; + ++first2; + } + else { + *result = *first1; + ++first1; + ++first2; + } + ++result; + } + return copy(first2, last2, copy(first1, last1, result)); +} + +template <class InputIterator1, class InputIterator2, class OutputIterator> +OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result) { + while (first1 != last1 && first2 != last2) + if (*first1 < *first2) + ++first1; + else if (*first2 < *first1) + ++first2; + else { + *result = *first1; + ++first1; + ++first2; + ++result; + } + return result; +} + +template <class InputIterator1, class InputIterator2, class OutputIterator, + class Compare> +OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result, Compare comp) { + while (first1 != last1 && first2 != last2) + if (comp(*first1, *first2)) + ++first1; + else if (comp(*first2, *first1)) + ++first2; + else { + *result = *first1; + ++first1; + ++first2; + ++result; + } + return result; +} + +template <class InputIterator1, class InputIterator2, class OutputIterator> +OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result) { + while (first1 != last1 && first2 != last2) + if (*first1 < *first2) { + *result = *first1; + ++first1; + ++result; + } + else if (*first2 < *first1) + ++first2; + else { + ++first1; + ++first2; + } + return copy(first1, last1, result); +} + +template <class InputIterator1, class InputIterator2, class OutputIterator, + class Compare> +OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result, Compare comp) { + while (first1 != last1 && first2 != last2) + if (comp(*first1, *first2)) { + *result = *first1; + ++first1; + ++result; + } + else if (comp(*first2, *first1)) + ++first2; + else { + ++first1; + ++first2; + } + return copy(first1, last1, result); +} + +template <class InputIterator1, class InputIterator2, class OutputIterator> +OutputIterator set_symmetric_difference(InputIterator1 first1, + InputIterator1 last1, + InputIterator2 first2, + InputIterator2 last2, + OutputIterator result) { + while (first1 != last1 && first2 != last2) + if (*first1 < *first2) { + *result = *first1; + ++first1; + ++result; + } + else if (*first2 < *first1) { + *result = *first2; + ++first2; + ++result; + } + else { + ++first1; + ++first2; + } + return copy(first2, last2, copy(first1, last1, result)); +} + +template <class InputIterator1, class InputIterator2, class OutputIterator, + class Compare> +OutputIterator set_symmetric_difference(InputIterator1 first1, + InputIterator1 last1, + InputIterator2 first2, + InputIterator2 last2, + OutputIterator result, Compare comp) { + while (first1 != last1 && first2 != last2) + if (comp(*first1, *first2)) { + *result = *first1; + ++first1; + ++result; + } + else if (comp(*first2, *first1)) { + *result = *first2; + ++first2; + ++result; + } + else { + ++first1; + ++first2; + } + return copy(first2, last2, copy(first1, last1, result)); +} + +template <class ForwardIterator> +ForwardIterator max_element(ForwardIterator first, ForwardIterator last) { + if (first == last) return first; + ForwardIterator result = first; + while (++first != last) + if (*result < *first) result = first; + return result; +} + +template <class ForwardIterator, class Compare> +ForwardIterator max_element(ForwardIterator first, ForwardIterator last, + Compare comp) { + if (first == last) return first; + ForwardIterator result = first; + while (++first != last) + if (comp(*result, *first)) result = first; + return result; +} + +template <class ForwardIterator> +ForwardIterator min_element(ForwardIterator first, ForwardIterator last) { + if (first == last) return first; + ForwardIterator result = first; + while (++first != last) + if (*first < *result) result = first; + return result; +} + +template <class ForwardIterator, class Compare> +ForwardIterator min_element(ForwardIterator first, ForwardIterator last, + Compare comp) { + if (first == last) return first; + ForwardIterator result = first; + while (++first != last) + if (comp(*first, *result)) result = first; + return result; +} + +template <class BidirectionalIterator> +bool next_permutation(BidirectionalIterator first, + BidirectionalIterator last) { + if (first == last) return false; + BidirectionalIterator i = first; + ++i; + if (i == last) return false; + i = last; + --i; + + for(;;) { + BidirectionalIterator ii = i; + --i; + if (*i < *ii) { + BidirectionalIterator j = last; + while (!(*i < *--j)); + iter_swap(i, j); + reverse(ii, last); + return true; + } + if (i == first) { + reverse(first, last); + return false; + } + } +} + +template <class BidirectionalIterator, class Compare> +bool next_permutation(BidirectionalIterator first, BidirectionalIterator last, + Compare comp) { + if (first == last) return false; + BidirectionalIterator i = first; + ++i; + if (i == last) return false; + i = last; + --i; + + for(;;) { + BidirectionalIterator ii = i; + --i; + if (comp(*i, *ii)) { + BidirectionalIterator j = last; + while (!comp(*i, *--j)); + iter_swap(i, j); + reverse(ii, last); + return true; + } + if (i == first) { + reverse(first, last); + return false; + } + } +} + +template <class BidirectionalIterator> +bool prev_permutation(BidirectionalIterator first, + BidirectionalIterator last) { + if (first == last) return false; + BidirectionalIterator i = first; + ++i; + if (i == last) return false; + i = last; + --i; + + for(;;) { + BidirectionalIterator ii = i; + --i; + if (*ii < *i) { + BidirectionalIterator j = last; + while (!(*--j < *i)); + iter_swap(i, j); + reverse(ii, last); + return true; + } + if (i == first) { + reverse(first, last); + return false; + } + } +} + +template <class BidirectionalIterator, class Compare> +bool prev_permutation(BidirectionalIterator first, BidirectionalIterator last, + Compare comp) { + if (first == last) return false; + BidirectionalIterator i = first; + ++i; + if (i == last) return false; + i = last; + --i; + + for(;;) { + BidirectionalIterator ii = i; + --i; + if (comp(*ii, *i)) { + BidirectionalIterator j = last; + while (!comp(*--j, *i)); + iter_swap(i, j); + reverse(ii, last); + return true; + } + if (i == first) { + reverse(first, last); + return false; + } + } +} + +template <class InputIterator, class ForwardIterator> +InputIterator find_first_of(InputIterator first1, InputIterator last1, + ForwardIterator first2, ForwardIterator last2) +{ + for ( ; first1 != last1; ++first1) + for (ForwardIterator iter = first2; iter != last2; ++iter) + if (*first1 == *iter) + return first1; + return last1; +} + +template <class InputIterator, class ForwardIterator, class BinaryPredicate> +InputIterator find_first_of(InputIterator first1, InputIterator last1, + ForwardIterator first2, ForwardIterator last2, + BinaryPredicate comp) +{ + for ( ; first1 != last1; ++first1) + for (ForwardIterator iter = first2; iter != last2; ++iter) + if (comp(*first1, *iter)) + return first1; + return last1; +} + + +// Search [first2, last2) as a subsequence in [first1, last1). + +// find_end for forward iterators. +template <class ForwardIterator1, class ForwardIterator2> +ForwardIterator1 __find_end(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + forward_iterator_tag, forward_iterator_tag) +{ + if (first2 == last2) + return last1; + else { + ForwardIterator1 result = last1; + while (1) { + ForwardIterator1 new_result = search(first1, last1, first2, last2); + if (new_result == last1) + return result; + else { + result = new_result; + first1 = new_result; + ++first1; + } + } + } +} + +template <class ForwardIterator1, class ForwardIterator2, + class BinaryPredicate> +ForwardIterator1 __find_end(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + forward_iterator_tag, forward_iterator_tag, + BinaryPredicate comp) +{ + if (first2 == last2) + return last1; + else { + ForwardIterator1 result = last1; + while (1) { + ForwardIterator1 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 <class BidirectionalIterator1, class BidirectionalIterator2> +BidirectionalIterator1 +__find_end(BidirectionalIterator1 first1, BidirectionalIterator1 last1, + BidirectionalIterator2 first2, BidirectionalIterator2 last2, + bidirectional_iterator_tag, bidirectional_iterator_tag) +{ + typedef reverse_iterator<BidirectionalIterator1> reviter1; + typedef reverse_iterator<BidirectionalIterator2> reviter2; + + reviter1 rlast1(first1); + reviter2 rlast2(first2); + reviter1 rresult = search(reviter1(last1), rlast1, reviter2(last2), rlast2); + + if (rresult == rlast1) + return last1; + else { + BidirectionalIterator1 result = rresult.base(); + advance(result, -distance(first2, last2)); + return result; + } +} + +template <class BidirectionalIterator1, class BidirectionalIterator2, + class BinaryPredicate> +BidirectionalIterator1 +__find_end(BidirectionalIterator1 first1, BidirectionalIterator1 last1, + BidirectionalIterator2 first2, BidirectionalIterator2 last2, + bidirectional_iterator_tag, bidirectional_iterator_tag, + BinaryPredicate comp) +{ + typedef reverse_iterator<BidirectionalIterator1> reviter1; + typedef reverse_iterator<BidirectionalIterator2> reviter2; + + reviter1 rlast1(first1); + reviter2 rlast2(first2); + reviter1 rresult = search(reviter1(last1), rlast1, reviter2(last2), rlast2, + comp); + + if (rresult == rlast1) + return last1; + else { + BidirectionalIterator1 result = rresult.base(); + advance(result, -distance(first2, last2)); + return result; + } +} +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +// Dispatching functions. + +template <class ForwardIterator1, class ForwardIterator2> +inline ForwardIterator1 +find_end(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2) +{ +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + typedef typename iterator_traits<ForwardIterator1>::iterator_category + category1; + typedef typename iterator_traits<ForwardIterator2>::iterator_category + category2; + return __find_end(first1, last1, first2, last2, category1(), category2()); +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + return __find_end(first1, last1, first2, last2, + forward_iterator_tag(), forward_iterator_tag()); +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ +} + +template <class ForwardIterator1, class ForwardIterator2, + class BinaryPredicate> +inline ForwardIterator1 +find_end(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate comp) +{ +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + typedef typename iterator_traits<ForwardIterator1>::iterator_category + category1; + typedef typename iterator_traits<ForwardIterator2>::iterator_category + category2; + return __find_end(first1, last1, first2, last2, category1(), category2(), + comp); +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + return __find_end(first1, last1, first2, last2, + forward_iterator_tag(), forward_iterator_tag(), + comp); +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ +} + +template <class RandomAccessIterator, class Distance> +bool __is_heap(RandomAccessIterator first, RandomAccessIterator last, + Distance*) +{ + const Distance n = last - first; + + 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 <class RandomAccessIterator> +inline bool is_heap(RandomAccessIterator first, RandomAccessIterator last) +{ + return __is_heap(first, last, distance_type(first)); +} + + +template <class RandomAccessIterator, class Distance, class StrictWeakOrdering> +bool __is_heap(RandomAccessIterator first, RandomAccessIterator last, + StrictWeakOrdering comp, + Distance*) +{ + const Distance n = last - first; + + 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 <class RandomAccessIterator, class StrictWeakOrdering> +inline bool is_heap(RandomAccessIterator first, RandomAccessIterator last, + StrictWeakOrdering comp) +{ + return __is_heap(first, last, comp, distance_type(first)); +} + + +template <class ForwardIterator> +bool is_sorted(ForwardIterator first, ForwardIterator last) +{ + if (first == last) + return true; + + ForwardIterator next = first; + for (++next; next != last; first = next, ++next) { + if (*next < *first) + return false; + } + + return true; +} + +template <class ForwardIterator, class StrictWeakOrdering> +bool is_sorted(ForwardIterator first, ForwardIterator last, + StrictWeakOrdering comp) +{ + if (first == last) + return true; + + ForwardIterator 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/contrib/libstdc++/stl/stl_algobase.h b/contrib/libstdc++/stl/stl_algobase.h new file mode 100644 index 0000000..101fea5 --- /dev/null +++ b/contrib/libstdc++/stl/stl_algobase.h @@ -0,0 +1,442 @@ +/* + * + * 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_ALGOBASE_H +#define __SGI_STL_INTERNAL_ALGOBASE_H + +#ifndef __STL_CONFIG_H +#include <stl_config.h> +#endif +#ifndef __SGI_STL_INTERNAL_RELOPS +#include <stl_relops.h> +#endif +#ifndef __SGI_STL_INTERNAL_PAIR_H +#include <stl_pair.h> +#endif +#ifndef __TYPE_TRAITS_H_ +#include <type_traits.h> +#endif + +#include <string.h> +#include <limits.h> +#include <stdlib.h> +#include <stddef.h> +#include <new.h> +#include <iostream.h> + +#ifndef __SGI_STL_INTERNAL_ITERATOR_H +#include <stl_iterator.h> +#endif + +__STL_BEGIN_NAMESPACE + +template <class ForwardIterator1, class ForwardIterator2, class T> +inline void __iter_swap(ForwardIterator1 a, ForwardIterator2 b, T*) { + T tmp = *a; + *a = *b; + *b = tmp; +} + +template <class ForwardIterator1, class ForwardIterator2> +inline void iter_swap(ForwardIterator1 a, ForwardIterator2 b) { + __iter_swap(a, b, value_type(a)); +} + +template <class T> +inline void swap(T& a, T& b) { + T tmp = a; + a = b; + b = tmp; +} + +#ifndef __BORLANDC__ + +#undef min +#undef max + +template <class T> +inline const T& min(const T& a, const T& b) { + return b < a ? b : a; +} + +template <class T> +inline const T& max(const T& a, const T& b) { + return a < b ? b : a; +} + +#endif /* __BORLANDC__ */ + +template <class T, class Compare> +inline const T& min(const T& a, const T& b, Compare comp) { + return comp(b, a) ? b : a; +} + +template <class T, class Compare> +inline const T& max(const T& a, const T& b, Compare comp) { + return comp(a, b) ? b : a; +} + +template <class InputIterator, class OutputIterator> +inline OutputIterator __copy(InputIterator first, InputIterator last, + OutputIterator result, input_iterator_tag) +{ + for ( ; first != last; ++result, ++first) + *result = *first; + return result; +} + +template <class RandomAccessIterator, class OutputIterator, class Distance> +inline OutputIterator +__copy_d(RandomAccessIterator first, RandomAccessIterator last, + OutputIterator result, Distance*) +{ + for (Distance n = last - first; n > 0; --n, ++result, ++first) + *result = *first; + return result; +} + +template <class RandomAccessIterator, class OutputIterator> +inline OutputIterator +__copy(RandomAccessIterator first, RandomAccessIterator last, + OutputIterator result, random_access_iterator_tag) +{ + return __copy_d(first, last, result, distance_type(first)); +} + +template <class InputIterator, class OutputIterator> +struct __copy_dispatch +{ + OutputIterator operator()(InputIterator first, InputIterator last, + OutputIterator result) { + return __copy(first, last, result, iterator_category(first)); + } +}; + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + +template <class T> +inline T* __copy_t(const T* first, const T* last, T* result, __true_type) { + memmove(result, first, sizeof(T) * (last - first)); + return result + (last - first); +} + +template <class T> +inline T* __copy_t(const T* first, const T* last, T* result, __false_type) { + return __copy_d(first, last, result, (ptrdiff_t*) 0); +} + +template <class T> +struct __copy_dispatch<T*, T*> +{ + T* operator()(T* first, T* last, T* result) { + typedef typename __type_traits<T>::has_trivial_assignment_operator t; + return __copy_t(first, last, result, t()); + } +}; + +template <class T> +struct __copy_dispatch<const T*, T*> +{ + T* operator()(const T* first, const T* last, T* result) { + typedef typename __type_traits<T>::has_trivial_assignment_operator t; + return __copy_t(first, last, result, t()); + } +}; + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template <class InputIterator, class OutputIterator> +inline OutputIterator copy(InputIterator first, InputIterator last, + OutputIterator result) +{ + return __copy_dispatch<InputIterator,OutputIterator>()(first, last, result); +} + +inline char* copy(const char* first, const char* last, char* result) { + memmove(result, first, last - first); + return result + (last - first); +} + +inline wchar_t* copy(const wchar_t* first, const wchar_t* last, + wchar_t* result) { + memmove(result, first, sizeof(wchar_t) * (last - first)); + return result + (last - first); +} + +template <class BidirectionalIterator1, class BidirectionalIterator2> +inline BidirectionalIterator2 __copy_backward(BidirectionalIterator1 first, + BidirectionalIterator1 last, + BidirectionalIterator2 result) { + while (first != last) *--result = *--last; + return result; +} + + +template <class BidirectionalIterator1, class BidirectionalIterator2> +struct __copy_backward_dispatch +{ + BidirectionalIterator2 operator()(BidirectionalIterator1 first, + BidirectionalIterator1 last, + BidirectionalIterator2 result) { + return __copy_backward(first, last, result); + } +}; + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + +template <class T> +inline T* __copy_backward_t(const T* first, const T* last, T* result, + __true_type) { + const ptrdiff_t N = last - first; + memmove(result - N, first, sizeof(T) * N); + return result - N; +} + +template <class T> +inline T* __copy_backward_t(const T* first, const T* last, T* result, + __false_type) { + return __copy_backward(first, last, result); +} + +template <class T> +struct __copy_backward_dispatch<T*, T*> +{ + T* operator()(T* first, T* last, T* result) { + typedef typename __type_traits<T>::has_trivial_assignment_operator t; + return __copy_backward_t(first, last, result, t()); + } +}; + +template <class T> +struct __copy_backward_dispatch<const T*, T*> +{ + T* operator()(const T* first, const T* last, T* result) { + typedef typename __type_traits<T>::has_trivial_assignment_operator t; + return __copy_backward_t(first, last, result, t()); + } +}; + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template <class BidirectionalIterator1, class BidirectionalIterator2> +inline BidirectionalIterator2 copy_backward(BidirectionalIterator1 first, + BidirectionalIterator1 last, + BidirectionalIterator2 result) { + return __copy_backward_dispatch<BidirectionalIterator1, + BidirectionalIterator2>()(first, last, + result); +} + +template <class InputIterator, class Size, class OutputIterator> +pair<InputIterator, OutputIterator> __copy_n(InputIterator first, Size count, + OutputIterator result, + input_iterator_tag) { + for ( ; count > 0; --count, ++first, ++result) + *result = *first; + return pair<InputIterator, OutputIterator>(first, result); +} + +template <class RandomAccessIterator, class Size, class OutputIterator> +inline pair<RandomAccessIterator, OutputIterator> +__copy_n(RandomAccessIterator first, Size count, + OutputIterator result, + random_access_iterator_tag) { + RandomAccessIterator last = first + count; + return pair<RandomAccessIterator, OutputIterator>(last, + copy(first, last, result)); +} + +template <class InputIterator, class Size, class OutputIterator> +inline pair<InputIterator, OutputIterator> +copy_n(InputIterator first, Size count, + OutputIterator result) { + return __copy_n(first, count, result, iterator_category(first)); +} + +template <class ForwardIterator, class T> +void fill(ForwardIterator first, ForwardIterator last, const T& value) { + for ( ; first != last; ++first) + *first = value; +} + +template <class OutputIterator, class Size, class T> +OutputIterator fill_n(OutputIterator first, Size n, const T& value) { + for ( ; n > 0; --n, ++first) + *first = value; + return first; +} + +template <class InputIterator1, class InputIterator2> +pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1, + InputIterator1 last1, + InputIterator2 first2) { + while (first1 != last1 && *first1 == *first2) { + ++first1; + ++first2; + } + return pair<InputIterator1, InputIterator2>(first1, first2); +} + +template <class InputIterator1, class InputIterator2, class BinaryPredicate> +pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1, + InputIterator1 last1, + InputIterator2 first2, + BinaryPredicate binary_pred) { + while (first1 != last1 && binary_pred(*first1, *first2)) { + ++first1; + ++first2; + } + return pair<InputIterator1, InputIterator2>(first1, first2); +} + +template <class InputIterator1, class InputIterator2> +inline bool equal(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2) { + for ( ; first1 != last1; ++first1, ++first2) + if (*first1 != *first2) + return false; + return true; +} + +template <class InputIterator1, class InputIterator2, class BinaryPredicate> +inline bool equal(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, BinaryPredicate binary_pred) { + for ( ; first1 != last1; ++first1, ++first2) + if (!binary_pred(*first1, *first2)) + return false; + return true; +} + +template <class InputIterator1, class InputIterator2> +bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2) { + for ( ; first1 != last1 && first2 != last2; ++first1, ++first2) { + if (*first1 < *first2) + return true; + if (*first2 < *first1) + return false; + } + return first1 == last1 && first2 != last2; +} + +template <class InputIterator1, class InputIterator2, class Compare> +bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + Compare comp) { + for ( ; first1 != last1 && first2 != last2; ++first1, ++first2) { + if (comp(*first1, *first2)) + return true; + if (comp(*first2, *first1)) + return false; + } + return first1 == last1 && first2 != last2; +} + +inline bool +lexicographical_compare(const unsigned char* first1, + const unsigned char* last1, + const unsigned char* first2, + const unsigned char* last2) +{ + const size_t len1 = last1 - first1; + const size_t len2 = last2 - first2; + const int result = memcmp(first1, first2, min(len1, len2)); + return result != 0 ? result < 0 : len1 < len2; +} + +inline bool lexicographical_compare(const char* first1, const char* last1, + const char* first2, const char* last2) +{ +#if CHAR_MAX == SCHAR_MAX + return lexicographical_compare((const signed char*) first1, + (const signed char*) last1, + (const signed char*) first2, + (const signed char*) last2); +#else + return lexicographical_compare((const unsigned char*) first1, + (const unsigned char*) last1, + (const unsigned char*) first2, + (const unsigned char*) last2); +#endif +} + +template <class InputIterator1, class InputIterator2> +int lexicographical_compare_3way(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2) +{ + while (first1 != last1 && first2 != last2) { + if (*first1 < *first2) return -1; + if (*first2 < *first1) return 1; + ++first1; ++first2; + } + if (first2 == last2) { + return !(first1 == last1); + } else { + return -1; + } +} + +inline int +lexicographical_compare_3way(const unsigned char* first1, + const unsigned char* last1, + const unsigned char* first2, + const unsigned char* last2) +{ + const 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 +} + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_ALGOBASE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/stl_alloc.h b/contrib/libstdc++/stl/stl_alloc.h new file mode 100644 index 0000000..2c3de40 --- /dev/null +++ b/contrib/libstdc++/stl/stl_alloc.h @@ -0,0 +1,698 @@ +/* + * 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 <new> +# define __THROW_BAD_ALLOC throw bad_alloc +#elif !defined(__THROW_BAD_ALLOC) +# include <iostream.h> +# define __THROW_BAD_ALLOC cerr << "out of memory" << endl; exit(1) +#endif + +#ifndef __ALLOC +# define __ALLOC alloc +#endif +#ifdef __STL_WIN32THREADS +# include <windows.h> +#endif + +#include <stddef.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#ifndef __RESTRICT +# define __RESTRICT +#endif + +#if !defined(__STL_PTHREADS) && !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 <pthread.h> +# define __NODE_ALLOCATOR_LOCK \ + if (threads) pthread_mutex_lock(&__node_allocator_lock) +# define __NODE_ALLOCATOR_UNLOCK \ + if (threads) pthread_mutex_unlock(&__node_allocator_lock) +# define __NODE_ALLOCATOR_THREADS true +# define __VOLATILE volatile // Needed at -O3 on SGI +# endif +# ifdef __STL_WIN32THREADS + // The lock needs to be initialized by constructing an allocator + // objects of the right type. We do that here explicitly for alloc. +# define __NODE_ALLOCATOR_LOCK \ + EnterCriticalSection(&__node_allocator_lock) +# define __NODE_ALLOCATOR_UNLOCK \ + LeaveCriticalSection(&__node_allocator_lock) +# define __NODE_ALLOCATOR_THREADS true +# define __VOLATILE volatile // may not be needed +# endif /* WIN32THREADS */ +# ifdef __STL_SGI_THREADS + // This should work without threads, with sproc threads, or with + // pthreads. It is suboptimal in all cases. + // It is unlikely to even compile on nonSGI machines. + + extern "C" { + extern int __us_rsthread_malloc; + } + // The above is copied from malloc.h. Including <malloc.h> + // would be cleaner but fails with certain levels of standard + // conformance. +# define __NODE_ALLOCATOR_LOCK if (threads && __us_rsthread_malloc) \ + { __lock(&__node_allocator_lock); } +# define __NODE_ALLOCATOR_UNLOCK if (threads && __us_rsthread_malloc) \ + { __unlock(&__node_allocator_lock); } +# define __NODE_ALLOCATOR_THREADS true +# define __VOLATILE volatile // Needed at -O3 on SGI +# endif +# ifdef _NOTHREADS +// Thread-unsafe +# define __NODE_ALLOCATOR_LOCK +# define __NODE_ALLOCATOR_UNLOCK +# define __NODE_ALLOCATOR_THREADS false +# define __VOLATILE +# endif + +__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 <int inst> +class __malloc_alloc_template { + +private: + +static void *oom_malloc(size_t); + +static void *oom_realloc(void *, size_t); + +#ifndef __STL_STATIC_TEMPLATE_MEMBER_BUG + static void (* __malloc_alloc_oom_handler)(); +#endif + +public: + +static void * allocate(size_t n) +{ + void *result = malloc(n); + if (0 == result) result = oom_malloc(n); + return result; +} + +static void deallocate(void *p, size_t /* n */) +{ + free(p); +} + +static void * reallocate(void *p, size_t /* old_sz */, size_t new_sz) +{ + void * result = realloc(p, new_sz); + if (0 == result) result = oom_realloc(p, new_sz); + return result; +} + +static void (* set_malloc_handler(void (*f)()))() +{ + void (* old)() = __malloc_alloc_oom_handler; + __malloc_alloc_oom_handler = f; + return(old); +} + +}; + +// malloc_alloc out-of-memory handling + +#ifndef __STL_STATIC_TEMPLATE_MEMBER_BUG +template <int inst> +void (* __malloc_alloc_template<inst>::__malloc_alloc_oom_handler)() = 0; +#endif + +template <int inst> +void * __malloc_alloc_template<inst>::oom_malloc(size_t n) +{ + void (* my_malloc_handler)(); + void *result; + + for (;;) { + my_malloc_handler = __malloc_alloc_oom_handler; + if (0 == my_malloc_handler) { __THROW_BAD_ALLOC; } + (*my_malloc_handler)(); + result = malloc(n); + if (result) return(result); + } +} + +template <int inst> +void * __malloc_alloc_template<inst>::oom_realloc(void *p, size_t n) +{ + void (* my_malloc_handler)(); + void *result; + + for (;;) { + my_malloc_handler = __malloc_alloc_oom_handler; + if (0 == my_malloc_handler) { __THROW_BAD_ALLOC; } + (*my_malloc_handler)(); + result = realloc(p, n); + if (result) return(result); + } +} + +typedef __malloc_alloc_template<0> malloc_alloc; + +template<class T, class Alloc> +class simple_alloc { + +public: + static T *allocate(size_t n) + { return 0 == n? 0 : (T*) Alloc::allocate(n * sizeof (T)); } + static T *allocate(void) + { return (T*) Alloc::allocate(sizeof (T)); } + static void deallocate(T *p, size_t n) + { if (0 != n) Alloc::deallocate(p, n * sizeof (T)); } + static void deallocate(T *p) + { Alloc::deallocate(p, sizeof (T)); } +}; + +// Allocator adaptor to check size arguments for debugging. +// Reports errors using assert. Checking can be disabled with +// NDEBUG, but it's far better to just use the underlying allocator +// instead when no checking is desired. +// There is some evidence that this can confuse Purify. +template <class Alloc> +class debug_alloc { + +private: + +enum {extra = 8}; // Size of space used to store size. Note + // that this must be large enough to preserve + // alignment. + +public: + +static void * allocate(size_t n) +{ + char *result = (char *)Alloc::allocate(n + extra); + *(size_t *)result = n; + return result + extra; +} + +static void deallocate(void *p, size_t n) +{ + char * real_p = (char *)p - extra; + assert(*(size_t *)real_p == n); + Alloc::deallocate(real_p, n + extra); +} + +static void * reallocate(void *p, size_t old_sz, size_t new_sz) +{ + char * real_p = (char *)p - extra; + assert(*(size_t *)real_p == old_sz); + char * result = (char *) + Alloc::reallocate(real_p, old_sz + extra, new_sz + extra); + *(size_t *)result = new_sz; + return result + extra; +} + + +}; + + +# ifdef __USE_MALLOC + +typedef malloc_alloc alloc; +typedef malloc_alloc single_client_alloc; + +# else + + +// Default node allocator. +// With a reasonable compiler, this should be roughly as fast as the +// original STL class-specific allocators, but with less fragmentation. +// Default_alloc_template parameters are experimental and MAY +// DISAPPEAR in the future. Clients should just use alloc for now. +// +// Important implementation properties: +// 1. If the client request an object of size > __MAX_BYTES, the resulting +// object will be obtained directly from malloc. +// 2. In all other cases, we allocate an object of size exactly +// ROUND_UP(requested_size). Thus the client has enough size +// information that we can return the object to the proper free list +// without permanently losing part of the object. +// + +// The first template parameter specifies whether more than one thread +// may use this allocator. It is safe to allocate an object from +// one instance of a default_alloc and deallocate it with another +// one. This effectively transfers its ownership to the second one. +// This may have undesirable effects on reference locality. +// The second parameter is unreferenced and serves only to allow the +// creation of multiple default_alloc instances. +// Node that containers built on different allocator instances have +// different types, limiting the utility of this approach. +#ifdef __SUNPRO_CC +// breaks if we make these template class members: + enum {__ALIGN = 8}; + enum {__MAX_BYTES = 128}; + enum {__NFREELISTS = __MAX_BYTES/__ALIGN}; +#endif + +template <bool threads, int inst> +class __default_alloc_template { + +private: + // Really we should use static const int x = N + // instead of enum { x = N }, but few compilers accept the former. +# ifndef __SUNPRO_CC + enum {__ALIGN = 8}; + enum {__MAX_BYTES = 128}; + enum {__NFREELISTS = __MAX_BYTES/__ALIGN}; +# endif + static size_t ROUND_UP(size_t bytes) { + return (((bytes) + __ALIGN-1) & ~(__ALIGN - 1)); + } +__PRIVATE: + union obj { + union obj * free_list_link; + char client_data[1]; /* The client sees this. */ + }; +private: +# ifdef __SUNPRO_CC + static obj * __VOLATILE free_list[]; + // Specifying a size results in duplicate def for 4.1 +# else + static obj * __VOLATILE free_list[__NFREELISTS]; +# endif + static size_t FREELIST_INDEX(size_t bytes) { + return (((bytes) + __ALIGN-1)/__ALIGN - 1); + } + + // Returns an object of size n, and optionally adds to size n free list. + static void *refill(size_t n); + // Allocates a chunk for nobjs of size "size". nobjs may be reduced + // if it is inconvenient to allocate the requested number. + static char *chunk_alloc(size_t size, int &nobjs); + + // Chunk allocation state. + static char *start_free; + static char *end_free; + static size_t heap_size; + +# ifdef __STL_SGI_THREADS + static volatile unsigned long __node_allocator_lock; + static void __lock(volatile unsigned long *); + static inline void __unlock(volatile unsigned long *); +# endif + +# ifdef __STL_PTHREADS + static pthread_mutex_t __node_allocator_lock; +# endif + +# ifdef __STL_WIN32THREADS + static CRITICAL_SECTION __node_allocator_lock; + static bool __node_allocator_lock_initialized; + + public: + __default_alloc_template() { + // This assumes the first constructor is called before threads + // are started. + if (!__node_allocator_lock_initialized) { + InitializeCriticalSection(&__node_allocator_lock); + __node_allocator_lock_initialized = true; + } + } + private: +# endif + + class lock { + public: + lock() { __NODE_ALLOCATOR_LOCK; } + ~lock() { __NODE_ALLOCATOR_UNLOCK; } + }; + friend class lock; + +public: + + /* n must be > 0 */ + static void * allocate(size_t n) + { + obj * __VOLATILE * my_free_list; + obj * __RESTRICT result; + + if (n > (size_t) __MAX_BYTES) { + return(malloc_alloc::allocate(n)); + } + my_free_list = free_list + FREELIST_INDEX(n); + // Acquire the lock here with a constructor call. + // This ensures that it is released in exit or during stack + // unwinding. +# ifndef _NOTHREADS + /*REFERENCED*/ + lock lock_instance; +# endif + result = *my_free_list; + if (result == 0) { + void *r = refill(ROUND_UP(n)); + return r; + } + *my_free_list = result -> free_list_link; + return (result); + }; + + /* p may not be 0 */ + static void deallocate(void *p, size_t n) + { + obj *q = (obj *)p; + obj * __VOLATILE * my_free_list; + + if (n > (size_t) __MAX_BYTES) { + malloc_alloc::deallocate(p, n); + return; + } + my_free_list = free_list + FREELIST_INDEX(n); + // acquire lock +# ifndef _NOTHREADS + /*REFERENCED*/ + lock lock_instance; +# endif /* _NOTHREADS */ + q -> free_list_link = *my_free_list; + *my_free_list = q; + // lock is released here + } + + static void * reallocate(void *p, size_t old_sz, size_t new_sz); + +} ; + +typedef __default_alloc_template<__NODE_ALLOCATOR_THREADS, 0> alloc; +typedef __default_alloc_template<false, 0> single_client_alloc; + + + +/* We allocate memory in large chunks in order to avoid fragmenting */ +/* the malloc heap too much. */ +/* We assume that size is properly aligned. */ +/* We hold the allocation lock. */ +template <bool threads, int inst> +char* +__default_alloc_template<threads, inst>::chunk_alloc(size_t size, int& nobjs) +{ + char * result; + size_t total_bytes = size * nobjs; + size_t bytes_left = end_free - start_free; + + if (bytes_left >= total_bytes) { + result = start_free; + start_free += total_bytes; + return(result); + } else if (bytes_left >= size) { + nobjs = bytes_left/size; + total_bytes = size * nobjs; + result = start_free; + start_free += total_bytes; + return(result); + } else { + size_t bytes_to_get = 2 * total_bytes + ROUND_UP(heap_size >> 4); + // Try to make use of the left-over piece. + if (bytes_left > 0) { + obj * __VOLATILE * my_free_list = + free_list + FREELIST_INDEX(bytes_left); + + ((obj *)start_free) -> free_list_link = *my_free_list; + *my_free_list = (obj *)start_free; + } + start_free = (char *)malloc(bytes_to_get); + if (0 == start_free) { + int i; + obj * __VOLATILE * my_free_list, *p; + // Try to make do with what we have. That can't + // hurt. We do not try smaller requests, since that tends + // to result in disaster on multi-process machines. + for (i = size; i <= __MAX_BYTES; i += __ALIGN) { + my_free_list = free_list + FREELIST_INDEX(i); + p = *my_free_list; + if (0 != p) { + *my_free_list = p -> free_list_link; + start_free = (char *)p; + end_free = start_free + i; + return(chunk_alloc(size, nobjs)); + // Any leftover piece will eventually make it to the + // right free list. + } + } + end_free = 0; // In case of exception. + start_free = (char *)malloc_alloc::allocate(bytes_to_get); + // This should either throw an + // exception or remedy the situation. Thus we assume it + // succeeded. + } + heap_size += bytes_to_get; + end_free = start_free + bytes_to_get; + return(chunk_alloc(size, nobjs)); + } +} + + +/* Returns an object of size n, and optionally adds to size n free list.*/ +/* We assume that n is properly aligned. */ +/* We hold the allocation lock. */ +template <bool threads, int inst> +void* __default_alloc_template<threads, inst>::refill(size_t n) +{ + int nobjs = 20; + char * chunk = chunk_alloc(n, nobjs); + obj * __VOLATILE * my_free_list; + obj * result; + obj * current_obj, * next_obj; + int i; + + if (1 == nobjs) return(chunk); + my_free_list = free_list + FREELIST_INDEX(n); + + /* Build free list in chunk */ + result = (obj *)chunk; + *my_free_list = next_obj = (obj *)(chunk + n); + for (i = 1; ; i++) { + current_obj = next_obj; + next_obj = (obj *)((char *)next_obj + n); + if (nobjs - 1 == i) { + current_obj -> free_list_link = 0; + break; + } else { + current_obj -> free_list_link = next_obj; + } + } + return(result); +} + +template <bool threads, int inst> +void* +__default_alloc_template<threads, inst>::reallocate(void *p, + size_t old_sz, + size_t new_sz) +{ + void * result; + size_t copy_sz; + + if (old_sz > (size_t) __MAX_BYTES && new_sz > (size_t) __MAX_BYTES) { + return(realloc(p, new_sz)); + } + if (ROUND_UP(old_sz) == ROUND_UP(new_sz)) return(p); + result = allocate(new_sz); + copy_sz = new_sz > old_sz? old_sz : new_sz; + memcpy(result, p, copy_sz); + deallocate(p, old_sz); + return(result); +} + +#ifdef __STL_PTHREADS + template <bool threads, int inst> + pthread_mutex_t + __default_alloc_template<threads, inst>::__node_allocator_lock + = PTHREAD_MUTEX_INITIALIZER; +#endif + +#ifdef __STL_WIN32THREADS + template <bool threads, int inst> CRITICAL_SECTION + __default_alloc_template<threads, inst>::__node_allocator_lock; + + template <bool threads, int inst> bool + __default_alloc_template<threads, inst>::__node_allocator_lock_initialized + = false; +#endif + +#ifdef __STL_SGI_THREADS +__STL_END_NAMESPACE +#include <mutex.h> +#include <time.h> +__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 <bool threads, int inst> +volatile unsigned long +__default_alloc_template<threads, inst>::__node_allocator_lock = 0; + +#if __mips < 3 || !(defined (_ABIN32) || defined(_ABI64)) || defined(__GNUC__) +# define __test_and_set(l,v) test_and_set(l,v) +#endif + +template <bool threads, int inst> +void +__default_alloc_template<threads, inst>::__lock(volatile unsigned long *lock) +{ + const unsigned low_spin_max = 30; // spin cycles if we suspect uniprocessor + const unsigned high_spin_max = 1000; // spin cycles for multiprocessor + static unsigned spin_max = low_spin_max; + unsigned my_spin_max; + static unsigned last_spins = 0; + unsigned my_last_spins; + static struct timespec ts = {0, 1000}; + unsigned junk; +# define __ALLOC_PAUSE junk *= junk; junk *= junk; junk *= junk; junk *= junk + int i; + + if (!__test_and_set((unsigned long *)lock, 1)) { + return; + } + my_spin_max = spin_max; + my_last_spins = last_spins; + for (i = 0; i < my_spin_max; i++) { + if (i < my_last_spins/2 || *lock) { + __ALLOC_PAUSE; + continue; + } + if (!__test_and_set((unsigned long *)lock, 1)) { + // got it! + // Spinning worked. Thus we're probably not being scheduled + // against the other process with which we were contending. + // Thus it makes sense to spin longer the next time. + last_spins = i; + spin_max = high_spin_max; + return; + } + } + // We are probably being scheduled against the other process. Sleep. + spin_max = low_spin_max; + for (;;) { + if (!__test_and_set((unsigned long *)lock, 1)) { + return; + } + nanosleep(&ts, 0); + } +} + +template <bool threads, int inst> +inline void +__default_alloc_template<threads, inst>::__unlock(volatile unsigned long *lock) +{ +# if defined(__GNUC__) && __mips >= 3 + asm("sync"); + *lock = 0; +# elif __mips >= 3 && (defined (_ABIN32) || defined(_ABI64)) + __lock_release(lock); +# else + *lock = 0; + // This is not sufficient on many multiprocessors, since + // writes to protected variables and the lock may be reordered. +# endif +} +#endif + +template <bool threads, int inst> +char *__default_alloc_template<threads, inst>::start_free = 0; + +template <bool threads, int inst> +char *__default_alloc_template<threads, inst>::end_free = 0; + +template <bool threads, int inst> +size_t __default_alloc_template<threads, inst>::heap_size = 0; + +template <bool threads, int inst> +__default_alloc_template<threads, inst>::obj * __VOLATILE +__default_alloc_template<threads, inst> ::free_list[ +# ifdef __SUNPRO_CC + __NFREELISTS +# else + __default_alloc_template<threads, inst>::__NFREELISTS +# endif +] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; +// The 16 zeros are necessary to make version 4.1 of the SunPro +// compiler happy. Otherwise it appears to allocate too little +// space for the array. + +# ifdef __STL_WIN32THREADS + // Create one to get critical section initialized. + // We do this onece per file, but only the first constructor + // does anything. + static alloc __node_allocator_dummy_instance; +# endif + +#endif /* ! __USE_MALLOC */ + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#endif + +__STL_END_NAMESPACE + +#undef __PRIVATE + +#endif /* __SGI_STL_INTERNAL_ALLOC_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/stl_bvector.h b/contrib/libstdc++/stl/stl_bvector.h new file mode 100644 index 0000000..00fe500 --- /dev/null +++ b/contrib/libstdc++/stl/stl_bvector.h @@ -0,0 +1,616 @@ +/* + * + * 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 +#endif + +struct __bit_reference { + unsigned int* p; + unsigned int mask; + __bit_reference(unsigned int* x, unsigned int y) : p(x), mask(y) {} + +public: + __bit_reference() : p(0), mask(0) {} + operator bool() const { return !(!(*p & mask)); } + __bit_reference& operator=(bool x) { + if (x) + *p |= mask; + else + *p &= ~mask; + 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() { *p ^= mask; } +}; + +inline void swap(__bit_reference x, __bit_reference y) { + bool tmp = x; + x = y; + y = tmp; +} + +struct __bit_iterator : public random_access_iterator<bool, ptrdiff_t> { + typedef __bit_reference reference; + typedef __bit_reference* pointer; + typedef __bit_iterator iterator; + + unsigned int* p; + unsigned int offset; + void bump_up() { + if (offset++ == __WORD_BIT - 1) { + offset = 0; + ++p; + } + } + void bump_down() { + if (offset-- == 0) { + offset = __WORD_BIT - 1; + --p; + } + } + + __bit_iterator() : p(0), offset(0) {} + __bit_iterator(unsigned int* x, unsigned int y) : p(x), offset(y) {} + reference operator*() const { return reference(p, 1U << offset); } + iterator& operator++() { + bump_up(); + return *this; + } + iterator operator++(int) { + iterator tmp = *this; + bump_up(); + return tmp; + } + iterator& operator--() { + bump_down(); + return *this; + } + iterator operator--(int) { + iterator tmp = *this; + bump_down(); + return tmp; + } + iterator& operator+=(difference_type i) { + difference_type n = i + offset; + p += n / __WORD_BIT; + n = n % __WORD_BIT; + if (n < 0) { + offset = (unsigned int) n + __WORD_BIT; + --p; + } else + 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 * (p - x.p) + offset - x.offset; + } + reference operator[](difference_type i) { return *(*this + i); } + bool operator==(const iterator& x) const { + return p == x.p && offset == x.offset; + } + bool operator!=(const iterator& x) const { + return p != x.p || offset != x.offset; + } + bool operator<(iterator x) const { + return p < x.p || (p == x.p && offset < x.offset); + } +}; + +struct __bit_const_iterator + : public random_access_iterator<bool, ptrdiff_t> +{ + typedef bool reference; + typedef bool const_reference; + typedef const bool* pointer; + typedef __bit_const_iterator const_iterator; + + unsigned int* p; + unsigned int offset; + void bump_up() { + if (offset++ == __WORD_BIT - 1) { + offset = 0; + ++p; + } + } + void bump_down() { + if (offset-- == 0) { + offset = __WORD_BIT - 1; + --p; + } + } + + __bit_const_iterator() : p(0), offset(0) {} + __bit_const_iterator(unsigned int* x, unsigned int y) : p(x), offset(y) {} + __bit_const_iterator(const __bit_iterator& x) : p(x.p), offset(x.offset) {} + const_reference operator*() const { + return __bit_reference(p, 1U << offset); + } + const_iterator& operator++() { + bump_up(); + return *this; + } + const_iterator operator++(int) { + const_iterator tmp = *this; + bump_up(); + return tmp; + } + const_iterator& operator--() { + bump_down(); + return *this; + } + const_iterator operator--(int) { + const_iterator tmp = *this; + bump_down(); + return tmp; + } + const_iterator& operator+=(difference_type i) { + difference_type n = i + offset; + p += n / __WORD_BIT; + n = n % __WORD_BIT; + if (n < 0) { + offset = (unsigned int) n + __WORD_BIT; + --p; + } else + 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 * (p - x.p) + offset - x.offset; + } + const_reference operator[](difference_type i) { + return *(*this + i); + } + bool operator==(const const_iterator& x) const { + return p == x.p && offset == x.offset; + } + bool operator!=(const const_iterator& x) const { + return p != x.p || offset != x.offset; + } + bool operator<(const_iterator x) const { + return p < x.p || (p == x.p && offset < x.offset); + } +}; + +// The next few lines are confusing. What we're doing is declaring a +// partial specialization of vector<T, Alloc> if we have the necessary +// compiler support. Otherwise, we define a class bit_vector which uses +// the default allocator. In either case, we typedef "data_allocator" +// appropriately. + +#if defined(__STL_CLASS_PARTIAL_SPECIALIZATION) && !defined(__STL_NEED_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_vector.h> + __STL_BEGIN_NAMESPACE +template<class Alloc> class vector<bool, Alloc> +# else /* __SGI_STL_VECBOOL_TEMPLATE */ +class bit_vector +# endif /* __SGI_STL_VECBOOL_TEMPLATE */ +{ +# ifdef __SGI_STL_VECBOOL_TEMPLATE + typedef simple_alloc<unsigned int, Alloc> data_allocator; +# else /* __SGI_STL_VECBOOL_TEMPLATE */ + typedef simple_alloc<unsigned int, alloc> data_allocator; +# 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_iterator> const_reverse_iterator; + typedef reverse_iterator<iterator> reverse_iterator; +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + typedef reverse_iterator<const_iterator, value_type, const_reference, + difference_type> const_reverse_iterator; + typedef reverse_iterator<iterator, value_type, reference, difference_type> + reverse_iterator; +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +protected: + iterator start; + iterator finish; + unsigned int* end_of_storage; + unsigned int* bit_alloc(size_type n) { + return data_allocator::allocate((n + __WORD_BIT - 1)/__WORD_BIT); + } + void deallocate() { + if (start.p) + data_allocator::deallocate(start.p, end_of_storage - start.p); + } + void initialize(size_type n) { + unsigned int* q = bit_alloc(n); + end_of_storage = q + (n + __WORD_BIT - 1)/__WORD_BIT; + start = iterator(q, 0); + finish = start + difference_type(n); + } + void insert_aux(iterator position, bool x) { + if (finish.p != end_of_storage) { + copy_backward(position, finish, finish + 1); + *position = x; + ++finish; + } + else { + size_type len = size() ? 2 * size() : __WORD_BIT; + unsigned int* q = bit_alloc(len); + iterator i = copy(begin(), position, iterator(q, 0)); + *i++ = x; + finish = copy(position, end(), i); + deallocate(); + end_of_storage = q + (len + __WORD_BIT - 1)/__WORD_BIT; + start = iterator(q, 0); + } + } + +#ifdef __STL_MEMBER_TEMPLATES + template <class InputIterator> + void initialize_range(InputIterator first, InputIterator last, + input_iterator_tag) { + start = iterator(); + finish = iterator(); + end_of_storage = 0; + for ( ; first != last; ++first) + push_back(*first); + } + + template <class ForwardIterator> + void initialize_range(ForwardIterator first, ForwardIterator last, + forward_iterator_tag) { + size_type n = 0; + distance(first, last, n); + initialize(n); + copy(first, last, start); + } + + template <class InputIterator> + void insert_range(iterator pos, + InputIterator first, InputIterator last, + input_iterator_tag) { + for ( ; first != last; ++first) { + pos = insert(pos, *first); + ++pos; + } + } + + template <class ForwardIterator> + void insert_range(iterator position, + ForwardIterator first, ForwardIterator last, + forward_iterator_tag) { + if (first != last) { + size_type n = 0; + distance(first, last, n); + if (capacity() - size() >= n) { + copy_backward(position, end(), finish + difference_type(n)); + copy(first, last, position); + finish += difference_type(n); + } + else { + size_type len = size() + max(size(), n); + unsigned int* q = bit_alloc(len); + iterator i = copy(begin(), position, iterator(q, 0)); + i = copy(first, last, i); + finish = copy(position, end(), i); + deallocate(); + end_of_storage = q + (len + __WORD_BIT - 1)/__WORD_BIT; + start = iterator(q, 0); + } + } + } + +#endif /* __STL_MEMBER_TEMPLATES */ + +public: + iterator begin() { return start; } + const_iterator begin() const { return start; } + iterator end() { return finish; } + const_iterator end() const { return finish; } + + reverse_iterator rbegin() { return reverse_iterator(end()); } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } + reverse_iterator rend() { return reverse_iterator(begin()); } + const_reverse_iterator rend() const { + return const_reverse_iterator(begin()); + } + + size_type size() const { return size_type(end() - begin()); } + size_type max_size() const { return size_type(-1); } + size_type capacity() const { + return size_type(const_iterator(end_of_storage, 0) - begin()); + } + bool empty() const { return begin() == end(); } + reference operator[](size_type n) { + return *(begin() + difference_type(n)); + } + const_reference operator[](size_type n) const { + return *(begin() + difference_type(n)); + } + __BVECTOR() : start(iterator()), finish(iterator()), end_of_storage(0) {} + __BVECTOR(size_type n, bool value) { + initialize(n); + fill(start.p, end_of_storage, value ? ~0 : 0); + } + __BVECTOR(int n, bool value) { + initialize(n); + fill(start.p, end_of_storage, value ? ~0 : 0); + } + __BVECTOR(long n, bool value) { + initialize(n); + fill(start.p, end_of_storage, value ? ~0 : 0); + } + explicit __BVECTOR(size_type n) { + initialize(n); + fill(start.p, end_of_storage, 0); + } + __BVECTOR(const __BVECTOR& x) { + initialize(x.size()); + copy(x.begin(), x.end(), start); + } + +#ifdef __STL_MEMBER_TEMPLATES + template <class InputIterator> + __BVECTOR(InputIterator first, InputIterator last) { + initialize_range(first, last, iterator_category(first)); + } +#else /* __STL_MEMBER_TEMPLATES */ + __BVECTOR(const_iterator first, const_iterator last) { + size_type n = 0; + distance(first, last, n); + initialize(n); + copy(first, last, start); + } + __BVECTOR(const bool* first, const bool* last) { + size_type n = 0; + distance(first, last, n); + initialize(n); + copy(first, last, start); + } +#endif /* __STL_MEMBER_TEMPLATES */ + + ~__BVECTOR() { deallocate(); } + __BVECTOR& operator=(const __BVECTOR& x) { + if (&x == this) return *this; + if (x.size() > capacity()) { + deallocate(); + initialize(x.size()); + } + copy(x.begin(), x.end(), begin()); + finish = begin() + difference_type(x.size()); + return *this; + } + void reserve(size_type n) { + if (capacity() < n) { + unsigned int* q = bit_alloc(n); + finish = copy(begin(), end(), iterator(q, 0)); + deallocate(); + start = iterator(q, 0); + end_of_storage = q + (n + __WORD_BIT - 1)/__WORD_BIT; + } + } + reference front() { return *begin(); } + const_reference front() const { return *begin(); } + reference back() { return *(end() - 1); } + const_reference back() const { return *(end() - 1); } + void push_back(bool x) { + if (finish.p != end_of_storage) + *finish++ = x; + else + insert_aux(end(), x); + } + void swap(__BVECTOR& x) { + __STD::swap(start, x.start); + __STD::swap(finish, x.finish); + __STD::swap(end_of_storage, x.end_of_storage); + } + iterator insert(iterator position, bool x = bool()) { + difference_type n = position - begin(); + if (finish.p != end_of_storage && position == end()) + *finish++ = x; + else + insert_aux(position, x); + return begin() + n; + } + +#ifdef __STL_MEMBER_TEMPLATES + template <class InputIterator> void insert(iterator position, + InputIterator first, + InputIterator last) { + insert_range(position, first, last, iterator_category(first)); + } +#else /* __STL_MEMBER_TEMPLATES */ + void insert(iterator position, const_iterator first, + const_iterator last) { + if (first == last) return; + size_type n = 0; + distance(first, last, n); + if (capacity() - size() >= n) { + copy_backward(position, end(), finish + n); + copy(first, last, position); + finish += n; + } + else { + size_type len = size() + max(size(), n); + unsigned int* q = bit_alloc(len); + iterator i = copy(begin(), position, iterator(q, 0)); + i = copy(first, last, i); + finish = copy(position, end(), i); + deallocate(); + end_of_storage = q + (len + __WORD_BIT - 1)/__WORD_BIT; + start = iterator(q, 0); + } + } + + void insert(iterator position, const bool* first, const bool* last) { + if (first == last) return; + size_type n = 0; + distance(first, last, n); + if (capacity() - size() >= n) { + copy_backward(position, end(), finish + n); + copy(first, last, position); + finish += n; + } + else { + size_type len = size() + max(size(), n); + unsigned int* q = bit_alloc(len); + iterator i = copy(begin(), position, iterator(q, 0)); + i = copy(first, last, i); + finish = copy(position, end(), i); + deallocate(); + end_of_storage = q + (len + __WORD_BIT - 1)/__WORD_BIT; + start = iterator(q, 0); + } + } +#endif /* __STL_MEMBER_TEMPLATES */ + + void insert(iterator position, size_type n, bool x) { + if (n == 0) return; + if (capacity() - size() >= n) { + copy_backward(position, end(), finish + difference_type(n)); + fill(position, position + difference_type(n), x); + finish += difference_type(n); + } + else { + size_type len = size() + max(size(), n); + unsigned int* q = bit_alloc(len); + iterator i = copy(begin(), position, iterator(q, 0)); + fill_n(i, n, x); + finish = copy(position, end(), i + difference_type(n)); + deallocate(); + end_of_storage = q + (len + __WORD_BIT - 1)/__WORD_BIT; + start = iterator(q, 0); + } + } + + void insert(iterator pos, int n, bool x) { insert(pos, (size_type)n, x); } + void insert(iterator pos, long n, bool x) { insert(pos, (size_type)n, x); } + + void pop_back() { --finish; } + iterator erase(iterator position) { + if (position + 1 != end()) + copy(position + 1, end(), position); + --finish; + return position; + } + iterator erase(iterator first, iterator last) { + 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<bool, alloc> 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 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_BVECTOR_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/stl_config.h b/contrib/libstdc++/stl/stl_config.h new file mode 100644 index 0000000..02a1f88 --- /dev/null +++ b/contrib/libstdc++/stl/stl_config.h @@ -0,0 +1,250 @@ +/* + * + * 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 + +// What this file does. +// (1) Defines bool, true, and false if the compiler doesn't do so already. +// (2) Defines __STL_NO_DRAND48 if the compiler's standard library does +// not support the drand48() function. +// (3) Defines __STL_STATIC_TEMPLATE_MEMBER_BUG if the compiler can't +// handle static members of template classes. +// (4) Defines 'typename' as a null macro if the compiler does not support +// the typename keyword. +// (5) Defines __STL_CLASS_PARTIAL_SPECIALIZATION if the compiler +// supports partial specialization of class templates. +// (6) Defines __STL_FUNCTION_TMPL_PARTIAL_ORDER if the compiler supports +// partial ordering of function templates (a.k.a partial specialization +// of function templates. +// (7) Defines __STL_EXPLICIT_FUNCTION_TMPL_ARGS if the compiler +// supports calling a function template by providing its template +// arguments explicitly. +// (8) Defines __STL_MEMBER_TEMPLATES if the compiler supports +// template members of classes. +// (9) Defines 'explicit' as a null macro if the compiler does not support +// the explicit keyword. +// (10) Defines __STL_LIMITED_DEFAULT_TEMPLATES if the compiler is +// unable to handle default template parameters that depend on +// previous template parameters. +// (11) Defines __STL_NON_TYPE_TMPL_PARAM_BUG if the compiler has +// trouble performing function template argument deduction for +// non-type template parameters. +// (12) Defines __SGI_STL_NO_ARROW_OPERATOR if the compiler is unable +// to support the -> operator for iterators. +// (13) Defines __STL_USE_EXCEPTIONS if the compiler (in the current +// compilation mode) supports exceptions. +// (14) Define __STL_USE_NAMESPACES if we're putting the STL into a +// namespace. +// (15) Defines __STL_SGI_THREADS if this is being compiled on an SGI +// compiler, and if the user hasn't selected pthreads or no threads +// instead. +// (16) Defines __STL_WIN32THREADS if this is being compiled on a +// WIN32 compiler in multithreaded mode. +// (17) Define namespace-related macros (__STD, __STL_BEGIN_NAMESPACE, etc.) +// apropriately. +// (18) Define exception-related macros (__STL_TRY, __STL_UNWIND, etc.) +// appropriately. +// (19) Defines __stl_assert either as a test or as a null macro, +// depending on whether or not __STL_ASSERTIONS is defined. + +#ifdef _PTHREADS +# define __STL_PTHREADS +#endif + +# if defined(__sgi) && !defined(__GNUC__) +# if !defined(_BOOL) +# define __STL_NEED_BOOL +# 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 +# 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_USE_NAMESPACES +# endif +# if !defined(_NOTHREADS) && !defined(__STL_PTHREADS) +# define __STL_SGI_THREADS +# endif +# endif + +# ifdef __GNUC__ +# include <_G_config.h> +# 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_EXPLICIT_FUNCTION_TMPL_ARGS +# define __STL_MEMBER_TEMPLATES +# endif + /* glibc pre 2.0 is very buggy. We have to disable thread for it. + It should be upgraded to glibc 2.0 or later. */ +# if !defined(_NOTHREADS) && __GLIBC__ >= 2 && defined(_G_USING_THUNKS) +# define __STL_PTHREADS +# endif +# ifdef __EXCEPTIONS +# define __STL_USE_EXCEPTIONS +# endif +# endif + +# if defined(__SUNPRO_CC) +# define __STL_NEED_BOOL +# define __STL_NEED_TYPENAME +# define __STL_NEED_EXPLICIT +# define __STL_USE_EXCEPTIONS +# endif + +# if defined(__COMO__) +# define __STL_MEMBER_TEMPLATES +# define __STL_CLASS_PARTIAL_SPECIALIZATION +# define __STL_USE_EXCEPTIONS +# define __STL_USE_NAMESPACES +# endif + +# if defined(_MSC_VER) +# if _MSC_VER > 1000 +# include <yvals.h> +# else +# define __STL_NEED_BOOL +# endif +# define __STL_NO_DRAND48 +# define __STL_NEED_TYPENAME +# if _MSC_VER < 1100 +# define __STL_NEED_EXPLICIT +# 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 +# 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_NEED_BOOL) + typedef int bool; +# define true 1 +# define false 0 +# endif + +# ifdef __STL_NEED_TYPENAME +# define typename +# 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 + +# ifdef __STL_CLASS_PARTIAL_SPECIALIZATION +# define __STL_TEMPLATE_NULL template<> +# else +# define __STL_TEMPLATE_NULL +# endif + +// __STL_NO_NAMESPACES is a hook so that users can disable namespaces +// without having to edit library headers. +# if defined(__STL_USE_NAMESPACES) && !defined(__STL_NO_NAMESPACES) +# define __STD std +# define __STL_BEGIN_NAMESPACE namespace std { +# define __STL_END_NAMESPACE } +# define __STL_USE_NAMESPACE_FOR_RELOPS +# define __STL_BEGIN_RELOPS_NAMESPACE namespace std { +# define __STL_END_RELOPS_NAMESPACE } +# define __STD_RELOPS std +# else +# define __STD +# define __STL_BEGIN_NAMESPACE +# define __STL_END_NAMESPACE +# undef __STL_USE_NAMESPACE_FOR_RELOPS +# define __STL_BEGIN_RELOPS_NAMESPACE +# define __STL_END_RELOPS_NAMESPACE +# define __STD_RELOPS +# endif + +# ifdef __STL_USE_EXCEPTIONS +# define __STL_TRY try +# define __STL_CATCH_ALL catch(...) +# define __STL_RETHROW throw +# define __STL_NOTHROW throw() +# define __STL_UNWIND(action) catch(...) { action; throw; } +# else +# define __STL_TRY +# define __STL_CATCH_ALL if (false) +# define __STL_RETHROW +# define __STL_NOTHROW +# define __STL_UNWIND(action) +# endif + +#ifdef __STL_ASSERTIONS +# include <stdio.h> +# 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/contrib/libstdc++/stl/stl_construct.h b/contrib/libstdc++/stl/stl_construct.h new file mode 100644 index 0000000..4687635 --- /dev/null +++ b/contrib/libstdc++/stl/stl_construct.h @@ -0,0 +1,78 @@ +/* + * + * 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 <new.h> + +__STL_BEGIN_NAMESPACE + +template <class T> +inline void destroy(T* pointer) { + pointer->~T(); +} + +template <class T1, class T2> +inline void construct(T1* p, const T2& value) { + new (p) T1(value); +} + +template <class ForwardIterator> +inline void +__destroy_aux(ForwardIterator first, ForwardIterator last, __false_type) { + for ( ; first < last; ++first) + destroy(&*first); +} + +template <class ForwardIterator> +inline void __destroy_aux(ForwardIterator, ForwardIterator, __true_type) {} + +template <class ForwardIterator, class T> +inline void __destroy(ForwardIterator first, ForwardIterator last, T*) { + typedef typename __type_traits<T>::has_trivial_destructor trivial_destructor; + __destroy_aux(first, last, trivial_destructor()); +} + +template <class ForwardIterator> +inline void destroy(ForwardIterator first, ForwardIterator last) { + __destroy(first, last, value_type(first)); +} + +inline void destroy(char*, char*) {} +inline void destroy(wchar_t*, wchar_t*) {} + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_CONSTRUCT_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/stl_deque.h b/contrib/libstdc++/stl/stl_deque.h new file mode 100644 index 0000000..72325d5 --- /dev/null +++ b/contrib/libstdc++/stl/stl_deque.h @@ -0,0 +1,1335 @@ +/* + * + * 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 +#endif + +// Note: this function is simply a kludge to work around several compilers' +// bugs in handling constant expressions. +inline size_t __deque_buf_size(size_t n, size_t sz) +{ + return n != 0 ? n : (sz < 512 ? size_t(512 / sz) : size_t(1)); +} + +#ifndef __STL_NON_TYPE_TMPL_PARAM_BUG +template <class T, class Ref, class Ptr, size_t BufSiz> +struct __deque_iterator { + typedef __deque_iterator<T, T&, T*, BufSiz> iterator; + typedef __deque_iterator<T, const T&, const T*, BufSiz> const_iterator; + static size_t buffer_size() {return __deque_buf_size(BufSiz, sizeof(T)); } +#else /* __STL_NON_TYPE_TMPL_PARAM_BUG */ +template <class T, class Ref, class Ptr> +struct __deque_iterator { + typedef __deque_iterator<T, T&, T*> iterator; + typedef __deque_iterator<T, const T&, const T*> const_iterator; + static size_t buffer_size() {return __deque_buf_size(0, sizeof(T)); } +#endif + + typedef random_access_iterator_tag iterator_category; + typedef T value_type; + typedef Ptr pointer; + typedef Ref reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef T** map_pointer; + + typedef __deque_iterator self; + + T* cur; + T* first; + T* last; + map_pointer node; + + __deque_iterator(T* x, map_pointer y) + : cur(x), first(*y), last(*y + buffer_size()), node(y) {} + __deque_iterator() : cur(0), first(0), last(0), node(0) {} + __deque_iterator(const iterator& x) + : cur(x.cur), first(x.first), last(x.last), node(x.node) {} + + reference operator*() const { return *cur; } +#ifndef __SGI_STL_NO_ARROW_OPERATOR + pointer operator->() const { return &(operator*()); } +#endif /* __SGI_STL_NO_ARROW_OPERATOR */ + + difference_type operator-(const self& x) const { + return difference_type(buffer_size()) * (node - x.node - 1) + + (cur - first) + (x.last - x.cur); + } + + self& operator++() { + ++cur; + if (cur == last) { + set_node(node + 1); + cur = first; + } + return *this; + } + self operator++(int) { + self tmp = *this; + ++*this; + return tmp; + } + + self& operator--() { + if (cur == first) { + set_node(node - 1); + cur = last; + } + --cur; + return *this; + } + self operator--(int) { + self tmp = *this; + --*this; + return tmp; + } + + self& operator+=(difference_type n) { + difference_type offset = n + (cur - first); + if (offset >= 0 && offset < difference_type(buffer_size())) + cur += n; + else { + difference_type node_offset = + offset > 0 ? offset / difference_type(buffer_size()) + : -difference_type((-offset - 1) / buffer_size()) - 1; + set_node(node + node_offset); + cur = first + (offset - node_offset * difference_type(buffer_size())); + } + 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 cur == x.cur; } + bool operator!=(const self& x) const { return !(*this == x); } + bool operator<(const self& x) const { + return (node == x.node) ? (cur < x.cur) : (node < x.node); + } + + void set_node(map_pointer new_node) { + node = new_node; + first = *new_node; + last = first + difference_type(buffer_size()); + } +}; + +#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION + +#ifndef __STL_NON_TYPE_TMPL_PARAM_BUG + +template <class T, class Ref, class Ptr, size_t BufSiz> +inline random_access_iterator_tag +iterator_category(const __deque_iterator<T, Ref, Ptr, BufSiz>&) { + return random_access_iterator_tag(); +} + +template <class T, class Ref, class Ptr, size_t BufSiz> +inline T* value_type(const __deque_iterator<T, Ref, Ptr, BufSiz>&) { + return 0; +} + +template <class T, class Ref, class Ptr, size_t BufSiz> +inline ptrdiff_t* distance_type(const __deque_iterator<T, Ref, Ptr, BufSiz>&) { + return 0; +} + +#else /* __STL_NON_TYPE_TMPL_PARAM_BUG */ + +template <class T, class Ref, class Ptr> +inline random_access_iterator_tag +iterator_category(const __deque_iterator<T, Ref, Ptr>&) { + return random_access_iterator_tag(); +} + +template <class T, class Ref, class Ptr> +inline T* value_type(const __deque_iterator<T, Ref, Ptr>&) { return 0; } + +template <class T, class Ref, class Ptr> +inline ptrdiff_t* distance_type(const __deque_iterator<T, Ref, Ptr>&) { + return 0; +} + +#endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */ + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +// 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 T, class Alloc = alloc, size_t BufSiz = 0> +class deque { +public: // Basic types + typedef T 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; + +public: // Iterators +#ifndef __STL_NON_TYPE_TMPL_PARAM_BUG + typedef __deque_iterator<T, T&, T*, BufSiz> iterator; + typedef __deque_iterator<T, const T&, const T&, BufSiz> const_iterator; +#else /* __STL_NON_TYPE_TMPL_PARAM_BUG */ + typedef __deque_iterator<T, T&, T*> iterator; + typedef __deque_iterator<T, const T&, const T*> const_iterator; +#endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */ + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + typedef reverse_iterator<const_iterator> const_reverse_iterator; + typedef reverse_iterator<iterator> reverse_iterator; +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + typedef reverse_iterator<const_iterator, value_type, const_reference, + difference_type> + const_reverse_iterator; + typedef reverse_iterator<iterator, value_type, reference, difference_type> + reverse_iterator; +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +protected: // Internal typedefs + typedef pointer* map_pointer; + typedef simple_alloc<value_type, Alloc> data_allocator; + typedef simple_alloc<pointer, Alloc> map_allocator; + + static size_type buffer_size() { + return __deque_buf_size(BufSiz, sizeof(value_type)); + } + static size_type initial_map_size() { return 8; } + +protected: // Data members + iterator start; + iterator finish; + + map_pointer map; + size_type map_size; + +public: // Basic accessors + iterator begin() { return start; } + iterator end() { return finish; } + const_iterator begin() const { return start; } + const_iterator end() const { return finish; } + + reverse_iterator rbegin() { return reverse_iterator(finish); } + reverse_iterator rend() { return reverse_iterator(start); } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(finish); + } + const_reverse_iterator rend() const { + return const_reverse_iterator(start); + } + + reference operator[](size_type n) { return start[difference_type(n)]; } + const_reference operator[](size_type n) const { + return start[difference_type(n)]; + } + + reference front() { return *start; } + reference back() { + iterator tmp = finish; + --tmp; + return *tmp; + } + const_reference front() const { return *start; } + const_reference back() const { + const_iterator tmp = finish; + --tmp; + return *tmp; + } + + size_type size() const { return finish - start;; } + size_type max_size() const { return size_type(-1); } + bool empty() const { return finish == start; } + +public: // Constructor, destructor. + deque() + : start(), finish(), map(0), map_size(0) + { + create_map_and_nodes(0); + } + + deque(const deque& x) + : start(), finish(), map(0), map_size(0) + { + create_map_and_nodes(x.size()); + __STL_TRY { + uninitialized_copy(x.begin(), x.end(), start); + } + __STL_UNWIND(destroy_map_and_nodes()); + } + + deque(size_type n, const value_type& value) + : start(), finish(), map(0), map_size(0) + { + fill_initialize(n, value); + } + + deque(int n, const value_type& value) + : start(), finish(), map(0), map_size(0) + { + fill_initialize(n, value); + } + + deque(long n, const value_type& value) + : start(), finish(), map(0), map_size(0) + { + fill_initialize(n, value); + } + + explicit deque(size_type n) + : start(), finish(), map(0), map_size(0) + { + fill_initialize(n, value_type()); + } + +#ifdef __STL_MEMBER_TEMPLATES + + template <class InputIterator> + deque(InputIterator first, InputIterator last) + : start(), finish(), map(0), map_size(0) + { + range_initialize(first, last, iterator_category(first)); + } + +#else /* __STL_MEMBER_TEMPLATES */ + + deque(const value_type* first, const value_type* last) + : start(), finish(), map(0), map_size(0) + { + create_map_and_nodes(last - first); + __STL_TRY { + uninitialized_copy(first, last, start); + } + __STL_UNWIND(destroy_map_and_nodes()); + } + + deque(const_iterator first, const_iterator last) + : start(), finish(), map(0), map_size(0) + { + create_map_and_nodes(last - first); + __STL_TRY { + uninitialized_copy(first, last, start); + } + __STL_UNWIND(destroy_map_and_nodes()); + } + +#endif /* __STL_MEMBER_TEMPLATES */ + + ~deque() { + destroy(start, finish); + destroy_map_and_nodes(); + } + + deque& operator= (const deque& x) { + const size_type len = size(); + if (&x != this) { + if (len >= x.size()) + erase(copy(x.begin(), x.end(), start), finish); + else { + const_iterator mid = x.begin() + difference_type(len); + copy(x.begin(), mid, start); + insert(finish, mid, x.end()); + } + } + return *this; + } + + void swap(deque& x) { + __STD::swap(start, x.start); + __STD::swap(finish, x.finish); + __STD::swap(map, x.map); + __STD::swap(map_size, x.map_size); + } + +public: // push_* and pop_* + + void push_back(const value_type& t) { + if (finish.cur != finish.last - 1) { + construct(finish.cur, t); + ++finish.cur; + } + else + push_back_aux(t); + } + + void push_front(const value_type& t) { + if (start.cur != start.first) { + construct(start.cur - 1, t); + --start.cur; + } + else + push_front_aux(t); + } + + void pop_back() { + if (finish.cur != finish.first) { + --finish.cur; + destroy(finish.cur); + } + else + pop_back_aux(); + } + + void pop_front() { + if (start.cur != start.last - 1) { + destroy(start.cur); + ++start.cur; + } + else + pop_front_aux(); + } + +public: // Insert + + iterator insert(iterator position, const value_type& x) { + if (position.cur == start.cur) { + push_front(x); + return start; + } + else if (position.cur == finish.cur) { + push_back(x); + iterator tmp = finish; + --tmp; + return tmp; + } + else { + return insert_aux(position, x); + } + } + + iterator insert(iterator position) { return insert(position, value_type()); } + + void insert(iterator pos, size_type n, const value_type& x); + + void insert(iterator pos, int n, const value_type& x) { + insert(pos, (size_type) n, x); + } + void insert(iterator pos, long n, const value_type& x) { + insert(pos, (size_type) n, x); + } + +#ifdef __STL_MEMBER_TEMPLATES + + template <class InputIterator> + void insert(iterator pos, InputIterator first, InputIterator last) { + 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(start + new_size, finish); + else + insert(finish, new_size - len, x); + } + + void resize(size_type new_size) { resize(new_size, value_type()); } + +public: // Erase + iterator erase(iterator pos) { + iterator next = pos; + ++next; + difference_type index = pos - start; + if (index < (size() >> 1)) { + copy_backward(start, pos, next); + pop_front(); + } + else { + copy(next, finish, pos); + pop_back(); + } + return start + index; + } + + iterator erase(iterator first, iterator last); + void clear(); + +protected: // Internal construction/destruction + + void create_map_and_nodes(size_type num_elements); + void destroy_map_and_nodes(); + void fill_initialize(size_type n, const value_type& value); + +#ifdef __STL_MEMBER_TEMPLATES + + template <class InputIterator> + void range_initialize(InputIterator first, InputIterator last, + input_iterator_tag); + + template <class ForwardIterator> + void range_initialize(ForwardIterator first, ForwardIterator last, + forward_iterator_tag); + +#endif /* __STL_MEMBER_TEMPLATES */ + +protected: // Internal push_* and pop_* + + void push_back_aux(const value_type& t); + void push_front_aux(const value_type& t); + void pop_back_aux(); + void pop_front_aux(); + +protected: // Internal insert functions + +#ifdef __STL_MEMBER_TEMPLATES + + template <class InputIterator> + void insert(iterator pos, InputIterator first, InputIterator last, + input_iterator_tag); + + template <class ForwardIterator> + void insert(iterator pos, ForwardIterator first, ForwardIterator last, + forward_iterator_tag); + +#endif /* __STL_MEMBER_TEMPLATES */ + + iterator insert_aux(iterator pos, const value_type& x); + void insert_aux(iterator pos, size_type n, const value_type& x); + +#ifdef __STL_MEMBER_TEMPLATES + + template <class ForwardIterator> + void insert_aux(iterator pos, ForwardIterator first, ForwardIterator last, + size_type n); + +#else /* __STL_MEMBER_TEMPLATES */ + + void insert_aux(iterator pos, + const value_type* first, const value_type* last, + size_type n); + + void insert_aux(iterator pos, const_iterator first, const_iterator last, + size_type n); + +#endif /* __STL_MEMBER_TEMPLATES */ + + iterator reserve_elements_at_front(size_type n) { + size_type vacancies = start.cur - start.first; + if (n > vacancies) + new_elements_at_front(n - vacancies); + return start - difference_type(n); + } + + iterator reserve_elements_at_back(size_type n) { + size_type vacancies = (finish.last - finish.cur) - 1; + if (n > vacancies) + new_elements_at_back(n - vacancies); + return finish + difference_type(n); + } + + void new_elements_at_front(size_type new_elements); + void new_elements_at_back(size_type new_elements); + + void destroy_nodes_at_front(iterator before_start); + void destroy_nodes_at_back(iterator after_finish); + +protected: // Allocation of map and nodes + + // Makes sure the map has space for new nodes. Does not actually + // add the nodes. Can invalidate map pointers. (And consequently, + // deque iterators.) + + void reserve_map_at_back (size_type nodes_to_add = 1) { + if (nodes_to_add + 1 > map_size - (finish.node - map)) + reallocate_map(nodes_to_add, false); + } + + void reserve_map_at_front (size_type nodes_to_add = 1) { + if (nodes_to_add > start.node - map) + reallocate_map(nodes_to_add, true); + } + + void reallocate_map(size_type nodes_to_add, bool add_at_front); + + pointer allocate_node() { return data_allocator::allocate(buffer_size()); } + void deallocate_node(pointer n) { + data_allocator::deallocate(n, buffer_size()); + } + +#ifdef __STL_NON_TYPE_TMPL_PARAM_BUG +public: + bool operator==(const deque<T, Alloc, 0>& x) const { + return size() == x.size() && equal(begin(), end(), x.begin()); + } + bool operator!=(const deque<T, Alloc, 0>& x) const { + return size() != x.size() || !equal(begin(), end(), x.begin()); + } + bool operator<(const deque<T, Alloc, 0>& x) const { + return lexicographical_compare(begin(), end(), x.begin(), x.end()); + } +#endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */ +}; + +// Non-inline member functions + +template <class T, class Alloc, size_t BufSize> +void deque<T, Alloc, BufSize>::insert(iterator pos, + size_type n, const value_type& x) { + if (pos.cur == start.cur) { + iterator new_start = reserve_elements_at_front(n); + uninitialized_fill(new_start, start, x); + start = new_start; + } + else if (pos.cur == finish.cur) { + iterator new_finish = reserve_elements_at_back(n); + uninitialized_fill(finish, new_finish, x); + finish = new_finish; + } + else + insert_aux(pos, n, x); +} + +#ifndef __STL_MEMBER_TEMPLATES + +template <class T, class Alloc, size_t BufSize> +void deque<T, Alloc, BufSize>::insert(iterator pos, + const value_type* first, + const value_type* last) { + size_type n = last - first; + if (pos.cur == start.cur) { + iterator new_start = reserve_elements_at_front(n); + __STL_TRY { + uninitialized_copy(first, last, new_start); + start = new_start; + } + __STL_UNWIND(destroy_nodes_at_front(new_start)); + } + else if (pos.cur == finish.cur) { + iterator new_finish = reserve_elements_at_back(n); + __STL_TRY { + uninitialized_copy(first, last, finish); + finish = new_finish; + } + __STL_UNWIND(destroy_nodes_at_back(new_finish)); + } + else + insert_aux(pos, first, last, n); +} + +template <class T, class Alloc, size_t BufSize> +void deque<T, Alloc, BufSize>::insert(iterator pos, + const_iterator first, + const_iterator last) +{ + size_type n = last - first; + if (pos.cur == start.cur) { + iterator new_start = reserve_elements_at_front(n); + __STL_TRY { + uninitialized_copy(first, last, new_start); + start = new_start; + } + __STL_UNWIND(destroy_nodes_at_front(new_start)); + } + else if (pos.cur == finish.cur) { + iterator new_finish = reserve_elements_at_back(n); + __STL_TRY { + uninitialized_copy(first, last, finish); + finish = new_finish; + } + __STL_UNWIND(destroy_nodes_at_back(new_finish)); + } + else + insert_aux(pos, first, last, n); +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +template <class T, class Alloc, size_t BufSize> +deque<T, Alloc, BufSize>::iterator +deque<T, Alloc, BufSize>::erase(iterator first, iterator last) { + if (first == start && last == finish) { + clear(); + return finish; + } + else { + difference_type n = last - first; + difference_type elems_before = first - start; + if (elems_before < (size() - n) / 2) { + copy_backward(start, first, last); + iterator new_start = start + n; + destroy(start, new_start); + for (map_pointer cur = start.node; cur < new_start.node; ++cur) + data_allocator::deallocate(*cur, buffer_size()); + start = new_start; + } + else { + copy(last, finish, first); + iterator new_finish = finish - n; + destroy(new_finish, finish); + for (map_pointer cur = new_finish.node + 1; cur <= finish.node; ++cur) + data_allocator::deallocate(*cur, buffer_size()); + finish = new_finish; + } + return start + elems_before; + } +} + +template <class T, class Alloc, size_t BufSize> +void deque<T, Alloc, BufSize>::clear() { + for (map_pointer node = start.node + 1; node < finish.node; ++node) { + destroy(*node, *node + buffer_size()); + data_allocator::deallocate(*node, buffer_size()); + } + + if (start.node != finish.node) { + destroy(start.cur, start.last); + destroy(finish.first, finish.cur); + data_allocator::deallocate(finish.first, buffer_size()); + } + else + destroy(start.cur, finish.cur); + + finish = start; +} + +template <class T, class Alloc, size_t BufSize> +void deque<T, Alloc, BufSize>::create_map_and_nodes(size_type num_elements) { + size_type num_nodes = num_elements / buffer_size() + 1; + + map_size = max(initial_map_size(), num_nodes + 2); + map = map_allocator::allocate(map_size); + + map_pointer nstart = map + (map_size - num_nodes) / 2; + map_pointer nfinish = nstart + num_nodes - 1; + + map_pointer cur; + __STL_TRY { + for (cur = nstart; cur <= nfinish; ++cur) + *cur = allocate_node(); + } +# ifdef __STL_USE_EXCEPTIONS + catch(...) { + for (map_pointer n = nstart; n < cur; ++n) + deallocate_node(*n); + map_allocator::deallocate(map, map_size); + throw; + } +# endif /* __STL_USE_EXCEPTIONS */ + + start.set_node(nstart); + finish.set_node(nfinish); + start.cur = start.first; + finish.cur = finish.first + num_elements % buffer_size(); +} + +// This is only used as a cleanup function in catch clauses. +template <class T, class Alloc, size_t BufSize> +void deque<T, Alloc, BufSize>::destroy_map_and_nodes() { + for (map_pointer cur = start.node; cur <= finish.node; ++cur) + deallocate_node(*cur); + map_allocator::deallocate(map, map_size); +} + + +template <class T, class Alloc, size_t BufSize> +void deque<T, Alloc, BufSize>::fill_initialize(size_type n, + const value_type& value) { + create_map_and_nodes(n); + map_pointer cur; + __STL_TRY { + for (cur = start.node; cur < finish.node; ++cur) + uninitialized_fill(*cur, *cur + buffer_size(), value); + uninitialized_fill(finish.first, finish.cur, value); + } +# ifdef __STL_USE_EXCEPTIONS + catch(...) { + for (map_pointer n = start.node; n < cur; ++n) + destroy(*n, *n + buffer_size()); + destroy_map_and_nodes(); + throw; + } +# endif /* __STL_USE_EXCEPTIONS */ +} + +#ifdef __STL_MEMBER_TEMPLATES + +template <class T, class Alloc, size_t BufSize> +template <class InputIterator> +void deque<T, Alloc, BufSize>::range_initialize(InputIterator first, + InputIterator last, + input_iterator_tag) { + create_map_and_nodes(0); + for ( ; first != last; ++first) + push_back(*first); +} + +template <class T, class Alloc, size_t BufSize> +template <class ForwardIterator> +void deque<T, Alloc, BufSize>::range_initialize(ForwardIterator first, + ForwardIterator last, + forward_iterator_tag) { + size_type n = 0; + distance(first, last, n); + create_map_and_nodes(n); + __STL_TRY { + uninitialized_copy(first, last, start); + } + __STL_UNWIND(destroy_map_and_nodes()); +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +// Called only if finish.cur == finish.last - 1. +template <class T, class Alloc, size_t BufSize> +void deque<T, Alloc, BufSize>::push_back_aux(const value_type& t) { + value_type t_copy = t; + reserve_map_at_back(); + *(finish.node + 1) = allocate_node(); + __STL_TRY { + construct(finish.cur, t_copy); + finish.set_node(finish.node + 1); + finish.cur = finish.first; + } + __STL_UNWIND(deallocate_node(*(finish.node + 1))); +} + +// Called only if start.cur == start.first. +template <class T, class Alloc, size_t BufSize> +void deque<T, Alloc, BufSize>::push_front_aux(const value_type& t) { + value_type t_copy = t; + reserve_map_at_front(); + *(start.node - 1) = allocate_node(); + __STL_TRY { + start.set_node(start.node - 1); + start.cur = start.last - 1; + construct(start.cur, t_copy); + } +# ifdef __STL_USE_EXCEPTIONS + catch(...) { + start.set_node(start.node + 1); + start.cur = start.first; + deallocate_node(*(start.node - 1)); + throw; + } +# endif /* __STL_USE_EXCEPTIONS */ +} + +// Called only if finish.cur == finish.first. +template <class T, class Alloc, size_t BufSize> +void deque<T, Alloc, BufSize>:: pop_back_aux() { + deallocate_node(finish.first); + finish.set_node(finish.node - 1); + finish.cur = finish.last - 1; + destroy(finish.cur); +} + +// Called only if start.cur == start.last - 1. Note that if the deque +// has at least one element (a necessary precondition for this member +// function), and if start.cur == start.last, then the deque must have +// at least two nodes. +template <class T, class Alloc, size_t BufSize> +void deque<T, Alloc, BufSize>::pop_front_aux() { + destroy(start.cur); + deallocate_node(start.first); + start.set_node(start.node + 1); + start.cur = start.first; +} + +#ifdef __STL_MEMBER_TEMPLATES + +template <class T, class Alloc, size_t BufSize> +template <class InputIterator> +void deque<T, Alloc, BufSize>::insert(iterator pos, + InputIterator first, InputIterator last, + input_iterator_tag) { + copy(first, last, inserter(*this, pos)); +} + +template <class T, class Alloc, size_t BufSize> +template <class ForwardIterator> +void deque<T, Alloc, BufSize>::insert(iterator pos, + ForwardIterator first, + ForwardIterator last, + forward_iterator_tag) { + size_type n = 0; + distance(first, last, n); + if (pos.cur == start.cur) { + iterator new_start = reserve_elements_at_front(n); + __STL_TRY { + uninitialized_copy(first, last, new_start); + start = new_start; + } + __STL_UNWIND(destroy_nodes_at_front(new_start)); + } + else if (pos.cur == finish.cur) { + iterator new_finish = reserve_elements_at_back(n); + __STL_TRY { + uninitialized_copy(first, last, finish); + finish = new_finish; + } + __STL_UNWIND(destroy_nodes_at_back(new_finish)); + } + else + insert_aux(pos, first, last, n); +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +template <class T, class Alloc, size_t BufSize> +typename deque<T, Alloc, BufSize>::iterator +deque<T, Alloc, BufSize>::insert_aux(iterator pos, const value_type& x) { + difference_type index = pos - start; + value_type x_copy = x; + if (index < size() / 2) { + push_front(front()); + iterator front1 = start; + ++front1; + iterator front2 = front1; + ++front2; + pos = start + index; + iterator pos1 = pos; + ++pos1; + copy(front2, pos1, front1); + } + else { + push_back(back()); + iterator back1 = finish; + --back1; + iterator back2 = back1; + --back2; + pos = start + index; + copy_backward(pos, back2, back1); + } + *pos = x_copy; + return pos; +} + +template <class T, class Alloc, size_t BufSize> +void deque<T, Alloc, BufSize>::insert_aux(iterator pos, + size_type n, const value_type& x) { + const difference_type elems_before = pos - start; + size_type length = size(); + value_type x_copy = x; + if (elems_before < length / 2) { + iterator new_start = reserve_elements_at_front(n); + iterator old_start = start; + pos = start + elems_before; + __STL_TRY { + if (elems_before >= difference_type(n)) { + iterator start_n = start + difference_type(n); + uninitialized_copy(start, start_n, new_start); + start = new_start; + copy(start_n, pos, old_start); + fill(pos - difference_type(n), pos, x_copy); + } + else { + __uninitialized_copy_fill(start, pos, new_start, start, x_copy); + start = new_start; + fill(old_start, pos, x_copy); + } + } + __STL_UNWIND(destroy_nodes_at_front(new_start)); + } + else { + iterator new_finish = reserve_elements_at_back(n); + iterator old_finish = finish; + const difference_type elems_after = difference_type(length) - elems_before; + pos = finish - elems_after; + __STL_TRY { + if (elems_after > difference_type(n)) { + iterator finish_n = finish - difference_type(n); + uninitialized_copy(finish_n, finish, finish); + finish = new_finish; + copy_backward(pos, finish_n, old_finish); + fill(pos, pos + difference_type(n), x_copy); + } + else { + __uninitialized_fill_copy(finish, pos + difference_type(n), + x_copy, + pos, finish); + finish = new_finish; + fill(pos, old_finish, x_copy); + } + } + __STL_UNWIND(destroy_nodes_at_back(new_finish)); + } +} + +#ifdef __STL_MEMBER_TEMPLATES + +template <class T, class Alloc, size_t BufSize> +template <class ForwardIterator> +void deque<T, Alloc, BufSize>::insert_aux(iterator pos, + ForwardIterator first, + ForwardIterator last, + size_type n) +{ + const difference_type elems_before = pos - start; + size_type length = size(); + if (elems_before < length / 2) { + iterator new_start = reserve_elements_at_front(n); + iterator old_start = start; + pos = start + elems_before; + __STL_TRY { + if (elems_before >= difference_type(n)) { + iterator start_n = start + difference_type(n); + uninitialized_copy(start, start_n, new_start); + start = new_start; + copy(start_n, pos, old_start); + copy(first, last, pos - difference_type(n)); + } + else { + ForwardIterator mid = first; + advance(mid, difference_type(n) - elems_before); + __uninitialized_copy_copy(start, pos, first, mid, new_start); + start = new_start; + copy(mid, last, old_start); + } + } + __STL_UNWIND(destroy_nodes_at_front(new_start)); + } + else { + iterator new_finish = reserve_elements_at_back(n); + iterator old_finish = finish; + const difference_type elems_after = difference_type(length) - elems_before; + pos = finish - elems_after; + __STL_TRY { + if (elems_after > difference_type(n)) { + iterator finish_n = finish - difference_type(n); + uninitialized_copy(finish_n, finish, finish); + finish = new_finish; + copy_backward(pos, finish_n, old_finish); + copy(first, last, pos); + } + else { + ForwardIterator mid = first; + advance(mid, elems_after); + __uninitialized_copy_copy(mid, last, pos, finish, finish); + finish = new_finish; + copy(first, mid, pos); + } + } + __STL_UNWIND(destroy_nodes_at_back(new_finish)); + } +} + +#else /* __STL_MEMBER_TEMPLATES */ + +template <class T, class Alloc, size_t BufSize> +void deque<T, Alloc, BufSize>::insert_aux(iterator pos, + const value_type* first, + const value_type* last, + size_type n) +{ + const difference_type elems_before = pos - start; + size_type length = size(); + if (elems_before < length / 2) { + iterator new_start = reserve_elements_at_front(n); + iterator old_start = start; + pos = start + elems_before; + __STL_TRY { + if (elems_before >= difference_type(n)) { + iterator start_n = start + difference_type(n); + uninitialized_copy(start, start_n, new_start); + start = new_start; + copy(start_n, pos, old_start); + copy(first, last, pos - difference_type(n)); + } + else { + const value_type* mid = first + (difference_type(n) - elems_before); + __uninitialized_copy_copy(start, pos, first, mid, new_start); + start = new_start; + copy(mid, last, old_start); + } + } + __STL_UNWIND(destroy_nodes_at_front(new_start)); + } + else { + iterator new_finish = reserve_elements_at_back(n); + iterator old_finish = finish; + const difference_type elems_after = difference_type(length) - elems_before; + pos = finish - elems_after; + __STL_TRY { + if (elems_after > difference_type(n)) { + iterator finish_n = finish - difference_type(n); + uninitialized_copy(finish_n, finish, finish); + finish = new_finish; + copy_backward(pos, finish_n, old_finish); + copy(first, last, pos); + } + else { + const value_type* mid = first + elems_after; + __uninitialized_copy_copy(mid, last, pos, finish, finish); + finish = new_finish; + copy(first, mid, pos); + } + } + __STL_UNWIND(destroy_nodes_at_back(new_finish)); + } +} + +template <class T, class Alloc, size_t BufSize> +void deque<T, Alloc, BufSize>::insert_aux(iterator pos, + const_iterator first, + const_iterator last, + size_type n) +{ + const difference_type elems_before = pos - start; + size_type length = size(); + if (elems_before < length / 2) { + iterator new_start = reserve_elements_at_front(n); + iterator old_start = start; + pos = start + elems_before; + __STL_TRY { + if (elems_before >= n) { + iterator start_n = start + n; + uninitialized_copy(start, start_n, new_start); + start = new_start; + copy(start_n, pos, old_start); + copy(first, last, pos - difference_type(n)); + } + else { + const_iterator mid = first + (n - elems_before); + __uninitialized_copy_copy(start, pos, first, mid, new_start); + start = new_start; + copy(mid, last, old_start); + } + } + __STL_UNWIND(destroy_nodes_at_front(new_start)); + } + else { + iterator new_finish = reserve_elements_at_back(n); + iterator old_finish = finish; + const difference_type elems_after = length - elems_before; + pos = finish - elems_after; + __STL_TRY { + if (elems_after > n) { + iterator finish_n = finish - difference_type(n); + uninitialized_copy(finish_n, finish, finish); + finish = new_finish; + copy_backward(pos, finish_n, old_finish); + copy(first, last, pos); + } + else { + const_iterator mid = first + elems_after; + __uninitialized_copy_copy(mid, last, pos, finish, finish); + finish = new_finish; + copy(first, mid, pos); + } + } + __STL_UNWIND(destroy_nodes_at_back(new_finish)); + } +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +template <class T, class Alloc, size_t BufSize> +void deque<T, Alloc, BufSize>::new_elements_at_front(size_type new_elements) { + size_type new_nodes = (new_elements + buffer_size() - 1) / buffer_size(); + reserve_map_at_front(new_nodes); + size_type i; + __STL_TRY { + for (i = 1; i <= new_nodes; ++i) + *(start.node - i) = allocate_node(); + } +# ifdef __STL_USE_EXCEPTIONS + catch(...) { + for (size_type j = 1; j < i; ++j) + deallocate_node(*(start.node - j)); + throw; + } +# endif /* __STL_USE_EXCEPTIONS */ +} + +template <class T, class Alloc, size_t BufSize> +void deque<T, Alloc, BufSize>::new_elements_at_back(size_type new_elements) { + size_type new_nodes = (new_elements + buffer_size() - 1) / buffer_size(); + reserve_map_at_back(new_nodes); + size_type i; + __STL_TRY { + for (i = 1; i <= new_nodes; ++i) + *(finish.node + i) = allocate_node(); + } +# ifdef __STL_USE_EXCEPTIONS + catch(...) { + for (size_type j = 1; j < i; ++j) + deallocate_node(*(finish.node + j)); + throw; + } +# endif /* __STL_USE_EXCEPTIONS */ +} + +template <class T, class Alloc, size_t BufSize> +void deque<T, Alloc, BufSize>::destroy_nodes_at_front(iterator before_start) { + for (map_pointer n = before_start.node; n < start.node; ++n) + deallocate_node(*n); +} + +template <class T, class Alloc, size_t BufSize> +void deque<T, Alloc, BufSize>::destroy_nodes_at_back(iterator after_finish) { + for (map_pointer n = after_finish.node; n > finish.node; --n) + deallocate_node(*n); +} + +template <class T, class Alloc, size_t BufSize> +void deque<T, Alloc, BufSize>::reallocate_map(size_type nodes_to_add, + bool add_at_front) { + size_type old_num_nodes = finish.node - start.node + 1; + size_type new_num_nodes = old_num_nodes + nodes_to_add; + + map_pointer new_nstart; + if (map_size > 2 * new_num_nodes) { + new_nstart = map + (map_size - new_num_nodes) / 2 + + (add_at_front ? nodes_to_add : 0); + if (new_nstart < start.node) + copy(start.node, finish.node + 1, new_nstart); + else + copy_backward(start.node, finish.node + 1, new_nstart + old_num_nodes); + } + else { + size_type new_map_size = map_size + max(map_size, nodes_to_add) + 2; + + map_pointer new_map = map_allocator::allocate(new_map_size); + new_nstart = new_map + (new_map_size - new_num_nodes) / 2 + + (add_at_front ? nodes_to_add : 0); + copy(start.node, finish.node + 1, new_nstart); + map_allocator::deallocate(map, map_size); + + map = new_map; + map_size = new_map_size; + } + + start.set_node(new_nstart); + finish.set_node(new_nstart + old_num_nodes - 1); +} + + +// Nonmember functions. + +#ifndef __STL_NON_TYPE_TMPL_PARAM_BUG + +template <class T, class Alloc, size_t BufSiz> +bool operator==(const deque<T, Alloc, BufSiz>& x, + const deque<T, Alloc, BufSiz>& y) { + return x.size() == y.size() && equal(x.begin(), x.end(), y.begin()); +} + +template <class T, class Alloc, size_t BufSiz> +bool operator<(const deque<T, Alloc, BufSiz>& x, + const deque<T, 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 <class T, class Alloc, size_t BufSiz> +inline void swap(deque<T, Alloc, BufSiz>& x, deque<T, Alloc, BufSiz>& y) { + x.swap(y); +} + +#endif + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_DEQUE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/stl_function.h b/contrib/libstdc++/stl/stl_function.h new file mode 100644 index 0000000..c0d785d --- /dev/null +++ b/contrib/libstdc++/stl/stl_function.h @@ -0,0 +1,628 @@ +/* + * + * 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_FUNCTION_H +#define __SGI_STL_INTERNAL_FUNCTION_H + +__STL_BEGIN_NAMESPACE + +template <class Arg, class Result> +struct unary_function { + typedef Arg argument_type; + typedef Result result_type; +}; + +template <class Arg1, class Arg2, class Result> +struct binary_function { + typedef Arg1 first_argument_type; + typedef Arg2 second_argument_type; + typedef Result result_type; +}; + +template <class T> +struct plus : public binary_function<T, T, T> { + T operator()(const T& x, const T& y) const { return x + y; } +}; + +template <class T> +struct minus : public binary_function<T, T, T> { + T operator()(const T& x, const T& y) const { return x - y; } +}; + +template <class T> +struct multiplies : public binary_function<T, T, T> { + T operator()(const T& x, const T& y) const { return x * y; } +}; + +template <class T> +struct divides : public binary_function<T, T, T> { + T operator()(const T& x, const T& y) const { return x / y; } +}; + +template <class T> inline T identity_element(plus<T>) { return T(0); } + +template <class T> inline T identity_element(multiplies<T>) { return T(1); } + +template <class T> +struct modulus : public binary_function<T, T, T> { + T operator()(const T& x, const T& y) const { return x % y; } +}; + +template <class T> +struct negate : public unary_function<T, T> { + T operator()(const T& x) const { return -x; } +}; + +template <class T> +struct equal_to : public binary_function<T, T, bool> { + bool operator()(const T& x, const T& y) const { return x == y; } +}; + +template <class T> +struct not_equal_to : public binary_function<T, T, bool> { + bool operator()(const T& x, const T& y) const { return x != y; } +}; + +template <class T> +struct greater : public binary_function<T, T, bool> { + bool operator()(const T& x, const T& y) const { return x > y; } +}; + +template <class T> +struct less : public binary_function<T, T, bool> { + bool operator()(const T& x, const T& y) const { return x < y; } +}; + +template <class T> +struct greater_equal : public binary_function<T, T, bool> { + bool operator()(const T& x, const T& y) const { return x >= y; } +}; + +template <class T> +struct less_equal : public binary_function<T, T, bool> { + bool operator()(const T& x, const T& y) const { return x <= y; } +}; + +template <class T> +struct logical_and : public binary_function<T, T, bool> { + bool operator()(const T& x, const T& y) const { return x && y; } +}; + +template <class T> +struct logical_or : public binary_function<T, T, bool> { + bool operator()(const T& x, const T& y) const { return x || y; } +}; + +template <class T> +struct logical_not : public unary_function<T, bool> { + bool operator()(const T& x) const { return !x; } +}; + +template <class Predicate> +class unary_negate + : public unary_function<typename Predicate::argument_type, bool> { +protected: + Predicate pred; +public: + explicit unary_negate(const Predicate& x) : pred(x) {} + bool operator()(const typename Predicate::argument_type& x) const { + return !pred(x); + } +}; + +template <class Predicate> +inline unary_negate<Predicate> not1(const Predicate& pred) { + return unary_negate<Predicate>(pred); +} + +template <class Predicate> +class binary_negate + : public binary_function<typename Predicate::first_argument_type, + typename Predicate::second_argument_type, + bool> { +protected: + Predicate pred; +public: + explicit binary_negate(const Predicate& x) : pred(x) {} + bool operator()(const typename Predicate::first_argument_type& x, + const typename Predicate::second_argument_type& y) const { + return !pred(x, y); + } +}; + +template <class Predicate> +inline binary_negate<Predicate> not2(const Predicate& pred) { + return binary_negate<Predicate>(pred); +} + +template <class Operation> +class binder1st + : public unary_function<typename Operation::second_argument_type, + typename Operation::result_type> { +protected: + Operation op; + typename Operation::first_argument_type value; +public: + binder1st(const Operation& x, + const typename Operation::first_argument_type& y) + : op(x), value(y) {} + typename Operation::result_type + operator()(const typename Operation::second_argument_type& x) const { + return op(value, x); + } +}; + +template <class Operation, class T> +inline binder1st<Operation> bind1st(const Operation& op, const T& x) { + typedef typename Operation::first_argument_type arg1_type; + return binder1st<Operation>(op, arg1_type(x)); +} + +template <class Operation> +class binder2nd + : public unary_function<typename Operation::first_argument_type, + typename Operation::result_type> { +protected: + Operation op; + typename Operation::second_argument_type value; +public: + binder2nd(const Operation& x, + const typename Operation::second_argument_type& y) + : op(x), value(y) {} + typename Operation::result_type + operator()(const typename Operation::first_argument_type& x) const { + return op(x, value); + } +}; + +template <class Operation, class T> +inline binder2nd<Operation> bind2nd(const Operation& op, const T& x) { + typedef typename Operation::second_argument_type arg2_type; + return binder2nd<Operation>(op, arg2_type(x)); +} + +template <class Operation1, class Operation2> +class unary_compose : public unary_function<typename Operation2::argument_type, + typename Operation1::result_type> { +protected: + Operation1 op1; + Operation2 op2; +public: + unary_compose(const Operation1& x, const Operation2& y) : op1(x), op2(y) {} + typename Operation1::result_type + operator()(const typename Operation2::argument_type& x) const { + return op1(op2(x)); + } +}; + +template <class Operation1, class Operation2> +inline unary_compose<Operation1, Operation2> compose1(const Operation1& op1, + const Operation2& op2) { + return unary_compose<Operation1, Operation2>(op1, op2); +} + +template <class Operation1, class Operation2, class Operation3> +class binary_compose + : public unary_function<typename Operation2::argument_type, + typename Operation1::result_type> { +protected: + Operation1 op1; + Operation2 op2; + Operation3 op3; +public: + binary_compose(const Operation1& x, const Operation2& y, + const Operation3& z) : op1(x), op2(y), op3(z) { } + typename Operation1::result_type + operator()(const typename Operation2::argument_type& x) const { + return op1(op2(x), op3(x)); + } +}; + +template <class Operation1, class Operation2, class Operation3> +inline binary_compose<Operation1, Operation2, Operation3> +compose2(const Operation1& op1, const Operation2& op2, const Operation3& op3) { + return binary_compose<Operation1, Operation2, Operation3>(op1, op2, op3); +} + +template <class Arg, class Result> +class pointer_to_unary_function : public unary_function<Arg, Result> { +protected: + Result (*ptr)(Arg); +public: + pointer_to_unary_function() {} + explicit pointer_to_unary_function(Result (*x)(Arg)) : ptr(x) {} + Result operator()(Arg x) const { return ptr(x); } +}; + +template <class Arg, class Result> +inline pointer_to_unary_function<Arg, Result> ptr_fun(Result (*x)(Arg)) { + return pointer_to_unary_function<Arg, Result>(x); +} + +template <class Arg1, class Arg2, class Result> +class pointer_to_binary_function : public binary_function<Arg1, Arg2, Result> { +protected: + Result (*ptr)(Arg1, Arg2); +public: + pointer_to_binary_function() {} + explicit pointer_to_binary_function(Result (*x)(Arg1, Arg2)) : ptr(x) {} + Result operator()(Arg1 x, Arg2 y) const { return ptr(x, y); } +}; + +template <class Arg1, class Arg2, class Result> +inline pointer_to_binary_function<Arg1, Arg2, Result> +ptr_fun(Result (*x)(Arg1, Arg2)) { + return pointer_to_binary_function<Arg1, Arg2, Result>(x); +} + +template <class T> +struct identity : public unary_function<T, T> { + const T& operator()(const T& x) const { return x; } +}; + +template <class Pair> +struct select1st : public unary_function<Pair, typename Pair::first_type> { + const typename Pair::first_type& operator()(const Pair& x) const + { + return x.first; + } +}; + +template <class Pair> +struct select2nd : public unary_function<Pair, typename Pair::second_type> { + const typename Pair::second_type& operator()(const Pair& x) const + { + return x.second; + } +}; + +template <class Arg1, class Arg2> +struct project1st : public binary_function<Arg1, Arg2, Arg1> { + Arg1 operator()(const Arg1& x, const Arg2&) const { return x; } +}; + +template <class Arg1, class Arg2> +struct project2nd : public binary_function<Arg1, Arg2, Arg2> { + Arg2 operator()(const Arg1&, const Arg2& y) const { return y; } +}; + +template <class Result> +struct constant_void_fun +{ + typedef Result result_type; + result_type val; + constant_void_fun(const result_type& v) : val(v) {} + const result_type& operator()() const { return val; } +}; + +#ifndef __STL_LIMITED_DEFAULT_TEMPLATES +template <class Result, class Argument = Result> +#else +template <class Result, class Argument> +#endif +struct constant_unary_fun : public unary_function<Argument, Result> { + Result val; + constant_unary_fun(const Result& v) : val(v) {} + const Result& operator()(const Argument&) const { return val; } +}; + +#ifndef __STL_LIMITED_DEFAULT_TEMPLATES +template <class Result, class Arg1 = Result, class Arg2 = Arg1> +#else +template <class Result, class Arg1, class Arg2> +#endif +struct constant_binary_fun : public binary_function<Arg1, Arg2, Result> { + Result val; + constant_binary_fun(const Result& v) : val(v) {} + const Result& operator()(const Arg1&, const Arg2&) const { + return val; + } +}; + +template <class Result> +inline constant_void_fun<Result> constant0(const Result& val) +{ + return constant_void_fun<Result>(val); +} + +template <class Result> +inline constant_unary_fun<Result,Result> constant1(const Result& val) +{ + return constant_unary_fun<Result,Result>(val); +} + +template <class Result> +inline constant_binary_fun<Result,Result,Result> constant2(const Result& val) +{ + return constant_binary_fun<Result,Result,Result>(val); +} + +// Note: this code assumes that int is 32 bits. +class subtractive_rng : public unary_function<unsigned int, unsigned int> { +private: + unsigned int table[55]; + size_t index1; + size_t index2; +public: + unsigned int operator()(unsigned int limit) { + index1 = (index1 + 1) % 55; + index2 = (index2 + 1) % 55; + table[index1] = table[index1] - table[index2]; + return table[index1] % limit; + } + + void initialize(unsigned int seed) + { + unsigned int k = 1; + table[54] = seed; + size_t i; + for (i = 0; i < 54; i++) { + size_t ii = (21 * (i + 1) % 55) - 1; + table[ii] = k; + k = seed - k; + seed = table[ii]; + } + for (int loop = 0; loop < 4; loop++) { + for (i = 0; i < 55; i++) + table[i] = table[i] - table[(1 + i + 30) % 55]; + } + index1 = 0; + index2 = 31; + } + + subtractive_rng(unsigned int seed) { initialize(seed); } + subtractive_rng() { initialize(161803398u); } +}; + + +// Adaptor function objects: pointers to member functions. + +// There are a total of 16 = 2^4 function objects in this family. +// (1) Member functions taking no arguments vs member functions taking +// one argument. +// (2) Call through pointer vs call through reference. +// (3) Member function with void return type vs member function with +// non-void return type. +// (4) Const vs non-const member function. + +// Note that choice (4) is not present in the 8/97 draft C++ standard, +// which only allows these adaptors to be used with non-const functions. +// This is likely to be recified before the standard becomes final. +// Note also that choice (3) is nothing more than a workaround: according +// to the draft, compilers should handle void and non-void the same way. +// This feature is not yet widely implemented, though. You can only use +// member functions returning void if your compiler supports partial +// specialization. + +// All of this complexity is in the function objects themselves. You can +// ignore it by using the helper function mem_fun, mem_fun_ref, +// mem_fun1, and mem_fun1_ref, which create whichever type of adaptor +// is appropriate. + + +template <class S, class T> +class mem_fun_t : public unary_function<T*, S> { +public: + explicit mem_fun_t(S (T::*pf)()) : f(pf) {} + S operator()(T* p) const { return (p->*f)(); } +private: + S (T::*f)(); +}; + +template <class S, class T> +class const_mem_fun_t : public unary_function<const T*, S> { +public: + explicit const_mem_fun_t(S (T::*pf)() const) : f(pf) {} + S operator()(const T* p) const { return (p->*f)(); } +private: + S (T::*f)() const; +}; + + +template <class S, class T> +class mem_fun_ref_t : public unary_function<T, S> { +public: + explicit mem_fun_ref_t(S (T::*pf)()) : f(pf) {} + S operator()(T& r) const { return (r.*f)(); } +private: + S (T::*f)(); +}; + +template <class S, class T> +class const_mem_fun_ref_t : public unary_function<T, S> { +public: + explicit const_mem_fun_ref_t(S (T::*pf)() const) : f(pf) {} + S operator()(const T& r) const { return (r.*f)(); } +private: + S (T::*f)() const; +}; + +template <class S, class T, class A> +class mem_fun1_t : public binary_function<T*, A, S> { +public: + explicit mem_fun1_t(S (T::*pf)(A)) : f(pf) {} + S operator()(T* p, A x) const { return (p->*f)(x); } +private: + S (T::*f)(A); +}; + +template <class S, class T, class A> +class const_mem_fun1_t : public binary_function<const T*, A, S> { +public: + explicit const_mem_fun1_t(S (T::*pf)(A) const) : f(pf) {} + S operator()(const T* p, A x) const { return (p->*f)(x); } +private: + S (T::*f)(A) const; +}; + +template <class S, class T, class A> +class mem_fun1_ref_t : public binary_function<T, A, S> { +public: + explicit mem_fun1_ref_t(S (T::*pf)(A)) : f(pf) {} + S operator()(T& r, A x) const { return (r.*f)(x); } +private: + S (T::*f)(A); +}; + +template <class S, class T, class A> +class const_mem_fun1_ref_t : public binary_function<T, A, S> { +public: + explicit const_mem_fun1_ref_t(S (T::*pf)(A) const) : f(pf) {} + S operator()(const T& r, A x) const { return (r.*f)(x); } +private: + S (T::*f)(A) const; +}; + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + +template <class T> +class mem_fun_t<void, T> : public unary_function<T*, void> { +public: + explicit mem_fun_t(void (T::*pf)()) : f(pf) {} + void operator()(T* p) const { (p->*f)(); } +private: + void (T::*f)(); +}; + +template <class T> +class const_mem_fun_t<void, T> : public unary_function<const T*, void> { +public: + explicit const_mem_fun_t(void (T::*pf)() const) : f(pf) {} + void operator()(const T* p) const { (p->*f)(); } +private: + void (T::*f)() const; +}; + +template <class T> +class mem_fun_ref_t<void, T> : public unary_function<T, void> { +public: + explicit mem_fun_ref_t(void (T::*pf)()) : f(pf) {} + void operator()(T& r) const { (r.*f)(); } +private: + void (T::*f)(); +}; + +template <class T> +class const_mem_fun_ref_t<void, T> : public unary_function<T, void> { +public: + explicit const_mem_fun_ref_t(void (T::*pf)() const) : f(pf) {} + void operator()(const T& r) const { (r.*f)(); } +private: + void (T::*f)() const; +}; + +template <class T, class A> +class mem_fun1_t<void, T, A> : public binary_function<T*, A, void> { +public: + explicit mem_fun1_t(void (T::*pf)(A)) : f(pf) {} + void operator()(T* p, A x) const { (p->*f)(x); } +private: + void (T::*f)(A); +}; + +template <class T, class A> +class const_mem_fun1_t<void, T, A> : public binary_function<const T*, A, void> { +public: + explicit const_mem_fun1_t(void (T::*pf)(A) const) : f(pf) {} + void operator()(const T* p, A x) const { (p->*f)(x); } +private: + void (T::*f)(A) const; +}; + +template <class T, class A> +class mem_fun1_ref_t<void, T, A> : public binary_function<T, A, void> { +public: + explicit mem_fun1_ref_t(void (T::*pf)(A)) : f(pf) {} + void operator()(T& r, A x) const { (r.*f)(x); } +private: + void (T::*f)(A); +}; + +template <class T, class A> +class const_mem_fun1_ref_t<void, T, A> : public binary_function<T, A, void> { +public: + explicit const_mem_fun1_ref_t(void (T::*pf)(A) const) : f(pf) {} + void operator()(const T& r, A x) const { (r.*f)(x); } +private: + void (T::*f)(A) const; +}; + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +// Mem_fun adaptor helper functions. There are only four: +// mem_fun, mem_fun_ref, mem_fun1, mem_fun1_ref. + +template <class S, class T> +inline mem_fun_t<S,T> mem_fun(S (T::*f)()) { + return mem_fun_t<S,T>(f); +} + +template <class S, class T> +inline const_mem_fun_t<S,T> mem_fun(S (T::*f)() const) { + return const_mem_fun_t<S,T>(f); +} + +template <class S, class T> +inline mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)()) { + return mem_fun_ref_t<S,T>(f); +} + +template <class S, class T> +inline const_mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)() const) { + return const_mem_fun_ref_t<S,T>(f); +} + +template <class S, class T, class A> +inline mem_fun1_t<S,T,A> mem_fun1(S (T::*f)(A)) { + return mem_fun1_t<S,T,A>(f); +} + +template <class S, class T, class A> +inline const_mem_fun1_t<S,T,A> mem_fun1(S (T::*f)(A) const) { + return const_mem_fun1_t<S,T,A>(f); +} + +template <class S, class T, class A> +inline mem_fun1_ref_t<S,T,A> mem_fun1_ref(S (T::*f)(A)) { + return mem_fun1_ref_t<S,T,A>(f); +} + +template <class S, class T, class A> +inline const_mem_fun1_ref_t<S,T,A> mem_fun1_ref(S (T::*f)(A) const) { + return const_mem_fun1_ref_t<S,T,A>(f); +} + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_FUNCTION_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/stl_hash_fun.h b/contrib/libstdc++/stl/stl_hash_fun.h new file mode 100644 index 0000000..3afa9dc --- /dev/null +++ b/contrib/libstdc++/stl/stl_hash_fun.h @@ -0,0 +1,93 @@ +/* + * 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_HASH_FUN_H +#define __SGI_STL_HASH_FUN_H + +#include <stddef.h> + +__STL_BEGIN_NAMESPACE + +template <class Key> struct hash { }; + +inline size_t __stl_hash_string(const char* s) +{ + unsigned long h = 0; + for ( ; *s; ++s) + h = 5*h + *s; + + return size_t(h); +} + +__STL_TEMPLATE_NULL struct hash<char*> +{ + size_t operator()(const char* s) const { return __stl_hash_string(s); } +}; + +__STL_TEMPLATE_NULL struct hash<const char*> +{ + size_t operator()(const char* s) const { return __stl_hash_string(s); } +}; + +__STL_TEMPLATE_NULL struct hash<char> { + size_t operator()(char x) const { return x; } +}; +__STL_TEMPLATE_NULL struct hash<unsigned char> { + size_t operator()(unsigned char x) const { return x; } +}; +__STL_TEMPLATE_NULL struct hash<signed char> { + size_t operator()(unsigned char x) const { return x; } +}; +__STL_TEMPLATE_NULL struct hash<short> { + size_t operator()(short x) const { return x; } +}; +__STL_TEMPLATE_NULL struct hash<unsigned short> { + size_t operator()(unsigned short x) const { return x; } +}; +__STL_TEMPLATE_NULL struct hash<int> { + size_t operator()(int x) const { return x; } +}; +__STL_TEMPLATE_NULL struct hash<unsigned int> { + size_t operator()(unsigned int x) const { return x; } +}; +__STL_TEMPLATE_NULL struct hash<long> { + size_t operator()(long x) const { return x; } +}; +__STL_TEMPLATE_NULL struct hash<unsigned long> { + 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/contrib/libstdc++/stl/stl_hash_map.h b/contrib/libstdc++/stl/stl_hash_map.h new file mode 100644 index 0000000..9999e9a --- /dev/null +++ b/contrib/libstdc++/stl/stl_hash_map.h @@ -0,0 +1,358 @@ +/* + * 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 +#endif + +#ifndef __STL_LIMITED_DEFAULT_TEMPLATES +template <class Key, class T, class HashFcn = hash<Key>, + class EqualKey = equal_to<Key>, + class Alloc = alloc> +#else +template <class Key, class T, class HashFcn, class EqualKey, + class Alloc = alloc> +#endif +class hash_map +{ +private: + typedef hashtable<pair<const Key, T>, Key, HashFcn, + select1st<pair<const Key, T> >, EqualKey, Alloc> ht; + ht rep; + +public: + typedef typename ht::key_type key_type; + typedef T data_type; + typedef T mapped_type; + typedef typename ht::value_type value_type; + typedef typename ht::hasher hasher; + typedef typename ht::key_equal key_equal; + + typedef typename ht::size_type size_type; + typedef typename ht::difference_type difference_type; + typedef typename ht::pointer pointer; + typedef typename ht::const_pointer const_pointer; + typedef typename ht::reference reference; + typedef typename ht::const_reference const_reference; + + typedef typename ht::iterator iterator; + typedef typename ht::const_iterator const_iterator; + + hasher hash_funct() const { return rep.hash_funct(); } + key_equal key_eq() const { return rep.key_eq(); } + +public: + hash_map() : rep(100, hasher(), key_equal()) {} + explicit hash_map(size_type n) : rep(n, hasher(), key_equal()) {} + hash_map(size_type n, const hasher& hf) : rep(n, hf, key_equal()) {} + hash_map(size_type n, const hasher& hf, const key_equal& eql) + : rep(n, hf, eql) {} + +#ifdef __STL_MEMBER_TEMPLATES + template <class InputIterator> + hash_map(InputIterator f, InputIterator l) + : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); } + template <class InputIterator> + hash_map(InputIterator f, InputIterator l, size_type n) + : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); } + template <class InputIterator> + hash_map(InputIterator f, InputIterator l, size_type n, + const hasher& hf) + : rep(n, hf, key_equal()) { rep.insert_unique(f, l); } + template <class InputIterator> + hash_map(InputIterator f, InputIterator l, size_type n, + const hasher& hf, const key_equal& eql) + : rep(n, hf, eql) { rep.insert_unique(f, l); } + +#else + hash_map(const value_type* f, const value_type* l) + : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); } + hash_map(const value_type* f, const value_type* l, size_type n) + : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); } + hash_map(const value_type* f, const value_type* l, size_type n, + const hasher& hf) + : rep(n, hf, key_equal()) { rep.insert_unique(f, l); } + hash_map(const value_type* f, const value_type* l, size_type n, + const hasher& hf, const key_equal& eql) + : rep(n, hf, eql) { rep.insert_unique(f, l); } + + hash_map(const_iterator f, const_iterator l) + : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); } + hash_map(const_iterator f, const_iterator l, size_type n) + : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); } + hash_map(const_iterator f, const_iterator l, size_type n, + const hasher& hf) + : rep(n, hf, key_equal()) { rep.insert_unique(f, l); } + hash_map(const_iterator f, const_iterator l, size_type n, + const hasher& hf, const key_equal& eql) + : rep(n, hf, eql) { rep.insert_unique(f, l); } +#endif /*__STL_MEMBER_TEMPLATES */ + +public: + size_type size() const { return rep.size(); } + size_type max_size() const { return rep.max_size(); } + bool empty() const { return rep.empty(); } + void swap(hash_map& hs) { rep.swap(hs.rep); } + friend bool + operator== __STL_NULL_TMPL_ARGS (const hash_map&, const hash_map&); + + iterator begin() { return rep.begin(); } + iterator end() { return rep.end(); } + const_iterator begin() const { return rep.begin(); } + const_iterator end() const { return rep.end(); } + +public: + pair<iterator, bool> insert(const value_type& obj) + { return rep.insert_unique(obj); } +#ifdef __STL_MEMBER_TEMPLATES + template <class InputIterator> + void insert(InputIterator f, InputIterator l) { rep.insert_unique(f,l); } +#else + void insert(const value_type* f, const value_type* l) { + rep.insert_unique(f,l); + } + void insert(const_iterator f, const_iterator l) { rep.insert_unique(f, l); } +#endif /*__STL_MEMBER_TEMPLATES */ + pair<iterator, bool> insert_noresize(const value_type& obj) + { return rep.insert_unique_noresize(obj); } + + iterator find(const key_type& key) { return rep.find(key); } + const_iterator find(const key_type& key) const { return rep.find(key); } + + T& operator[](const key_type& key) { + return rep.find_or_insert(value_type(key, T())).second; + } + + size_type count(const key_type& key) const { return rep.count(key); } + + pair<iterator, iterator> equal_range(const key_type& key) + { return rep.equal_range(key); } + pair<const_iterator, const_iterator> equal_range(const key_type& key) const + { return rep.equal_range(key); } + + size_type erase(const key_type& key) {return rep.erase(key); } + void erase(iterator it) { rep.erase(it); } + void erase(iterator f, iterator l) { rep.erase(f, l); } + void clear() { rep.clear(); } + +public: + void resize(size_type hint) { rep.resize(hint); } + size_type bucket_count() const { return rep.bucket_count(); } + size_type max_bucket_count() const { return rep.max_bucket_count(); } + size_type elems_in_bucket(size_type n) const + { return rep.elems_in_bucket(n); } +}; + +template <class Key, class T, class HashFcn, class EqualKey, class Alloc> +inline bool operator==(const hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm1, + const hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm2) +{ + return hm1.rep == hm2.rep; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template <class Key, class T, class HashFcn, class EqualKey, class Alloc> +inline void swap(hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm1, + hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm2) +{ + hm1.swap(hm2); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +#ifndef __STL_LIMITED_DEFAULT_TEMPLATES +template <class Key, class T, class HashFcn = hash<Key>, + class EqualKey = equal_to<Key>, + class Alloc = alloc> +#else +template <class Key, class T, class HashFcn, class EqualKey, + class Alloc = alloc> +#endif +class hash_multimap +{ +private: + typedef hashtable<pair<const Key, T>, Key, HashFcn, + select1st<pair<const Key, T> >, EqualKey, Alloc> ht; + ht rep; + +public: + typedef typename ht::key_type key_type; + typedef T data_type; + typedef T mapped_type; + typedef typename ht::value_type value_type; + typedef typename ht::hasher hasher; + typedef typename ht::key_equal key_equal; + + typedef typename ht::size_type size_type; + typedef typename ht::difference_type difference_type; + typedef typename ht::pointer pointer; + typedef typename ht::const_pointer const_pointer; + typedef typename ht::reference reference; + typedef typename ht::const_reference const_reference; + + typedef typename ht::iterator iterator; + typedef typename ht::const_iterator const_iterator; + + hasher hash_funct() const { return rep.hash_funct(); } + key_equal key_eq() const { return rep.key_eq(); } + +public: + hash_multimap() : rep(100, hasher(), key_equal()) {} + explicit hash_multimap(size_type n) : rep(n, hasher(), key_equal()) {} + hash_multimap(size_type n, const hasher& hf) : rep(n, hf, key_equal()) {} + hash_multimap(size_type n, const hasher& hf, const key_equal& eql) + : rep(n, hf, eql) {} + +#ifdef __STL_MEMBER_TEMPLATES + template <class InputIterator> + hash_multimap(InputIterator f, InputIterator l) + : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); } + template <class InputIterator> + hash_multimap(InputIterator f, InputIterator l, size_type n) + : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); } + template <class InputIterator> + hash_multimap(InputIterator f, InputIterator l, size_type n, + const hasher& hf) + : rep(n, hf, key_equal()) { rep.insert_equal(f, l); } + template <class InputIterator> + hash_multimap(InputIterator f, InputIterator l, size_type n, + const hasher& hf, const key_equal& eql) + : rep(n, hf, eql) { rep.insert_equal(f, l); } + +#else + hash_multimap(const value_type* f, const value_type* l) + : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); } + hash_multimap(const value_type* f, const value_type* l, size_type n) + : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); } + hash_multimap(const value_type* f, const value_type* l, size_type n, + const hasher& hf) + : rep(n, hf, key_equal()) { rep.insert_equal(f, l); } + hash_multimap(const value_type* f, const value_type* l, size_type n, + const hasher& hf, const key_equal& eql) + : rep(n, hf, eql) { rep.insert_equal(f, l); } + + hash_multimap(const_iterator f, const_iterator l) + : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); } + hash_multimap(const_iterator f, const_iterator l, size_type n) + : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); } + hash_multimap(const_iterator f, const_iterator l, size_type n, + const hasher& hf) + : rep(n, hf, key_equal()) { rep.insert_equal(f, l); } + hash_multimap(const_iterator f, const_iterator l, size_type n, + const hasher& hf, const key_equal& eql) + : rep(n, hf, eql) { rep.insert_equal(f, l); } +#endif /*__STL_MEMBER_TEMPLATES */ + +public: + size_type size() const { return rep.size(); } + size_type max_size() const { return rep.max_size(); } + bool empty() const { return rep.empty(); } + void swap(hash_multimap& hs) { rep.swap(hs.rep); } + friend bool + operator== __STL_NULL_TMPL_ARGS (const hash_multimap&, const hash_multimap&); + + iterator begin() { return rep.begin(); } + iterator end() { return rep.end(); } + const_iterator begin() const { return rep.begin(); } + const_iterator end() const { return rep.end(); } + +public: + iterator insert(const value_type& obj) { return rep.insert_equal(obj); } +#ifdef __STL_MEMBER_TEMPLATES + template <class InputIterator> + void insert(InputIterator f, InputIterator l) { rep.insert_equal(f,l); } +#else + void insert(const value_type* f, const value_type* l) { + rep.insert_equal(f,l); + } + void insert(const_iterator f, const_iterator l) { rep.insert_equal(f, l); } +#endif /*__STL_MEMBER_TEMPLATES */ + iterator insert_noresize(const value_type& obj) + { return rep.insert_equal_noresize(obj); } + + iterator find(const key_type& key) { return rep.find(key); } + const_iterator find(const key_type& key) const { return rep.find(key); } + + size_type count(const key_type& key) const { return rep.count(key); } + + pair<iterator, iterator> equal_range(const key_type& key) + { return rep.equal_range(key); } + pair<const_iterator, const_iterator> equal_range(const key_type& key) const + { return rep.equal_range(key); } + + size_type erase(const key_type& key) {return rep.erase(key); } + void erase(iterator it) { rep.erase(it); } + void erase(iterator f, iterator l) { rep.erase(f, l); } + void clear() { rep.clear(); } + +public: + void resize(size_type hint) { rep.resize(hint); } + size_type bucket_count() const { return rep.bucket_count(); } + size_type max_bucket_count() const { return rep.max_bucket_count(); } + size_type elems_in_bucket(size_type n) const + { return rep.elems_in_bucket(n); } +}; + +template <class Key, class T, class HF, class EqKey, class Alloc> +inline bool operator==(const hash_multimap<Key, T, HF, EqKey, Alloc>& hm1, + const hash_multimap<Key, T, HF, EqKey, Alloc>& hm2) +{ + return hm1.rep == hm2.rep; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template <class Key, class T, class HashFcn, class EqualKey, class Alloc> +inline void swap(hash_multimap<Key, T, HashFcn, EqualKey, Alloc>& hm1, + hash_multimap<Key, T, HashFcn, EqualKey, 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 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_HASH_MAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/stl_hash_set.h b/contrib/libstdc++/stl/stl_hash_set.h new file mode 100644 index 0000000..1ba87c4 --- /dev/null +++ b/contrib/libstdc++/stl/stl_hash_set.h @@ -0,0 +1,343 @@ +/* + * 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 +#endif + +#ifndef __STL_LIMITED_DEFAULT_TEMPLATES +template <class Value, class HashFcn = hash<Value>, + class EqualKey = equal_to<Value>, + class Alloc = alloc> +#else +template <class Value, class HashFcn, class EqualKey, class Alloc = alloc> +#endif +class hash_set +{ +private: + typedef hashtable<Value, Value, HashFcn, identity<Value>, + EqualKey, Alloc> ht; + ht rep; + +public: + typedef 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; + + hasher hash_funct() const { return rep.hash_funct(); } + key_equal key_eq() const { return rep.key_eq(); } + +public: + hash_set() : rep(100, hasher(), key_equal()) {} + explicit hash_set(size_type n) : rep(n, hasher(), key_equal()) {} + hash_set(size_type n, const hasher& hf) : rep(n, hf, key_equal()) {} + hash_set(size_type n, const hasher& hf, const key_equal& eql) + : rep(n, hf, eql) {} + +#ifdef __STL_MEMBER_TEMPLATES + template <class InputIterator> + hash_set(InputIterator f, InputIterator l) + : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); } + template <class InputIterator> + hash_set(InputIterator f, InputIterator l, size_type n) + : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); } + template <class InputIterator> + hash_set(InputIterator f, InputIterator l, size_type n, + const hasher& hf) + : rep(n, hf, key_equal()) { rep.insert_unique(f, l); } + template <class InputIterator> + hash_set(InputIterator f, InputIterator l, size_type n, + const hasher& hf, const key_equal& eql) + : rep(n, hf, eql) { rep.insert_unique(f, l); } +#else + + hash_set(const value_type* f, const value_type* l) + : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); } + hash_set(const value_type* f, const value_type* l, size_type n) + : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); } + hash_set(const value_type* f, const value_type* l, size_type n, + const hasher& hf) + : rep(n, hf, key_equal()) { rep.insert_unique(f, l); } + hash_set(const value_type* f, const value_type* l, size_type n, + const hasher& hf, const key_equal& eql) + : rep(n, hf, eql) { rep.insert_unique(f, l); } + + hash_set(const_iterator f, const_iterator l) + : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); } + hash_set(const_iterator f, const_iterator l, size_type n) + : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); } + hash_set(const_iterator f, const_iterator l, size_type n, + const hasher& hf) + : rep(n, hf, key_equal()) { rep.insert_unique(f, l); } + hash_set(const_iterator f, const_iterator l, size_type n, + const hasher& hf, const key_equal& eql) + : rep(n, hf, eql) { rep.insert_unique(f, l); } +#endif /*__STL_MEMBER_TEMPLATES */ + +public: + size_type size() const { return rep.size(); } + size_type max_size() const { return rep.max_size(); } + bool empty() const { return rep.empty(); } + void swap(hash_set& hs) { rep.swap(hs.rep); } + friend bool operator== __STL_NULL_TMPL_ARGS (const hash_set&, + const hash_set&); + + iterator begin() const { return rep.begin(); } + iterator end() const { return rep.end(); } + +public: + pair<iterator, bool> insert(const value_type& obj) + { + pair<typename ht::iterator, bool> p = rep.insert_unique(obj); + return pair<iterator, bool>(p.first, p.second); + } +#ifdef __STL_MEMBER_TEMPLATES + template <class InputIterator> + void insert(InputIterator f, InputIterator l) { rep.insert_unique(f,l); } +#else + void insert(const value_type* f, const value_type* l) { + rep.insert_unique(f,l); + } + void insert(const_iterator f, const_iterator l) {rep.insert_unique(f, l); } +#endif /*__STL_MEMBER_TEMPLATES */ + pair<iterator, bool> insert_noresize(const value_type& obj) + { + pair<typename ht::iterator, bool> p = rep.insert_unique_noresize(obj); + return pair<iterator, bool>(p.first, p.second); + } + + iterator find(const key_type& key) const { return rep.find(key); } + + size_type count(const key_type& key) const { return rep.count(key); } + + pair<iterator, iterator> equal_range(const key_type& key) const + { return rep.equal_range(key); } + + size_type erase(const key_type& key) {return rep.erase(key); } + void erase(iterator it) { rep.erase(it); } + void erase(iterator f, iterator l) { rep.erase(f, l); } + void clear() { rep.clear(); } + +public: + void resize(size_type hint) { rep.resize(hint); } + size_type bucket_count() const { return rep.bucket_count(); } + size_type max_bucket_count() const { return rep.max_bucket_count(); } + size_type elems_in_bucket(size_type n) const + { return rep.elems_in_bucket(n); } +}; + +template <class Value, class HashFcn, class EqualKey, class Alloc> +inline bool operator==(const hash_set<Value, HashFcn, EqualKey, Alloc>& hs1, + const hash_set<Value, HashFcn, EqualKey, Alloc>& hs2) +{ + return hs1.rep == hs2.rep; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template <class Val, class HashFcn, class EqualKey, class Alloc> +inline void swap(hash_set<Val, HashFcn, EqualKey, Alloc>& hs1, + hash_set<Val, HashFcn, EqualKey, Alloc>& hs2) { + hs1.swap(hs2); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + + +#ifndef __STL_LIMITED_DEFAULT_TEMPLATES +template <class Value, class HashFcn = hash<Value>, + class EqualKey = equal_to<Value>, + class Alloc = alloc> +#else +template <class Value, class HashFcn, class EqualKey, class Alloc = alloc> +#endif +class hash_multiset +{ +private: + typedef hashtable<Value, Value, HashFcn, identity<Value>, + EqualKey, Alloc> ht; + ht rep; + +public: + typedef 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; + + hasher hash_funct() const { return rep.hash_funct(); } + key_equal key_eq() const { return rep.key_eq(); } + +public: + hash_multiset() : rep(100, hasher(), key_equal()) {} + explicit hash_multiset(size_type n) : rep(n, hasher(), key_equal()) {} + hash_multiset(size_type n, const hasher& hf) : rep(n, hf, key_equal()) {} + hash_multiset(size_type n, const hasher& hf, const key_equal& eql) + : rep(n, hf, eql) {} + +#ifdef __STL_MEMBER_TEMPLATES + template <class InputIterator> + hash_multiset(InputIterator f, InputIterator l) + : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); } + template <class InputIterator> + hash_multiset(InputIterator f, InputIterator l, size_type n) + : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); } + template <class InputIterator> + hash_multiset(InputIterator f, InputIterator l, size_type n, + const hasher& hf) + : rep(n, hf, key_equal()) { rep.insert_equal(f, l); } + template <class InputIterator> + hash_multiset(InputIterator f, InputIterator l, size_type n, + const hasher& hf, const key_equal& eql) + : rep(n, hf, eql) { rep.insert_equal(f, l); } +#else + + hash_multiset(const value_type* f, const value_type* l) + : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); } + hash_multiset(const value_type* f, const value_type* l, size_type n) + : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); } + hash_multiset(const value_type* f, const value_type* l, size_type n, + const hasher& hf) + : rep(n, hf, key_equal()) { rep.insert_equal(f, l); } + hash_multiset(const value_type* f, const value_type* l, size_type n, + const hasher& hf, const key_equal& eql) + : rep(n, hf, eql) { rep.insert_equal(f, l); } + + hash_multiset(const_iterator f, const_iterator l) + : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); } + hash_multiset(const_iterator f, const_iterator l, size_type n) + : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); } + hash_multiset(const_iterator f, const_iterator l, size_type n, + const hasher& hf) + : rep(n, hf, key_equal()) { rep.insert_equal(f, l); } + hash_multiset(const_iterator f, const_iterator l, size_type n, + const hasher& hf, const key_equal& eql) + : rep(n, hf, eql) { rep.insert_equal(f, l); } +#endif /*__STL_MEMBER_TEMPLATES */ + +public: + size_type size() const { return rep.size(); } + size_type max_size() const { return rep.max_size(); } + bool empty() const { return rep.empty(); } + void swap(hash_multiset& hs) { rep.swap(hs.rep); } + friend bool operator== __STL_NULL_TMPL_ARGS (const hash_multiset&, + const hash_multiset&); + + iterator begin() const { return rep.begin(); } + iterator end() const { return rep.end(); } + +public: + iterator insert(const value_type& obj) { return rep.insert_equal(obj); } +#ifdef __STL_MEMBER_TEMPLATES + template <class InputIterator> + void insert(InputIterator f, InputIterator l) { rep.insert_equal(f,l); } +#else + void insert(const value_type* f, const value_type* l) { + rep.insert_equal(f,l); + } + void insert(const_iterator f, const_iterator l) { rep.insert_equal(f, l); } +#endif /*__STL_MEMBER_TEMPLATES */ + iterator insert_noresize(const value_type& obj) + { return rep.insert_equal_noresize(obj); } + + iterator find(const key_type& key) const { return rep.find(key); } + + size_type count(const key_type& key) const { return rep.count(key); } + + pair<iterator, iterator> equal_range(const key_type& key) const + { return rep.equal_range(key); } + + size_type erase(const key_type& key) {return rep.erase(key); } + void erase(iterator it) { rep.erase(it); } + void erase(iterator f, iterator l) { rep.erase(f, l); } + void clear() { rep.clear(); } + +public: + void resize(size_type hint) { rep.resize(hint); } + size_type bucket_count() const { return rep.bucket_count(); } + size_type max_bucket_count() const { return rep.max_bucket_count(); } + size_type elems_in_bucket(size_type n) const + { return rep.elems_in_bucket(n); } +}; + +template <class Val, class HashFcn, class EqualKey, class Alloc> +inline bool operator==(const hash_multiset<Val, HashFcn, EqualKey, Alloc>& hs1, + const hash_multiset<Val, HashFcn, EqualKey, Alloc>& hs2) +{ + return hs1.rep == hs2.rep; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template <class Val, class HashFcn, class EqualKey, class Alloc> +inline void swap(hash_multiset<Val, HashFcn, EqualKey, Alloc>& hs1, + hash_multiset<Val, HashFcn, EqualKey, Alloc>& hs2) +{ + hs1.swap(hs2); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_HASH_SET_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/stl_hashtable.h b/contrib/libstdc++/stl/stl_hashtable.h new file mode 100644 index 0000000..e5b63b2 --- /dev/null +++ b/contrib/libstdc++/stl/stl_hashtable.h @@ -0,0 +1,948 @@ +/* + * 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 <stl_algobase.h> +#include <stl_alloc.h> +#include <stl_construct.h> +#include <stl_tempbuf.h> +#include <stl_algo.h> +#include <stl_uninitialized.h> +#include <stl_function.h> +#include <stl_vector.h> +#include <stl_hash_fun.h> + +__STL_BEGIN_NAMESPACE + +template <class Value> +struct __hashtable_node +{ + __hashtable_node* next; + Value val; +}; + +template <class Value, class Key, class HashFcn, + class ExtractKey, class EqualKey, class Alloc = alloc> +class hashtable; + +template <class Value, class Key, class HashFcn, + class ExtractKey, class EqualKey, class Alloc> +struct __hashtable_iterator; + +template <class Value, class Key, class HashFcn, + class ExtractKey, class EqualKey, class Alloc> +struct __hashtable_const_iterator; + +template <class Value, class Key, class HashFcn, + class ExtractKey, class EqualKey, class Alloc> +struct __hashtable_iterator { + typedef hashtable<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc> + hashtable; + typedef __hashtable_iterator<Value, Key, HashFcn, + ExtractKey, EqualKey, Alloc> + iterator; + typedef __hashtable_const_iterator<Value, Key, HashFcn, + ExtractKey, EqualKey, Alloc> + const_iterator; + typedef __hashtable_node<Value> node; + + typedef forward_iterator_tag iterator_category; + typedef Value value_type; + typedef ptrdiff_t difference_type; + typedef size_t size_type; + typedef Value& reference; + typedef Value* pointer; + + node* cur; + hashtable* ht; + + __hashtable_iterator(node* n, hashtable* tab) : cur(n), ht(tab) {} + __hashtable_iterator() {} + reference operator*() const { return cur->val; } +#ifndef __SGI_STL_NO_ARROW_OPERATOR + pointer operator->() const { return &(operator*()); } +#endif /* __SGI_STL_NO_ARROW_OPERATOR */ + iterator& operator++(); + iterator operator++(int); + bool operator==(const iterator& it) const { return cur == it.cur; } + bool operator!=(const iterator& it) const { return cur != it.cur; } +}; + + +template <class Value, class Key, class HashFcn, + class ExtractKey, class EqualKey, class Alloc> +struct __hashtable_const_iterator { + typedef hashtable<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc> + hashtable; + typedef __hashtable_iterator<Value, Key, HashFcn, + ExtractKey, EqualKey, Alloc> + iterator; + typedef __hashtable_const_iterator<Value, Key, HashFcn, + ExtractKey, EqualKey, Alloc> + const_iterator; + typedef __hashtable_node<Value> node; + + typedef forward_iterator_tag iterator_category; + typedef Value value_type; + typedef ptrdiff_t difference_type; + typedef size_t size_type; + typedef const Value& reference; + typedef const Value* pointer; + + const node* cur; + const hashtable* ht; + + __hashtable_const_iterator(const node* n, const hashtable* tab) + : cur(n), ht(tab) {} + __hashtable_const_iterator() {} + __hashtable_const_iterator(const iterator& it) : cur(it.cur), ht(it.ht) {} + reference operator*() const { return cur->val; } +#ifndef __SGI_STL_NO_ARROW_OPERATOR + pointer operator->() const { return &(operator*()); } +#endif /* __SGI_STL_NO_ARROW_OPERATOR */ + const_iterator& operator++(); + const_iterator operator++(int); + bool operator==(const const_iterator& it) const { return cur == it.cur; } + bool operator!=(const const_iterator& it) const { return cur != it.cur; } +}; + +// Note: assumes long is at least 32 bits. +static const int __stl_num_primes = 28; +static const unsigned long __stl_prime_list[__stl_num_primes] = +{ + 53, 97, 193, 389, 769, + 1543, 3079, 6151, 12289, 24593, + 49157, 98317, 196613, 393241, 786433, + 1572869, 3145739, 6291469, 12582917, 25165843, + 50331653, 100663319, 201326611, 402653189, 805306457, + 1610612741, 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; +} + + +template <class Value, class Key, class HashFcn, + class ExtractKey, class EqualKey, + class Alloc> +class hashtable { +public: + typedef Key key_type; + typedef Value value_type; + typedef HashFcn hasher; + typedef EqualKey key_equal; + + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + + hasher hash_funct() const { return hash; } + key_equal key_eq() const { return equals; } + +private: + hasher hash; + key_equal equals; + ExtractKey get_key; + + typedef __hashtable_node<Value> node; + typedef simple_alloc<node, Alloc> node_allocator; + + vector<node*,Alloc> buckets; + size_type num_elements; + +public: + typedef __hashtable_iterator<Value, Key, HashFcn, ExtractKey, EqualKey, + Alloc> + iterator; + + typedef __hashtable_const_iterator<Value, Key, HashFcn, ExtractKey, EqualKey, + Alloc> + const_iterator; + + friend struct + __hashtable_iterator<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc>; + friend struct + __hashtable_const_iterator<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc>; + +public: + hashtable(size_type n, + const HashFcn& hf, + const EqualKey& eql, + const ExtractKey& ext) + : hash(hf), equals(eql), get_key(ext), num_elements(0) + { + initialize_buckets(n); + } + + hashtable(size_type n, + const HashFcn& hf, + const EqualKey& eql) + : hash(hf), equals(eql), get_key(ExtractKey()), num_elements(0) + { + initialize_buckets(n); + } + + hashtable(const hashtable& ht) + : hash(ht.hash), equals(ht.equals), get_key(ht.get_key), num_elements(0) + { + copy_from(ht); + } + + hashtable& operator= (const hashtable& ht) + { + if (&ht != this) { + clear(); + hash = ht.hash; + equals = ht.equals; + get_key = ht.get_key; + copy_from(ht); + } + return *this; + } + + ~hashtable() { clear(); } + + size_type size() const { return num_elements; } + size_type max_size() const { return size_type(-1); } + bool empty() const { return size() == 0; } + + void swap(hashtable& ht) + { + __STD::swap(hash, ht.hash); + __STD::swap(equals, ht.equals); + __STD::swap(get_key, ht.get_key); + buckets.swap(ht.buckets); + __STD::swap(num_elements, ht.num_elements); + } + + iterator begin() + { + for (size_type n = 0; n < buckets.size(); ++n) + if (buckets[n]) + return iterator(buckets[n], this); + return end(); + } + + iterator end() { return iterator(0, this); } + + const_iterator begin() const + { + for (size_type n = 0; n < buckets.size(); ++n) + if (buckets[n]) + return const_iterator(buckets[n], this); + return end(); + } + + const_iterator end() const { return const_iterator(0, this); } + + friend bool + operator== __STL_NULL_TMPL_ARGS (const hashtable&, const hashtable&); + +public: + + size_type bucket_count() const { return buckets.size(); } + + size_type max_bucket_count() const + { return __stl_prime_list[__stl_num_primes - 1]; } + + size_type elems_in_bucket(size_type bucket) const + { + size_type result = 0; + for (node* cur = buckets[bucket]; cur; cur = cur->next) + result += 1; + return result; + } + + pair<iterator, bool> insert_unique(const value_type& obj) + { + resize(num_elements + 1); + return insert_unique_noresize(obj); + } + + iterator insert_equal(const value_type& obj) + { + resize(num_elements + 1); + return insert_equal_noresize(obj); + } + + pair<iterator, bool> insert_unique_noresize(const value_type& obj); + iterator insert_equal_noresize(const value_type& obj); + +#ifdef __STL_MEMBER_TEMPLATES + template <class InputIterator> + void insert_unique(InputIterator f, InputIterator l) + { + insert_unique(f, l, iterator_category(f)); + } + + template <class InputIterator> + void insert_equal(InputIterator f, InputIterator l) + { + insert_equal(f, l, iterator_category(f)); + } + + template <class InputIterator> + void insert_unique(InputIterator f, InputIterator l, + input_iterator_tag) + { + for ( ; f != l; ++f) + insert_unique(*f); + } + + template <class InputIterator> + void insert_equal(InputIterator f, InputIterator l, + input_iterator_tag) + { + for ( ; f != l; ++f) + insert_equal(*f); + } + + template <class ForwardIterator> + void insert_unique(ForwardIterator f, ForwardIterator l, + forward_iterator_tag) + { + size_type n = 0; + distance(f, l, n); + resize(num_elements + n); + for ( ; n > 0; --n, ++f) + insert_unique_noresize(*f); + } + + template <class ForwardIterator> + void insert_equal(ForwardIterator f, ForwardIterator l, + forward_iterator_tag) + { + size_type n = 0; + distance(f, l, n); + resize(num_elements + n); + for ( ; n > 0; --n, ++f) + insert_equal_noresize(*f); + } + +#else /* __STL_MEMBER_TEMPLATES */ + void insert_unique(const value_type* f, const value_type* l) + { + size_type n = l - f; + resize(num_elements + n); + for ( ; n > 0; --n, ++f) + insert_unique_noresize(*f); + } + + void insert_equal(const value_type* f, const value_type* l) + { + size_type n = l - f; + resize(num_elements + n); + for ( ; n > 0; --n, ++f) + insert_equal_noresize(*f); + } + + void insert_unique(const_iterator f, const_iterator l) + { + size_type n = 0; + distance(f, l, n); + resize(num_elements + n); + for ( ; n > 0; --n, ++f) + insert_unique_noresize(*f); + } + + void insert_equal(const_iterator f, const_iterator l) + { + size_type n = 0; + distance(f, l, n); + resize(num_elements + n); + for ( ; n > 0; --n, ++f) + insert_equal_noresize(*f); + } +#endif /*__STL_MEMBER_TEMPLATES */ + + reference find_or_insert(const value_type& obj); + + iterator find(const key_type& key) + { + size_type n = bkt_num_key(key); + node* first; + for ( first = buckets[n]; + first && !equals(get_key(first->val), key); + first = first->next) + {} + return iterator(first, this); + } + + const_iterator find(const key_type& key) const + { + size_type n = bkt_num_key(key); + const node* first; + for ( first = buckets[n]; + first && !equals(get_key(first->val), key); + first = first->next) + {} + return const_iterator(first, this); + } + + size_type count(const key_type& key) const + { + const size_type n = bkt_num_key(key); + size_type result = 0; + + for (const node* cur = buckets[n]; cur; cur = cur->next) + if (equals(get_key(cur->val), key)) + ++result; + return result; + } + + pair<iterator, iterator> equal_range(const key_type& key); + pair<const_iterator, const_iterator> equal_range(const key_type& key) const; + + size_type erase(const key_type& key); + void erase(const iterator& it); + void erase(iterator first, iterator last); + + void erase(const const_iterator& it); + void erase(const_iterator first, const_iterator last); + + void resize(size_type num_elements_hint); + void clear(); + +private: + size_type next_size(size_type n) const { return __stl_next_prime(n); } + + void initialize_buckets(size_type n) + { + const size_type n_buckets = next_size(n); + buckets.reserve(n_buckets); + buckets.insert(buckets.end(), n_buckets, (node*) 0); + num_elements = 0; + } + + size_type bkt_num_key(const key_type& key) const + { + return bkt_num_key(key, buckets.size()); + } + + size_type bkt_num(const value_type& obj) const + { + return bkt_num_key(get_key(obj)); + } + + size_type bkt_num_key(const key_type& key, size_t n) const + { + return hash(key) % n; + } + + size_type bkt_num(const value_type& obj, size_t n) const + { + return bkt_num_key(get_key(obj), n); + } + + node* new_node(const value_type& obj) + { + node* n = node_allocator::allocate(); + n->next = 0; + __STL_TRY { + construct(&n->val, obj); + return n; + } + __STL_UNWIND(node_allocator::deallocate(n)); + } + + void delete_node(node* n) + { + destroy(&n->val); + node_allocator::deallocate(n); + } + + void erase_bucket(const size_type n, node* first, node* last); + void erase_bucket(const size_type n, node* last); + + void copy_from(const hashtable& ht); + +}; + +template <class V, class K, class HF, class ExK, class EqK, class A> +__hashtable_iterator<V, K, HF, ExK, EqK, A>& +__hashtable_iterator<V, K, HF, ExK, EqK, A>::operator++() +{ + const node* old = cur; + cur = cur->next; + if (!cur) { + size_type bucket = ht->bkt_num(old->val); + while (!cur && ++bucket < ht->buckets.size()) + cur = ht->buckets[bucket]; + } + return *this; +} + +template <class V, class K, class HF, class ExK, class EqK, class A> +inline __hashtable_iterator<V, K, HF, ExK, EqK, A> +__hashtable_iterator<V, K, HF, ExK, EqK, A>::operator++(int) +{ + iterator tmp = *this; + ++*this; + return tmp; +} + +template <class V, class K, class HF, class ExK, class EqK, class A> +__hashtable_const_iterator<V, K, HF, ExK, EqK, A>& +__hashtable_const_iterator<V, K, HF, ExK, EqK, A>::operator++() +{ + const node* old = cur; + cur = cur->next; + if (!cur) { + size_type bucket = ht->bkt_num(old->val); + while (!cur && ++bucket < ht->buckets.size()) + cur = ht->buckets[bucket]; + } + return *this; +} + +template <class V, class K, class HF, class ExK, class EqK, class A> +inline __hashtable_const_iterator<V, K, HF, ExK, EqK, A> +__hashtable_const_iterator<V, K, HF, ExK, EqK, A>::operator++(int) +{ + const_iterator tmp = *this; + ++*this; + return tmp; +} + +#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION + +template <class V, class K, class HF, class ExK, class EqK, class All> +inline forward_iterator_tag +iterator_category(const __hashtable_iterator<V, K, HF, ExK, EqK, All>&) +{ + return forward_iterator_tag(); +} + +template <class V, class K, class HF, class ExK, class EqK, class All> +inline V* value_type(const __hashtable_iterator<V, K, HF, ExK, EqK, All>&) +{ + return (V*) 0; +} + +template <class V, class K, class HF, class ExK, class EqK, class All> +inline hashtable<V, K, HF, ExK, EqK, All>::difference_type* +distance_type(const __hashtable_iterator<V, K, HF, ExK, EqK, All>&) +{ + return (hashtable<V, K, HF, ExK, EqK, All>::difference_type*) 0; +} + +template <class V, class K, class HF, class ExK, class EqK, class All> +inline forward_iterator_tag +iterator_category(const __hashtable_const_iterator<V, K, HF, ExK, EqK, All>&) +{ + return forward_iterator_tag(); +} + +template <class V, class K, class HF, class ExK, class EqK, class All> +inline V* +value_type(const __hashtable_const_iterator<V, K, HF, ExK, EqK, All>&) +{ + return (V*) 0; +} + +template <class V, class K, class HF, class ExK, class EqK, class All> +inline hashtable<V, K, HF, ExK, EqK, All>::difference_type* +distance_type(const __hashtable_const_iterator<V, K, HF, ExK, EqK, All>&) +{ + return (hashtable<V, K, HF, ExK, EqK, All>::difference_type*) 0; +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template <class V, class K, class HF, class Ex, class Eq, class A> +bool operator==(const hashtable<V, K, HF, Ex, Eq, A>& ht1, + const hashtable<V, K, HF, Ex, Eq, A>& ht2) +{ + typedef typename hashtable<V, K, HF, Ex, Eq, A>::node node; + if (ht1.buckets.size() != ht2.buckets.size()) + return false; + for (int n = 0; n < ht1.buckets.size(); ++n) { + node* cur1 = ht1.buckets[n]; + node* cur2 = ht2.buckets[n]; + for ( ; cur1 && cur2 && cur1->val == cur2->val; + cur1 = cur1->next, cur2 = cur2->next) + {} + if (cur1 || cur2) + return false; + } + return true; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template <class Val, class Key, class HF, class Extract, class EqKey, class A> +inline void swap(hashtable<Val, Key, HF, Extract, EqKey, A>& ht1, + hashtable<Val, Key, HF, Extract, EqKey, A>& ht2) { + ht1.swap(ht2); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + + +template <class V, class K, class HF, class Ex, class Eq, class A> +pair<typename hashtable<V, K, HF, Ex, Eq, A>::iterator, bool> +hashtable<V, K, HF, Ex, Eq, A>::insert_unique_noresize(const value_type& obj) +{ + const size_type n = bkt_num(obj); + node* first = buckets[n]; + + for (node* cur = first; cur; cur = cur->next) + if (equals(get_key(cur->val), get_key(obj))) + return pair<iterator, bool>(iterator(cur, this), false); + + node* tmp = new_node(obj); + tmp->next = first; + buckets[n] = tmp; + ++num_elements; + return pair<iterator, bool>(iterator(tmp, this), true); +} + +template <class V, class K, class HF, class Ex, class Eq, class A> +typename hashtable<V, K, HF, Ex, Eq, A>::iterator +hashtable<V, K, HF, Ex, Eq, A>::insert_equal_noresize(const value_type& obj) +{ + const size_type n = bkt_num(obj); + node* first = buckets[n]; + + for (node* cur = first; cur; cur = cur->next) + if (equals(get_key(cur->val), get_key(obj))) { + node* tmp = new_node(obj); + tmp->next = cur->next; + cur->next = tmp; + ++num_elements; + return iterator(tmp, this); + } + + node* tmp = new_node(obj); + tmp->next = first; + buckets[n] = tmp; + ++num_elements; + return iterator(tmp, this); +} + +template <class V, class K, class HF, class Ex, class Eq, class A> +typename hashtable<V, K, HF, Ex, Eq, A>::reference +hashtable<V, K, HF, Ex, Eq, A>::find_or_insert(const value_type& obj) +{ + resize(num_elements + 1); + + size_type n = bkt_num(obj); + node* first = buckets[n]; + + for (node* cur = first; cur; cur = cur->next) + if (equals(get_key(cur->val), get_key(obj))) + return cur->val; + + node* tmp = new_node(obj); + tmp->next = first; + buckets[n] = tmp; + ++num_elements; + return tmp->val; +} + +template <class V, class K, class HF, class Ex, class Eq, class A> +pair<typename hashtable<V, K, HF, Ex, Eq, A>::iterator, + typename hashtable<V, K, HF, Ex, Eq, A>::iterator> +hashtable<V, K, HF, Ex, Eq, A>::equal_range(const key_type& key) +{ + typedef pair<iterator, iterator> pii; + const size_type n = bkt_num_key(key); + + for (node* first = buckets[n]; first; first = first->next) { + if (equals(get_key(first->val), key)) { + for (node* cur = first->next; cur; cur = cur->next) + if (!equals(get_key(cur->val), key)) + return pii(iterator(first, this), iterator(cur, this)); + for (size_type m = n + 1; m < buckets.size(); ++m) + if (buckets[m]) + return pii(iterator(first, this), + iterator(buckets[m], this)); + return pii(iterator(first, this), end()); + } + } + return pii(end(), end()); +} + +template <class V, class K, class HF, class Ex, class Eq, class A> +pair<typename hashtable<V, K, HF, Ex, Eq, A>::const_iterator, + typename hashtable<V, K, HF, Ex, Eq, A>::const_iterator> +hashtable<V, K, HF, Ex, Eq, A>::equal_range(const key_type& key) const +{ + typedef pair<const_iterator, const_iterator> pii; + const size_type n = bkt_num_key(key); + + for (const node* first = buckets[n] ; first; first = first->next) { + if (equals(get_key(first->val), key)) { + for (const node* cur = first->next; cur; cur = cur->next) + if (!equals(get_key(cur->val), key)) + return pii(const_iterator(first, this), + const_iterator(cur, this)); + for (size_type m = n + 1; m < buckets.size(); ++m) + if (buckets[m]) + return pii(const_iterator(first, this), + const_iterator(buckets[m], this)); + return pii(const_iterator(first, this), end()); + } + } + return pii(end(), end()); +} + +template <class V, class K, class HF, class Ex, class Eq, class A> +typename hashtable<V, K, HF, Ex, Eq, A>::size_type +hashtable<V, K, HF, Ex, Eq, A>::erase(const key_type& key) +{ + const size_type n = bkt_num_key(key); + node* first = buckets[n]; + size_type erased = 0; + + if (first) { + node* cur = first; + node* next = cur->next; + while (next) { + if (equals(get_key(next->val), key)) { + cur->next = next->next; + delete_node(next); + next = cur->next; + ++erased; + --num_elements; + } + else { + cur = next; + next = cur->next; + } + } + if (equals(get_key(first->val), key)) { + buckets[n] = first->next; + delete_node(first); + ++erased; + --num_elements; + } + } + return erased; +} + +template <class V, class K, class HF, class Ex, class Eq, class A> +void hashtable<V, K, HF, Ex, Eq, A>::erase(const iterator& it) +{ + if (node* const p = it.cur) { + const size_type n = bkt_num(p->val); + node* cur = buckets[n]; + + if (cur == p) { + buckets[n] = cur->next; + delete_node(cur); + --num_elements; + } + else { + node* next = cur->next; + while (next) { + if (next == p) { + cur->next = next->next; + delete_node(next); + --num_elements; + break; + } + else { + cur = next; + next = cur->next; + } + } + } + } +} + +template <class V, class K, class HF, class Ex, class Eq, class A> +void hashtable<V, K, HF, Ex, Eq, A>::erase(iterator first, iterator last) +{ + size_type f_bucket = first.cur ? bkt_num(first.cur->val) : buckets.size(); + size_type l_bucket = last.cur ? bkt_num(last.cur->val) : buckets.size(); + + if (first.cur == last.cur) + return; + else if (f_bucket == l_bucket) + erase_bucket(f_bucket, first.cur, last.cur); + else { + erase_bucket(f_bucket, first.cur, 0); + for (size_type n = f_bucket + 1; n < l_bucket; ++n) + erase_bucket(n, 0); + if (l_bucket != buckets.size()) + erase_bucket(l_bucket, last.cur); + } +} + +template <class V, class K, class HF, class Ex, class Eq, class A> +inline void +hashtable<V, K, HF, Ex, Eq, A>::erase(const_iterator first, + const_iterator last) +{ + erase(iterator(const_cast<node*>(first.cur), + const_cast<hashtable*>(first.ht)), + iterator(const_cast<node*>(last.cur), + const_cast<hashtable*>(last.ht))); +} + +template <class V, class K, class HF, class Ex, class Eq, class A> +inline void +hashtable<V, K, HF, Ex, Eq, A>::erase(const const_iterator& it) +{ + erase(iterator(const_cast<node*>(it.cur), + const_cast<hashtable*>(it.ht))); +} + +template <class V, class K, class HF, class Ex, class Eq, class A> +void hashtable<V, K, HF, Ex, Eq, A>::resize(size_type num_elements_hint) +{ + const size_type old_n = buckets.size(); + if (num_elements_hint > old_n) { + const size_type n = next_size(num_elements_hint); + if (n > old_n) { + vector<node*, A> tmp(n, (node*) 0); + __STL_TRY { + for (size_type bucket = 0; bucket < old_n; ++bucket) { + node* first = buckets[bucket]; + while (first) { + size_type new_bucket = bkt_num(first->val, n); + buckets[bucket] = first->next; + first->next = tmp[new_bucket]; + tmp[new_bucket] = first; + first = buckets[bucket]; + } + } + buckets.swap(tmp); + } +# ifdef __STL_USE_EXCEPTIONS + catch(...) { + for (size_type bucket = 0; bucket < tmp.size(); ++bucket) { + while (tmp[bucket]) { + node* next = tmp[bucket]->next; + delete_node(tmp[bucket]); + tmp[bucket] = next; + } + } + throw; + } +# endif /* __STL_USE_EXCEPTIONS */ + } + } +} + +template <class V, class K, class HF, class Ex, class Eq, class A> +void hashtable<V, K, HF, Ex, Eq, A>::erase_bucket(const size_type n, + node* first, node* last) +{ + node* cur = buckets[n]; + if (cur == first) + erase_bucket(n, last); + else { + node* next; + for (next = cur->next; next != first; cur = next, next = cur->next) + ; + while (next) { + cur->next = next->next; + delete_node(next); + next = cur->next; + --num_elements; + } + } +} + +template <class V, class K, class HF, class Ex, class Eq, class A> +void +hashtable<V, K, HF, Ex, Eq, A>::erase_bucket(const size_type n, node* last) +{ + node* cur = buckets[n]; + while (cur != last) { + node* next = cur->next; + delete_node(cur); + cur = next; + buckets[n] = cur; + --num_elements; + } +} + +template <class V, class K, class HF, class Ex, class Eq, class A> +void hashtable<V, K, HF, Ex, Eq, A>::clear() +{ + for (size_type i = 0; i < buckets.size(); ++i) { + node* cur = buckets[i]; + while (cur != 0) { + node* next = cur->next; + delete_node(cur); + cur = next; + } + buckets[i] = 0; + } + num_elements = 0; +} + + +template <class V, class K, class HF, class Ex, class Eq, class A> +void hashtable<V, K, HF, Ex, Eq, A>::copy_from(const hashtable& ht) +{ + buckets.clear(); + buckets.reserve(ht.buckets.size()); + buckets.insert(buckets.end(), ht.buckets.size(), (node*) 0); + __STL_TRY { + for (size_type i = 0; i < ht.buckets.size(); ++i) { + if (const node* cur = ht.buckets[i]) { + node* copy = new_node(cur->val); + buckets[i] = copy; + + for (node* next = cur->next; next; cur = next, next = cur->next) { + copy->next = new_node(next->val); + copy = copy->next; + } + } + } + num_elements = ht.num_elements; + } + __STL_UNWIND(clear()); +} + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_HASHTABLE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/stl_heap.h b/contrib/libstdc++/stl/stl_heap.h new file mode 100644 index 0000000..3fe24f8 --- /dev/null +++ b/contrib/libstdc++/stl/stl_heap.h @@ -0,0 +1,226 @@ +/* + * + * 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 + +template <class RandomAccessIterator, class Distance, class T> +void __push_heap(RandomAccessIterator first, Distance holeIndex, + Distance topIndex, T value) { + Distance parent = (holeIndex - 1) / 2; + while (holeIndex > topIndex && *(first + parent) < value) { + *(first + holeIndex) = *(first + parent); + holeIndex = parent; + parent = (holeIndex - 1) / 2; + } + *(first + holeIndex) = value; +} + +template <class RandomAccessIterator, class Distance, class T> +inline void __push_heap_aux(RandomAccessIterator first, + RandomAccessIterator last, Distance*, T*) { + __push_heap(first, Distance((last - first) - 1), Distance(0), + T(*(last - 1))); +} + +template <class RandomAccessIterator> +inline void push_heap(RandomAccessIterator first, RandomAccessIterator last) { + __push_heap_aux(first, last, distance_type(first), value_type(first)); +} + +template <class RandomAccessIterator, class Distance, class T, class Compare> +void __push_heap(RandomAccessIterator first, Distance holeIndex, + Distance topIndex, T value, Compare comp) { + Distance parent = (holeIndex - 1) / 2; + while (holeIndex > topIndex && comp(*(first + parent), value)) { + *(first + holeIndex) = *(first + parent); + holeIndex = parent; + parent = (holeIndex - 1) / 2; + } + *(first + holeIndex) = value; +} + +template <class RandomAccessIterator, class Compare, class Distance, class T> +inline void __push_heap_aux(RandomAccessIterator first, + RandomAccessIterator last, Compare comp, + Distance*, T*) { + __push_heap(first, Distance((last - first) - 1), Distance(0), + T(*(last - 1)), comp); +} + +template <class RandomAccessIterator, class Compare> +inline void push_heap(RandomAccessIterator first, RandomAccessIterator last, + Compare comp) { + __push_heap_aux(first, last, comp, distance_type(first), value_type(first)); +} + +template <class RandomAccessIterator, class Distance, class T> +void __adjust_heap(RandomAccessIterator first, Distance holeIndex, + Distance len, T value) { + Distance topIndex = holeIndex; + Distance secondChild = 2 * holeIndex + 2; + while (secondChild < len) { + if (*(first + secondChild) < *(first + (secondChild - 1))) + secondChild--; + *(first + holeIndex) = *(first + secondChild); + holeIndex = secondChild; + secondChild = 2 * (secondChild + 1); + } + if (secondChild == len) { + *(first + holeIndex) = *(first + (secondChild - 1)); + holeIndex = secondChild - 1; + } + __push_heap(first, holeIndex, topIndex, value); +} + +template <class RandomAccessIterator, class T, class Distance> +inline void __pop_heap(RandomAccessIterator first, RandomAccessIterator last, + RandomAccessIterator result, T value, Distance*) { + *result = *first; + __adjust_heap(first, Distance(0), Distance(last - first), value); +} + +template <class RandomAccessIterator, class T> +inline void __pop_heap_aux(RandomAccessIterator first, + RandomAccessIterator last, T*) { + __pop_heap(first, last - 1, last - 1, T(*(last - 1)), distance_type(first)); +} + +template <class RandomAccessIterator> +inline void pop_heap(RandomAccessIterator first, RandomAccessIterator last) { + __pop_heap_aux(first, last, value_type(first)); +} + +template <class RandomAccessIterator, class Distance, class T, class Compare> +void __adjust_heap(RandomAccessIterator first, Distance holeIndex, + Distance len, T value, Compare comp) { + Distance topIndex = holeIndex; + Distance secondChild = 2 * holeIndex + 2; + while (secondChild < len) { + if (comp(*(first + secondChild), *(first + (secondChild - 1)))) + secondChild--; + *(first + holeIndex) = *(first + secondChild); + holeIndex = secondChild; + secondChild = 2 * (secondChild + 1); + } + if (secondChild == len) { + *(first + holeIndex) = *(first + (secondChild - 1)); + holeIndex = secondChild - 1; + } + __push_heap(first, holeIndex, topIndex, value, comp); +} + +template <class RandomAccessIterator, class T, class Compare, class Distance> +inline void __pop_heap(RandomAccessIterator first, RandomAccessIterator last, + RandomAccessIterator result, T value, Compare comp, + Distance*) { + *result = *first; + __adjust_heap(first, Distance(0), Distance(last - first), value, comp); +} + +template <class RandomAccessIterator, class T, class Compare> +inline void __pop_heap_aux(RandomAccessIterator first, + RandomAccessIterator last, T*, Compare comp) { + __pop_heap(first, last - 1, last - 1, T(*(last - 1)), comp, + distance_type(first)); +} + +template <class RandomAccessIterator, class Compare> +inline void pop_heap(RandomAccessIterator first, RandomAccessIterator last, + Compare comp) { + __pop_heap_aux(first, last, value_type(first), comp); +} + +template <class RandomAccessIterator, class T, class Distance> +void __make_heap(RandomAccessIterator first, RandomAccessIterator last, T*, + Distance*) { + if (last - first < 2) return; + Distance len = last - first; + Distance parent = (len - 2)/2; + + while (true) { + __adjust_heap(first, parent, len, T(*(first + parent))); + if (parent == 0) return; + parent--; + } +} + +template <class RandomAccessIterator> +inline void make_heap(RandomAccessIterator first, RandomAccessIterator last) { + __make_heap(first, last, value_type(first), distance_type(first)); +} + +template <class RandomAccessIterator, class Compare, class T, class Distance> +void __make_heap(RandomAccessIterator first, RandomAccessIterator last, + Compare comp, T*, Distance*) { + if (last - first < 2) return; + Distance len = last - first; + Distance parent = (len - 2)/2; + + while (true) { + __adjust_heap(first, parent, len, T(*(first + parent)), comp); + if (parent == 0) return; + parent--; + } +} + +template <class RandomAccessIterator, class Compare> +inline void make_heap(RandomAccessIterator first, RandomAccessIterator last, + Compare comp) { + __make_heap(first, last, comp, value_type(first), distance_type(first)); +} + +template <class RandomAccessIterator> +void sort_heap(RandomAccessIterator first, RandomAccessIterator last) { + while (last - first > 1) pop_heap(first, last--); +} + +template <class RandomAccessIterator, class Compare> +void sort_heap(RandomAccessIterator first, RandomAccessIterator last, + Compare comp) { + while (last - first > 1) pop_heap(first, last--, comp); +} + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1209 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_HEAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/stl_iterator.h b/contrib/libstdc++/stl/stl_iterator.h new file mode 100644 index 0000000..892db3e --- /dev/null +++ b/contrib/libstdc++/stl/stl_iterator.h @@ -0,0 +1,843 @@ +/* + * + * 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_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 {}; + +template <class T, class Distance> struct input_iterator { + typedef input_iterator_tag iterator_category; + typedef T value_type; + typedef Distance difference_type; + typedef T* pointer; + typedef T& reference; +}; + +struct output_iterator { + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; +}; + +template <class T, class Distance> struct forward_iterator { + typedef forward_iterator_tag iterator_category; + typedef T value_type; + typedef Distance difference_type; + typedef T* pointer; + typedef T& reference; +}; + + +template <class T, class Distance> struct bidirectional_iterator { + typedef bidirectional_iterator_tag iterator_category; + typedef T value_type; + typedef Distance difference_type; + typedef T* pointer; + typedef T& reference; +}; + +template <class T, class Distance> struct random_access_iterator { + typedef random_access_iterator_tag iterator_category; + typedef T value_type; + typedef Distance difference_type; + typedef T* pointer; + typedef T& reference; +}; + +#ifdef __STL_USE_NAMESPACES +template <class Category, class T, class Distance = ptrdiff_t, + class Pointer = T*, class Reference = T&> +struct iterator { + typedef Category iterator_category; + typedef T value_type; + typedef Distance difference_type; + typedef Pointer pointer; + typedef Reference reference; +}; +#endif /* __STL_USE_NAMESPACES */ + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + +template <class Iterator> +struct iterator_traits { + typedef typename Iterator::iterator_category iterator_category; + typedef typename Iterator::value_type value_type; + typedef typename Iterator::difference_type difference_type; + typedef typename Iterator::pointer pointer; + typedef typename Iterator::reference reference; +}; + +template <class T> +struct iterator_traits<T*> { + typedef random_access_iterator_tag iterator_category; + typedef T value_type; + typedef ptrdiff_t difference_type; + typedef T* pointer; + typedef T& reference; +}; + +template <class T> +struct iterator_traits<const T*> { + typedef random_access_iterator_tag iterator_category; + typedef T value_type; + typedef ptrdiff_t difference_type; + typedef const T* pointer; + typedef const T& reference; +}; + +template <class Iterator> +inline typename iterator_traits<Iterator>::iterator_category +iterator_category(const Iterator&) { + typedef typename iterator_traits<Iterator>::iterator_category category; + return category(); +} + +template <class Iterator> +inline typename iterator_traits<Iterator>::difference_type* +distance_type(const Iterator&) { + return static_cast<typename iterator_traits<Iterator>::difference_type*>(0); +} + +template <class Iterator> +inline typename iterator_traits<Iterator>::value_type* +value_type(const Iterator&) { + return static_cast<typename iterator_traits<Iterator>::value_type*>(0); +} + +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template <class T, class Distance> +inline input_iterator_tag +iterator_category(const input_iterator<T, Distance>&) { + return input_iterator_tag(); +} + +inline output_iterator_tag iterator_category(const output_iterator&) { + return output_iterator_tag(); +} + +template <class T, class Distance> +inline forward_iterator_tag +iterator_category(const forward_iterator<T, Distance>&) { + return forward_iterator_tag(); +} + +template <class T, class Distance> +inline bidirectional_iterator_tag +iterator_category(const bidirectional_iterator<T, Distance>&) { + return bidirectional_iterator_tag(); +} + +template <class T, class Distance> +inline random_access_iterator_tag +iterator_category(const random_access_iterator<T, Distance>&) { + return random_access_iterator_tag(); +} + +template <class T> +inline random_access_iterator_tag iterator_category(const T*) { + return random_access_iterator_tag(); +} + +template <class T, class Distance> +inline T* value_type(const input_iterator<T, Distance>&) { + return (T*)(0); +} + +template <class T, class Distance> +inline T* value_type(const forward_iterator<T, Distance>&) { + return (T*)(0); +} + +template <class T, class Distance> +inline T* value_type(const bidirectional_iterator<T, Distance>&) { + return (T*)(0); +} + +template <class T, class Distance> +inline T* value_type(const random_access_iterator<T, Distance>&) { + return (T*)(0); +} + +template <class T> +inline T* value_type(const T*) { return (T*)(0); } + +template <class T, class Distance> +inline Distance* distance_type(const input_iterator<T, Distance>&) { + return (Distance*)(0); +} + +template <class T, class Distance> +inline Distance* distance_type(const forward_iterator<T, Distance>&) { + return (Distance*)(0); +} + +template <class T, class Distance> +inline Distance* +distance_type(const bidirectional_iterator<T, Distance>&) { + return (Distance*)(0); +} + +template <class T, class Distance> +inline Distance* +distance_type(const random_access_iterator<T, Distance>&) { + return (Distance*)(0); +} + +template <class T> +inline ptrdiff_t* distance_type(const T*) { return (ptrdiff_t*)(0); } + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template <class InputIterator, class Distance> +inline void __distance(InputIterator first, InputIterator last, Distance& n, + input_iterator_tag) { + while (first != last) { ++first; ++n; } +} + +template <class RandomAccessIterator, class Distance> +inline void __distance(RandomAccessIterator first, RandomAccessIterator last, + Distance& n, random_access_iterator_tag) { + n += last - first; +} + +template <class InputIterator, class Distance> +inline void distance(InputIterator first, InputIterator last, Distance& n) { + __distance(first, last, n, iterator_category(first)); +} + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + +template <class InputIterator> +inline iterator_traits<InputIterator>::difference_type +__distance(InputIterator first, InputIterator last, input_iterator_tag) { + iterator_traits<InputIterator>::difference_type n = 0; + while (first != last) { + ++first; ++n; + } + return n; +} + +template <class RandomAccessIterator> +inline iterator_traits<RandomAccessIterator>::difference_type +__distance(RandomAccessIterator first, RandomAccessIterator last, + random_access_iterator_tag) { + return last - first; +} + +template <class InputIterator> +inline iterator_traits<InputIterator>::difference_type +distance(InputIterator first, InputIterator last) { + typedef typename iterator_traits<InputIterator>::iterator_category category; + return __distance(first, last, category()); +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template <class InputIterator, class Distance> +inline void __advance(InputIterator& i, Distance n, input_iterator_tag) { + while (n--) ++i; +} + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1183 +#endif + +template <class BidirectionalIterator, class Distance> +inline void __advance(BidirectionalIterator& i, Distance n, + bidirectional_iterator_tag) { + if (n >= 0) + while (n--) ++i; + else + while (n++) --i; +} + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1183 +#endif + +template <class RandomAccessIterator, class Distance> +inline void __advance(RandomAccessIterator& i, Distance n, + random_access_iterator_tag) { + i += n; +} + +template <class InputIterator, class Distance> +inline void advance(InputIterator& i, Distance n) { + __advance(i, n, iterator_category(i)); +} + +template <class Container> +class back_insert_iterator { +protected: + Container* container; +public: + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + explicit back_insert_iterator(Container& x) : container(&x) {} + back_insert_iterator<Container>& + operator=(const typename Container::value_type& value) { + container->push_back(value); + return *this; + } + back_insert_iterator<Container>& operator*() { return *this; } + back_insert_iterator<Container>& operator++() { return *this; } + back_insert_iterator<Container>& operator++(int) { return *this; } +}; + +#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION + +template <class Container> +inline output_iterator_tag +iterator_category(const back_insert_iterator<Container>&) +{ + return output_iterator_tag(); +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template <class Container> +inline back_insert_iterator<Container> back_inserter(Container& x) { + return back_insert_iterator<Container>(x); +} + +template <class Container> +class front_insert_iterator { +protected: + Container* container; +public: + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + explicit front_insert_iterator(Container& x) : container(&x) {} + front_insert_iterator<Container>& + operator=(const typename Container::value_type& value) { + container->push_front(value); + return *this; + } + front_insert_iterator<Container>& operator*() { return *this; } + front_insert_iterator<Container>& operator++() { return *this; } + front_insert_iterator<Container>& operator++(int) { return *this; } +}; + +#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION + +template <class Container> +inline output_iterator_tag +iterator_category(const front_insert_iterator<Container>&) +{ + return output_iterator_tag(); +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template <class Container> +inline front_insert_iterator<Container> front_inserter(Container& x) { + return front_insert_iterator<Container>(x); +} + +template <class Container> +class insert_iterator { +protected: + Container* container; + typename Container::iterator iter; +public: + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + insert_iterator(Container& x, typename Container::iterator i) + : container(&x), iter(i) {} + insert_iterator<Container>& + operator=(const typename Container::value_type& value) { + iter = container->insert(iter, value); + ++iter; + return *this; + } + insert_iterator<Container>& operator*() { return *this; } + insert_iterator<Container>& operator++() { return *this; } + insert_iterator<Container>& operator++(int) { return *this; } +}; + +#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION + +template <class Container> +inline output_iterator_tag +iterator_category(const insert_iterator<Container>&) +{ + return output_iterator_tag(); +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template <class Container, class Iterator> +inline insert_iterator<Container> inserter(Container& x, Iterator i) { + typedef typename Container::iterator iter; + return insert_iterator<Container>(x, iter(i)); +} + +#ifndef __STL_LIMITED_DEFAULT_TEMPLATES +template <class BidirectionalIterator, class T, class Reference = T&, + class Distance = ptrdiff_t> +#else +template <class BidirectionalIterator, class T, class Reference, + class Distance> +#endif +class reverse_bidirectional_iterator { + typedef reverse_bidirectional_iterator<BidirectionalIterator, T, Reference, + Distance> self; +protected: + BidirectionalIterator current; +public: + typedef bidirectional_iterator_tag iterator_category; + typedef T value_type; + typedef Distance difference_type; + typedef T* pointer; + typedef Reference reference; + + reverse_bidirectional_iterator() {} + explicit reverse_bidirectional_iterator(BidirectionalIterator x) + : current(x) {} + BidirectionalIterator base() 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 <class BidirectionalIterator, class T, class Reference, + class Distance> +inline bidirectional_iterator_tag +iterator_category(const reverse_bidirectional_iterator<BidirectionalIterator, + T, + Reference, Distance>&) { + return bidirectional_iterator_tag(); +} + +template <class BidirectionalIterator, class T, class Reference, + class Distance> +inline T* +value_type(const reverse_bidirectional_iterator<BidirectionalIterator, T, + Reference, Distance>&) { + return (T*) 0; +} + +template <class BidirectionalIterator, class T, class Reference, + class Distance> +inline Distance* +distance_type(const reverse_bidirectional_iterator<BidirectionalIterator, T, + Reference, Distance>&) { + return (Distance*) 0; +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template <class BidirectionalIterator, class T, class Reference, + class Distance> +inline bool operator==( + const reverse_bidirectional_iterator<BidirectionalIterator, T, Reference, + Distance>& x, + const reverse_bidirectional_iterator<BidirectionalIterator, T, Reference, + Distance>& y) { + return x.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 Iterator> +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 <class Iter> + reverse_iterator(const reverse_iterator<Iter>& x) : current(x.current) {} +#endif /* __STL_MEMBER_TEMPLATES */ + + iterator_type base() const { return current; } + reference operator*() const { + Iterator tmp = current; + return *--tmp; + } +#ifndef __SGI_STL_NO_ARROW_OPERATOR + pointer operator->() const { return &(operator*()); } +#endif /* __SGI_STL_NO_ARROW_OPERATOR */ + + self& operator++() { + --current; + return *this; + } + self operator++(int) { + self tmp = *this; + --current; + return tmp; + } + self& operator--() { + ++current; + return *this; + } + self operator--(int) { + self tmp = *this; + ++current; + return tmp; + } + + self operator+(difference_type n) const { + return self(current - n); + } + self& operator+=(difference_type n) { + current -= n; + return *this; + } + self operator-(difference_type n) const { + return self(current + n); + } + self& operator-=(difference_type n) { + current += n; + return *this; + } + reference operator[](difference_type n) const { return *(*this + n); } +}; + +template <class Iterator> +inline bool operator==(const reverse_iterator<Iterator>& x, + const reverse_iterator<Iterator>& y) { + return x.base() == y.base(); +} + +template <class Iterator> +inline bool operator<(const reverse_iterator<Iterator>& x, + const reverse_iterator<Iterator>& y) { + return y.base() < x.base(); +} + +template <class Iterator> +inline typename reverse_iterator<Iterator>::difference_type +operator-(const reverse_iterator<Iterator>& x, + const reverse_iterator<Iterator>& y) { + return y.base() - x.base(); +} + +template <class Iterator> +inline reverse_iterator<Iterator> +operator+(reverse_iterator<Iterator>::difference_type n, + const reverse_iterator<Iterator>& x) { + return reverse_iterator<Iterator>(x.base() - n); +} + +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +// This is the old version of reverse_iterator, as found in the original +// HP STL. It does not use partial specialization. + +#ifndef __STL_LIMITED_DEFAULT_TEMPLATES +template <class RandomAccessIterator, class T, class Reference = T&, + class Distance = ptrdiff_t> +#else +template <class RandomAccessIterator, class T, class Reference, + class Distance> +#endif +class reverse_iterator { + typedef reverse_iterator<RandomAccessIterator, T, Reference, Distance> + self; +protected: + RandomAccessIterator current; +public: + typedef random_access_iterator_tag iterator_category; + typedef T value_type; + typedef Distance difference_type; + typedef T* pointer; + typedef Reference reference; + + reverse_iterator() {} + explicit reverse_iterator(RandomAccessIterator x) : current(x) {} + RandomAccessIterator base() 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 <class RandomAccessIterator, class T, class Reference, class Distance> +inline random_access_iterator_tag +iterator_category(const reverse_iterator<RandomAccessIterator, T, + Reference, Distance>&) { + return random_access_iterator_tag(); +} + +template <class RandomAccessIterator, class T, class Reference, class Distance> +inline T* value_type(const reverse_iterator<RandomAccessIterator, T, + Reference, Distance>&) { + return (T*) 0; +} + +template <class RandomAccessIterator, class T, class Reference, class Distance> +inline Distance* distance_type(const reverse_iterator<RandomAccessIterator, T, + Reference, Distance>&) { + return (Distance*) 0; +} + + +template <class RandomAccessIterator, class T, class Reference, class Distance> +inline bool operator==(const reverse_iterator<RandomAccessIterator, T, + Reference, Distance>& x, + const reverse_iterator<RandomAccessIterator, T, + Reference, Distance>& y) { + return x.base() == y.base(); +} + +template <class RandomAccessIterator, class T, class Reference, class Distance> +inline bool operator<(const reverse_iterator<RandomAccessIterator, T, + Reference, Distance>& x, + const reverse_iterator<RandomAccessIterator, T, + Reference, Distance>& y) { + return y.base() < x.base(); +} + +template <class RandomAccessIterator, class T, class Reference, class Distance> +inline Distance operator-(const reverse_iterator<RandomAccessIterator, T, + Reference, Distance>& x, + const reverse_iterator<RandomAccessIterator, T, + Reference, Distance>& y) { + return y.base() - x.base(); +} + +template <class RandomAccessIter, class T, class Ref, class Dist> +inline reverse_iterator<RandomAccessIter, T, Ref, Dist> +operator+(Dist n, const reverse_iterator<RandomAccessIter, T, Ref, Dist>& x) { + return reverse_iterator<RandomAccessIter, T, Ref, Dist>(x.base() - n); +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template <class T, class Distance = ptrdiff_t> +class istream_iterator { + friend bool + operator== __STL_NULL_TMPL_ARGS (const istream_iterator<T, Distance>& x, + const istream_iterator<T, Distance>& y); +protected: + istream* stream; + T value; + bool end_marker; + void read() { + end_marker = (*stream) ? true : false; + if (end_marker) *stream >> value; + end_marker = (*stream) ? true : false; + } +public: + typedef input_iterator_tag iterator_category; + typedef T value_type; + typedef Distance difference_type; + typedef const T* pointer; + typedef const T& reference; + + istream_iterator() : stream(&cin), end_marker(false) {} + istream_iterator(istream& s) : stream(&s) { read(); } + reference operator*() const { return value; } +#ifndef __SGI_STL_NO_ARROW_OPERATOR + pointer operator->() const { return &(operator*()); } +#endif /* __SGI_STL_NO_ARROW_OPERATOR */ + istream_iterator<T, Distance>& operator++() { + read(); + return *this; + } + istream_iterator<T, Distance> operator++(int) { + istream_iterator<T, Distance> tmp = *this; + read(); + return tmp; + } +}; + +#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION + +template <class T, class Distance> +inline input_iterator_tag +iterator_category(const istream_iterator<T, Distance>&) { + return input_iterator_tag(); +} + +template <class T, class Distance> +inline T* value_type(const istream_iterator<T, Distance>&) { return (T*) 0; } + +template <class T, class Distance> +inline Distance* distance_type(const istream_iterator<T, Distance>&) { + return (Distance*) 0; +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template <class T, class Distance> +inline bool operator==(const istream_iterator<T, Distance>& x, + const istream_iterator<T, Distance>& y) { + return x.stream == y.stream && x.end_marker == y.end_marker || + x.end_marker == false && y.end_marker == false; +} + +template <class T> +class ostream_iterator { +protected: + ostream* stream; + const char* string; +public: + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + ostream_iterator(ostream& s) : stream(&s), string(0) {} + ostream_iterator(ostream& s, const char* c) : stream(&s), string(c) {} + ostream_iterator<T>& operator=(const T& value) { + *stream << value; + if (string) *stream << string; + return *this; + } + ostream_iterator<T>& operator*() { return *this; } + ostream_iterator<T>& operator++() { return *this; } + ostream_iterator<T>& operator++(int) { return *this; } +}; + +#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION + +template <class T> +inline output_iterator_tag +iterator_category(const ostream_iterator<T>&) { + return output_iterator_tag(); +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_ITERATOR_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/stl_list.h b/contrib/libstdc++/stl/stl_list.h new file mode 100644 index 0000000..ac836b6 --- /dev/null +++ b/contrib/libstdc++/stl/stl_list.h @@ -0,0 +1,617 @@ +/* + * + * 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 +#endif + +template <class T> +struct __list_node { + typedef void* void_pointer; + void_pointer next; + void_pointer prev; + T data; +}; + +template<class T, class Ref, class Ptr> +struct __list_iterator { + typedef __list_iterator<T, T&, T*> iterator; + typedef __list_iterator<T, const T&, const T*> const_iterator; + typedef __list_iterator<T, Ref, Ptr> self; + + typedef bidirectional_iterator_tag iterator_category; + typedef T value_type; + typedef Ptr pointer; + typedef Ref reference; + typedef __list_node<T>* link_type; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + + link_type node; + + __list_iterator(link_type x) : node(x) {} + __list_iterator() {} + __list_iterator(const iterator& x) : node(x.node) {} + + bool operator==(const self& x) const { return node == x.node; } + bool operator!=(const self& x) const { return node != x.node; } + reference operator*() const { return (*node).data; } + +#ifndef __SGI_STL_NO_ARROW_OPERATOR + pointer operator->() const { return &(operator*()); } +#endif /* __SGI_STL_NO_ARROW_OPERATOR */ + + self& operator++() { + node = (link_type)((*node).next); + return *this; + } + self operator++(int) { + self tmp = *this; + ++*this; + return tmp; + } + self& operator--() { + node = (link_type)((*node).prev); + return *this; + } + self operator--(int) { + self tmp = *this; + --*this; + return tmp; + } +}; + +#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION + +template <class T, class Ref, class Ptr> +inline bidirectional_iterator_tag +iterator_category(const __list_iterator<T, Ref, Ptr>&) { + return bidirectional_iterator_tag(); +} + +template <class T, class Ref, class Ptr> +inline T* +value_type(const __list_iterator<T, Ref, Ptr>&) { + return 0; +} + +template <class T, class Ref, class Ptr> +inline ptrdiff_t* +distance_type(const __list_iterator<T, Ref, Ptr>&) { + return 0; +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template <class T, class Alloc = alloc> +class list { +protected: + typedef void* void_pointer; + typedef __list_node<T> list_node; + typedef simple_alloc<list_node, Alloc> list_node_allocator; +public: + typedef T value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef list_node* link_type; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + +public: + typedef __list_iterator<T, T&, T*> iterator; + typedef __list_iterator<T, const T&, const T*> const_iterator; + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + typedef reverse_iterator<const_iterator> const_reverse_iterator; + typedef reverse_iterator<iterator> reverse_iterator; +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + typedef reverse_bidirectional_iterator<const_iterator, value_type, + const_reference, difference_type> + const_reverse_iterator; + typedef reverse_bidirectional_iterator<iterator, value_type, reference, + difference_type> + reverse_iterator; +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +protected: + link_type get_node() { return list_node_allocator::allocate(); } + void put_node(link_type p) { list_node_allocator::deallocate(p); } + + link_type create_node(const T& x) { + link_type p = get_node(); + __STL_TRY { + construct(&p->data, x); + } + __STL_UNWIND(put_node(p)); + return p; + } + void destroy_node(link_type p) { + destroy(&p->data); + put_node(p); + } + +protected: + void empty_initialize() { + node = get_node(); + node->next = node; + node->prev = node; + } + + void fill_initialize(size_type n, const T& value) { + empty_initialize(); + __STL_TRY { + insert(begin(), n, value); + } + __STL_UNWIND(clear(); put_node(node)); + } + +#ifdef __STL_MEMBER_TEMPLATES + template <class InputIterator> + void range_initialize(InputIterator first, InputIterator last) { + empty_initialize(); + __STL_TRY { + insert(begin(), first, last); + } + __STL_UNWIND(clear(); put_node(node)); + } +#else /* __STL_MEMBER_TEMPLATES */ + void range_initialize(const T* first, const T* last) { + empty_initialize(); + __STL_TRY { + insert(begin(), first, last); + } + __STL_UNWIND(clear(); put_node(node)); + } + void range_initialize(const_iterator first, const_iterator last) { + empty_initialize(); + __STL_TRY { + insert(begin(), first, last); + } + __STL_UNWIND(clear(); put_node(node)); + } +#endif /* __STL_MEMBER_TEMPLATES */ + +protected: + link_type node; + +public: + list() { empty_initialize(); } + + iterator begin() { return (link_type)((*node).next); } + const_iterator begin() const { return (link_type)((*node).next); } + iterator end() { return node; } + const_iterator end() const { return node; } + reverse_iterator rbegin() { return reverse_iterator(end()); } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } + reverse_iterator rend() { return reverse_iterator(begin()); } + const_reverse_iterator rend() const { + return const_reverse_iterator(begin()); + } + bool empty() const { return node->next == node; } + size_type size() const { + size_type result = 0; + distance(begin(), end(), result); + return result; + } + size_type max_size() const { return size_type(-1); } + reference front() { return *begin(); } + const_reference front() const { return *begin(); } + reference back() { return *(--end()); } + const_reference back() const { return *(--end()); } + void swap(list<T, Alloc>& x) { __STD::swap(node, x.node); } + iterator insert(iterator position, const T& x) { + link_type tmp = create_node(x); + tmp->next = position.node; + tmp->prev = position.node->prev; + (link_type(position.node->prev))->next = tmp; + position.node->prev = tmp; + return tmp; + } + iterator insert(iterator position) { return insert(position, T()); } +#ifdef __STL_MEMBER_TEMPLATES + template <class InputIterator> + void insert(iterator position, InputIterator first, InputIterator last); +#else /* __STL_MEMBER_TEMPLATES */ + void insert(iterator position, const T* first, const T* last); + void insert(iterator position, + const_iterator first, const_iterator last); +#endif /* __STL_MEMBER_TEMPLATES */ + void insert(iterator pos, size_type n, const T& x); + void insert(iterator pos, int n, const T& x) { + insert(pos, (size_type)n, x); + } + void insert(iterator pos, long n, const T& x) { + insert(pos, (size_type)n, x); + } + + void push_front(const T& x) { insert(begin(), x); } + void push_back(const T& x) { insert(end(), x); } + iterator erase(iterator position) { + link_type next_node = link_type(position.node->next); + link_type prev_node = link_type(position.node->prev); + prev_node->next = next_node; + next_node->prev = prev_node; + destroy_node(position.node); + return iterator(next_node); + } + iterator erase(iterator first, iterator last); + void resize(size_type new_size, const T& x); + void resize(size_type new_size) { resize(new_size, T()); } + void clear(); + + void pop_front() { erase(begin()); } + void pop_back() { + iterator tmp = end(); + erase(--tmp); + } + list(size_type n, const T& value) { fill_initialize(n, value); } + list(int n, const T& value) { fill_initialize(n, value); } + list(long n, const T& value) { fill_initialize(n, value); } + explicit list(size_type n) { fill_initialize(n, T()); } + +#ifdef __STL_MEMBER_TEMPLATES + template <class InputIterator> + list(InputIterator first, InputIterator last) { + range_initialize(first, last); + } + +#else /* __STL_MEMBER_TEMPLATES */ + list(const T* first, const T* last) { range_initialize(first, last); } + list(const_iterator first, const_iterator last) { + range_initialize(first, last); + } +#endif /* __STL_MEMBER_TEMPLATES */ + list(const list<T, Alloc>& x) { + range_initialize(x.begin(), x.end()); + } + ~list() { + clear(); + put_node(node); + } + list<T, Alloc>& operator=(const list<T, Alloc>& x); + +protected: + void transfer(iterator position, iterator first, iterator last) { + if (position != last) { + (*(link_type((*last.node).prev))).next = position.node; + (*(link_type((*first.node).prev))).next = last.node; + (*(link_type((*position.node).prev))).next = first.node; + link_type tmp = link_type((*position.node).prev); + (*position.node).prev = (*last.node).prev; + (*last.node).prev = (*first.node).prev; + (*first.node).prev = tmp; + } + } + +public: + void splice(iterator position, list& x) { + if (!x.empty()) + transfer(position, x.begin(), x.end()); + } + void splice(iterator position, list&, iterator i) { + iterator j = i; + ++j; + if (position == i || position == j) return; + transfer(position, i, j); + } + void splice(iterator position, list&, iterator first, iterator last) { + if (first != last) + transfer(position, first, last); + } + void remove(const T& value); + void unique(); + void merge(list& x); + void reverse(); + void sort(); + +#ifdef __STL_MEMBER_TEMPLATES + template <class Predicate> void remove_if(Predicate); + template <class BinaryPredicate> void unique(BinaryPredicate); + template <class StrictWeakOrdering> void merge(list&, StrictWeakOrdering); + template <class StrictWeakOrdering> void sort(StrictWeakOrdering); +#endif /* __STL_MEMBER_TEMPLATES */ + + friend bool operator== __STL_NULL_TMPL_ARGS (const list& x, const list& y); +}; + +template <class T, class Alloc> +inline bool operator==(const list<T,Alloc>& x, const list<T,Alloc>& y) { + typedef typename list<T,Alloc>::link_type link_type; + link_type e1 = x.node; + link_type e2 = y.node; + link_type n1 = (link_type) e1->next; + link_type n2 = (link_type) e2->next; + for ( ; n1 != e1 && n2 != e2 ; + n1 = (link_type) n1->next, n2 = (link_type) n2->next) + if (n1->data != n2->data) + return false; + return n1 == e1 && n2 == e2; +} + +template <class T, class Alloc> +inline bool operator<(const list<T, Alloc>& x, const list<T, Alloc>& y) { + return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template <class T, class Alloc> +inline void swap(list<T, Alloc>& x, list<T, Alloc>& y) { + x.swap(y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +#ifdef __STL_MEMBER_TEMPLATES + +template <class T, class Alloc> template <class InputIterator> +void list<T, Alloc>::insert(iterator position, + InputIterator first, InputIterator last) { + for ( ; first != last; ++first) + insert(position, *first); +} + +#else /* __STL_MEMBER_TEMPLATES */ + +template <class T, class Alloc> +void list<T, Alloc>::insert(iterator position, const T* first, const T* last) { + for ( ; first != last; ++first) + insert(position, *first); +} + +template <class T, class Alloc> +void list<T, Alloc>::insert(iterator position, + const_iterator first, const_iterator last) { + for ( ; first != last; ++first) + insert(position, *first); +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +template <class T, class Alloc> +void list<T, Alloc>::insert(iterator position, size_type n, const T& x) { + for ( ; n > 0; --n) + insert(position, x); +} + +template <class T, class Alloc> +list<T,Alloc>::iterator list<T, Alloc>::erase(iterator first, iterator last) { + while (first != last) erase(first++); + return last; +} + +template <class T, class Alloc> +void list<T, Alloc>::resize(size_type new_size, const T& 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 <class T, class Alloc> +void list<T, Alloc>::clear() +{ + link_type cur = (link_type) node->next; + while (cur != node) { + link_type tmp = cur; + cur = (link_type) cur->next; + destroy_node(tmp); + } + node->next = node; + node->prev = node; +} + +template <class T, class Alloc> +list<T, Alloc>& list<T, Alloc>::operator=(const list<T, Alloc>& x) { + if (this != &x) { + iterator first1 = begin(); + iterator last1 = end(); + const_iterator first2 = x.begin(); + const_iterator last2 = x.end(); + while (first1 != last1 && first2 != last2) *first1++ = *first2++; + if (first2 == last2) + erase(first1, last1); + else + insert(last1, first2, last2); + } + return *this; +} + +template <class T, class Alloc> +void list<T, Alloc>::remove(const T& value) { + iterator first = begin(); + iterator last = end(); + while (first != last) { + iterator next = first; + ++next; + if (*first == value) erase(first); + first = next; + } +} + +template <class T, class Alloc> +void list<T, Alloc>::unique() { + iterator first = begin(); + iterator last = end(); + if (first == last) return; + iterator next = first; + while (++next != last) { + if (*first == *next) + erase(next); + else + first = next; + next = first; + } +} + +template <class T, class Alloc> +void list<T, Alloc>::merge(list<T, Alloc>& x) { + iterator first1 = begin(); + iterator last1 = end(); + iterator first2 = x.begin(); + iterator last2 = x.end(); + while (first1 != last1 && first2 != last2) + if (*first2 < *first1) { + iterator next = first2; + transfer(first1, first2, ++next); + first2 = next; + } + else + ++first1; + if (first2 != last2) transfer(last1, first2, last2); +} + +template <class T, class Alloc> +void list<T, Alloc>::reverse() { + if (node->next == node || link_type(node->next)->next == node) return; + iterator first = begin(); + ++first; + while (first != end()) { + iterator old = first; + ++first; + transfer(begin(), old, first); + } +} + +template <class T, class Alloc> +void list<T, Alloc>::sort() { + if (node->next == node || link_type(node->next)->next == node) return; + list<T, Alloc> carry; + list<T, Alloc> counter[64]; + int fill = 0; + while (!empty()) { + carry.splice(carry.begin(), *this, begin()); + int i = 0; + while(i < fill && !counter[i].empty()) { + counter[i].merge(carry); + carry.swap(counter[i++]); + } + carry.swap(counter[i]); + if (i == fill) ++fill; + } + + for (int i = 1; i < fill; ++i) counter[i].merge(counter[i-1]); + swap(counter[fill-1]); +} + +#ifdef __STL_MEMBER_TEMPLATES + +template <class T, class Alloc> template <class Predicate> +void list<T, Alloc>::remove_if(Predicate pred) { + iterator first = begin(); + iterator last = end(); + while (first != last) { + iterator next = first; + ++next; + if (pred(*first)) erase(first); + first = next; + } +} + +template <class T, class Alloc> template <class BinaryPredicate> +void list<T, Alloc>::unique(BinaryPredicate binary_pred) { + iterator first = begin(); + iterator last = end(); + if (first == last) return; + iterator next = first; + while (++next != last) { + if (binary_pred(*first, *next)) + erase(next); + else + first = next; + next = first; + } +} + +template <class T, class Alloc> template <class StrictWeakOrdering> +void list<T, Alloc>::merge(list<T, Alloc>& x, StrictWeakOrdering comp) { + iterator first1 = begin(); + iterator last1 = end(); + iterator first2 = x.begin(); + iterator last2 = x.end(); + while (first1 != last1 && first2 != last2) + if (comp(*first2, *first1)) { + iterator next = first2; + transfer(first1, first2, ++next); + first2 = next; + } + else + ++first1; + if (first2 != last2) transfer(last1, first2, last2); +} + +template <class T, class Alloc> template <class StrictWeakOrdering> +void list<T, Alloc>::sort(StrictWeakOrdering comp) { + if (node->next == node || link_type(node->next)->next == node) return; + list<T, Alloc> carry; + list<T, Alloc> counter[64]; + int fill = 0; + while (!empty()) { + carry.splice(carry.begin(), *this, begin()); + int i = 0; + while(i < fill && !counter[i].empty()) { + counter[i].merge(carry, comp); + carry.swap(counter[i++]); + } + carry.swap(counter[i]); + if (i == fill) ++fill; + } + + for (int i = 1; i < fill; ++i) counter[i].merge(counter[i-1], comp); + swap(counter[fill-1]); +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_LIST_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/stl_map.h b/contrib/libstdc++/stl/stl_map.h new file mode 100644 index 0000000..2a830cc --- /dev/null +++ b/contrib/libstdc++/stl/stl_map.h @@ -0,0 +1,217 @@ +/* + * + * 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 +#endif + +#ifndef __STL_LIMITED_DEFAULT_TEMPLATES +template <class Key, class T, class Compare = less<Key>, class Alloc = alloc> +#else +template <class Key, class T, class Compare, class Alloc = alloc> +#endif +class map { +public: + +// typedefs: + + typedef Key key_type; + typedef T data_type; + typedef T mapped_type; + typedef pair<const Key, T> value_type; + typedef Compare key_compare; + + class value_compare + : public binary_function<value_type, value_type, bool> { + friend class map<Key, T, Compare, Alloc>; + protected : + Compare comp; + value_compare(Compare c) : comp(c) {} + public: + bool operator()(const value_type& x, const value_type& y) const { + return comp(x.first, y.first); + } + }; + +private: + typedef rb_tree<key_type, value_type, + select1st<value_type>, key_compare, Alloc> rep_type; + rep_type t; // red-black tree representing map +public: + typedef 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; + + // allocation/deallocation + + map() : t(Compare()) {} + explicit map(const Compare& comp) : t(comp) {} + +#ifdef __STL_MEMBER_TEMPLATES + template <class InputIterator> + map(InputIterator first, InputIterator last) + : t(Compare()) { t.insert_unique(first, last); } + + template <class InputIterator> + map(InputIterator first, InputIterator last, const Compare& comp) + : t(comp) { t.insert_unique(first, last); } +#else + map(const value_type* first, const value_type* last) + : t(Compare()) { t.insert_unique(first, last); } + map(const value_type* first, const value_type* last, const Compare& comp) + : t(comp) { t.insert_unique(first, last); } + + map(const_iterator first, const_iterator last) + : t(Compare()) { t.insert_unique(first, last); } + map(const_iterator first, const_iterator last, const Compare& comp) + : t(comp) { t.insert_unique(first, last); } +#endif /* __STL_MEMBER_TEMPLATES */ + + map(const map<Key, T, Compare, Alloc>& x) : t(x.t) {} + map<Key, T, Compare, Alloc>& operator=(const map<Key, T, Compare, Alloc>& x) + { + t = x.t; + return *this; + } + + // accessors: + + key_compare key_comp() const { return t.key_comp(); } + value_compare value_comp() const { return value_compare(t.key_comp()); } + iterator begin() { return t.begin(); } + const_iterator begin() const { return t.begin(); } + iterator end() { return t.end(); } + const_iterator end() const { return t.end(); } + reverse_iterator rbegin() { return t.rbegin(); } + const_reverse_iterator rbegin() const { return t.rbegin(); } + reverse_iterator rend() { return t.rend(); } + const_reverse_iterator rend() const { return t.rend(); } + bool empty() const { return t.empty(); } + size_type size() const { return t.size(); } + size_type max_size() const { return t.max_size(); } + T& operator[](const key_type& k) { + return (*((insert(value_type(k, T()))).first)).second; + } + void swap(map<Key, T, Compare, Alloc>& x) { t.swap(x.t); } + + // insert/erase + + pair<iterator,bool> insert(const value_type& x) { return t.insert_unique(x); } + iterator insert(iterator position, const value_type& x) { + return t.insert_unique(position, x); + } +#ifdef __STL_MEMBER_TEMPLATES + template <class InputIterator> + void insert(InputIterator first, InputIterator last) { + t.insert_unique(first, last); + } +#else + void insert(const value_type* first, const value_type* last) { + t.insert_unique(first, last); + } + void insert(const_iterator first, const_iterator last) { + t.insert_unique(first, last); + } +#endif /* __STL_MEMBER_TEMPLATES */ + + void erase(iterator position) { t.erase(position); } + size_type erase(const key_type& x) { return t.erase(x); } + void erase(iterator first, iterator last) { t.erase(first, last); } + void clear() { t.clear(); } + + // map operations: + + iterator find(const key_type& x) { return t.find(x); } + const_iterator find(const key_type& x) const { return t.find(x); } + size_type count(const key_type& x) const { return t.count(x); } + iterator lower_bound(const key_type& x) {return t.lower_bound(x); } + const_iterator lower_bound(const key_type& x) const { + return t.lower_bound(x); + } + iterator upper_bound(const key_type& x) {return t.upper_bound(x); } + const_iterator upper_bound(const key_type& x) const { + return t.upper_bound(x); + } + + pair<iterator,iterator> equal_range(const key_type& x) { + return t.equal_range(x); + } + pair<const_iterator,const_iterator> equal_range(const key_type& x) const { + return t.equal_range(x); + } + friend bool operator== __STL_NULL_TMPL_ARGS (const map&, const map&); + friend bool operator< __STL_NULL_TMPL_ARGS (const map&, const map&); +}; + +template <class Key, class T, class Compare, class Alloc> +inline bool operator==(const map<Key, T, Compare, Alloc>& x, + const map<Key, T, Compare, Alloc>& y) { + return x.t == y.t; +} + +template <class Key, class T, class Compare, class Alloc> +inline bool operator<(const map<Key, T, Compare, Alloc>& x, + const map<Key, T, Compare, Alloc>& y) { + return x.t < y.t; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template <class Key, class T, class Compare, class Alloc> +inline void swap(map<Key, T, Compare, Alloc>& x, + map<Key, T, 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 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_MAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/stl_multimap.h b/contrib/libstdc++/stl/stl_multimap.h new file mode 100644 index 0000000..b82159b --- /dev/null +++ b/contrib/libstdc++/stl/stl_multimap.h @@ -0,0 +1,214 @@ +/* + * + * 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 +#endif + +#ifndef __STL_LIMITED_DEFAULT_TEMPLATES +template <class Key, class T, class Compare = less<Key>, class Alloc = alloc> +#else +template <class Key, class T, class Compare, class Alloc = alloc> +#endif +class multimap { +public: + +// typedefs: + + typedef Key key_type; + typedef T data_type; + typedef T mapped_type; + typedef pair<const Key, T> value_type; + typedef Compare key_compare; + + class value_compare : public binary_function<value_type, value_type, bool> { + friend class multimap<Key, T, Compare, Alloc>; + protected: + Compare comp; + value_compare(Compare c) : comp(c) {} + public: + bool operator()(const value_type& x, const value_type& y) const { + return comp(x.first, y.first); + } + }; + +private: + typedef rb_tree<key_type, value_type, + select1st<value_type>, key_compare, Alloc> rep_type; + rep_type t; // red-black tree representing multimap +public: + typedef 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; + +// allocation/deallocation + + multimap() : t(Compare()) { } + explicit multimap(const Compare& comp) : t(comp) { } + +#ifdef __STL_MEMBER_TEMPLATES + template <class InputIterator> + multimap(InputIterator first, InputIterator last) + : t(Compare()) { t.insert_equal(first, last); } + + template <class InputIterator> + multimap(InputIterator first, InputIterator last, const Compare& comp) + : t(comp) { t.insert_equal(first, last); } +#else + multimap(const value_type* first, const value_type* last) + : t(Compare()) { t.insert_equal(first, last); } + multimap(const value_type* first, const value_type* last, + const Compare& comp) + : t(comp) { t.insert_equal(first, last); } + + multimap(const_iterator first, const_iterator last) + : t(Compare()) { t.insert_equal(first, last); } + multimap(const_iterator first, const_iterator last, const Compare& comp) + : t(comp) { t.insert_equal(first, last); } +#endif /* __STL_MEMBER_TEMPLATES */ + + multimap(const multimap<Key, T, Compare, Alloc>& x) : t(x.t) { } + multimap<Key, T, Compare, Alloc>& + operator=(const multimap<Key, T, Compare, Alloc>& x) { + t = x.t; + return *this; + } + + // accessors: + + key_compare key_comp() const { return t.key_comp(); } + value_compare value_comp() const { return value_compare(t.key_comp()); } + iterator begin() { return t.begin(); } + const_iterator begin() const { return t.begin(); } + iterator end() { return t.end(); } + const_iterator end() const { return t.end(); } + reverse_iterator rbegin() { return t.rbegin(); } + const_reverse_iterator rbegin() const { return t.rbegin(); } + reverse_iterator rend() { return t.rend(); } + const_reverse_iterator rend() const { return t.rend(); } + bool empty() const { return t.empty(); } + size_type size() const { return t.size(); } + size_type max_size() const { return t.max_size(); } + void swap(multimap<Key, T, Compare, Alloc>& x) { t.swap(x.t); } + + // insert/erase + + iterator insert(const value_type& x) { return t.insert_equal(x); } + iterator insert(iterator position, const value_type& x) { + return t.insert_equal(position, x); + } +#ifdef __STL_MEMBER_TEMPLATES + template <class InputIterator> + void insert(InputIterator first, InputIterator last) { + t.insert_equal(first, last); + } +#else + void insert(const value_type* first, const value_type* last) { + t.insert_equal(first, last); + } + void insert(const_iterator first, const_iterator last) { + t.insert_equal(first, last); + } +#endif /* __STL_MEMBER_TEMPLATES */ + void erase(iterator position) { t.erase(position); } + size_type erase(const key_type& x) { return t.erase(x); } + void erase(iterator first, iterator last) { t.erase(first, last); } + void clear() { t.clear(); } + + // multimap operations: + + iterator find(const key_type& x) { return t.find(x); } + const_iterator find(const key_type& x) const { return t.find(x); } + size_type count(const key_type& x) const { return t.count(x); } + iterator lower_bound(const key_type& x) {return t.lower_bound(x); } + const_iterator lower_bound(const key_type& x) const { + return t.lower_bound(x); + } + iterator upper_bound(const key_type& x) {return t.upper_bound(x); } + const_iterator upper_bound(const key_type& x) const { + return t.upper_bound(x); + } + pair<iterator,iterator> equal_range(const key_type& x) { + return t.equal_range(x); + } + pair<const_iterator,const_iterator> equal_range(const key_type& x) const { + return t.equal_range(x); + } + friend bool operator== __STL_NULL_TMPL_ARGS (const multimap&, + const multimap&); + friend bool operator< __STL_NULL_TMPL_ARGS (const multimap&, + const multimap&); +}; + +template <class Key, class T, class Compare, class Alloc> +inline bool operator==(const multimap<Key, T, Compare, Alloc>& x, + const multimap<Key, T, Compare, Alloc>& y) { + return x.t == y.t; +} + +template <class Key, class T, class Compare, class Alloc> +inline bool operator<(const multimap<Key, T, Compare, Alloc>& x, + const multimap<Key, T, Compare, Alloc>& y) { + return x.t < y.t; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template <class Key, class T, class Compare, class Alloc> +inline void swap(multimap<Key, T, Compare, Alloc>& x, + multimap<Key, T, 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 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_MULTIMAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/stl_multiset.h b/contrib/libstdc++/stl/stl_multiset.h new file mode 100644 index 0000000..ff5947e --- /dev/null +++ b/contrib/libstdc++/stl/stl_multiset.h @@ -0,0 +1,200 @@ +/* + * + * 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 +#endif + +#ifndef __STL_LIMITED_DEFAULT_TEMPLATES +template <class Key, class Compare = less<Key>, class Alloc = alloc> +#else +template <class Key, class Compare, class Alloc = alloc> +#endif +class multiset { +public: + // typedefs: + + typedef Key key_type; + typedef Key value_type; + typedef Compare key_compare; + typedef Compare value_compare; +private: + typedef rb_tree<key_type, value_type, + identity<value_type>, key_compare, Alloc> rep_type; + rep_type t; // red-black tree representing multiset +public: + typedef 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; + + // allocation/deallocation + + multiset() : t(Compare()) {} + explicit multiset(const Compare& comp) : t(comp) {} + +#ifdef __STL_MEMBER_TEMPLATES + template <class InputIterator> + multiset(InputIterator first, InputIterator last) + : t(Compare()) { t.insert_equal(first, last); } + template <class InputIterator> + multiset(InputIterator first, InputIterator last, const Compare& comp) + : t(comp) { t.insert_equal(first, last); } +#else + multiset(const value_type* first, const value_type* last) + : t(Compare()) { t.insert_equal(first, last); } + multiset(const value_type* first, const value_type* last, + const Compare& comp) + : t(comp) { t.insert_equal(first, last); } + + multiset(const_iterator first, const_iterator last) + : t(Compare()) { t.insert_equal(first, last); } + multiset(const_iterator first, const_iterator last, const Compare& comp) + : t(comp) { t.insert_equal(first, last); } +#endif /* __STL_MEMBER_TEMPLATES */ + + multiset(const multiset<Key, Compare, Alloc>& x) : t(x.t) {} + multiset<Key, Compare, Alloc>& + operator=(const multiset<Key, Compare, Alloc>& x) { + t = x.t; + return *this; + } + + // accessors: + + key_compare key_comp() const { return t.key_comp(); } + value_compare value_comp() const { return t.key_comp(); } + iterator begin() const { return t.begin(); } + iterator end() const { return t.end(); } + reverse_iterator rbegin() const { return t.rbegin(); } + reverse_iterator rend() const { return t.rend(); } + bool empty() const { return t.empty(); } + size_type size() const { return t.size(); } + size_type max_size() const { return t.max_size(); } + void swap(multiset<Key, Compare, Alloc>& x) { t.swap(x.t); } + + // insert/erase + iterator insert(const value_type& x) { + return t.insert_equal(x); + } + iterator insert(iterator position, const value_type& x) { + typedef typename rep_type::iterator rep_iterator; + return t.insert_equal((rep_iterator&)position, x); + } + +#ifdef __STL_MEMBER_TEMPLATES + template <class InputIterator> + void insert(InputIterator first, InputIterator last) { + t.insert_equal(first, last); + } +#else + void insert(const value_type* first, const value_type* last) { + t.insert_equal(first, last); + } + void insert(const_iterator first, const_iterator last) { + t.insert_equal(first, last); + } +#endif /* __STL_MEMBER_TEMPLATES */ + void erase(iterator position) { + typedef typename rep_type::iterator rep_iterator; + t.erase((rep_iterator&)position); + } + size_type erase(const key_type& x) { + return t.erase(x); + } + void erase(iterator first, iterator last) { + typedef typename rep_type::iterator rep_iterator; + t.erase((rep_iterator&)first, (rep_iterator&)last); + } + void clear() { t.clear(); } + + // multiset operations: + + iterator find(const key_type& x) const { return t.find(x); } + size_type count(const key_type& x) const { return t.count(x); } + iterator lower_bound(const key_type& x) const { + return t.lower_bound(x); + } + iterator upper_bound(const key_type& x) const { + return t.upper_bound(x); + } + pair<iterator,iterator> equal_range(const key_type& x) const { + return t.equal_range(x); + } + friend bool operator== __STL_NULL_TMPL_ARGS (const multiset&, + const multiset&); + friend bool operator< __STL_NULL_TMPL_ARGS (const multiset&, + const multiset&); +}; + +template <class Key, class Compare, class Alloc> +inline bool operator==(const multiset<Key, Compare, Alloc>& x, + const multiset<Key, Compare, Alloc>& y) { + return x.t == y.t; +} + +template <class Key, class Compare, class Alloc> +inline bool operator<(const multiset<Key, Compare, Alloc>& x, + const multiset<Key, Compare, Alloc>& y) { + return x.t < y.t; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template <class Key, class Compare, class Alloc> +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 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_MULTISET_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/stl_numeric.h b/contrib/libstdc++/stl/stl_numeric.h new file mode 100644 index 0000000..57fee2b --- /dev/null +++ b/contrib/libstdc++/stl/stl_numeric.h @@ -0,0 +1,196 @@ +/* + * + * 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 <class InputIterator, class T> +T accumulate(InputIterator first, InputIterator last, T init) { + for ( ; first != last; ++first) + init = init + *first; + return init; +} + +template <class InputIterator, class T, class BinaryOperation> +T accumulate(InputIterator first, InputIterator last, T init, + BinaryOperation binary_op) { + for ( ; first != last; ++first) + init = binary_op(init, *first); + return init; +} + +template <class InputIterator1, class InputIterator2, class T> +T inner_product(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, T init) { + for ( ; first1 != last1; ++first1, ++first2) + init = init + (*first1 * *first2); + return init; +} + +template <class InputIterator1, class InputIterator2, class T, + class BinaryOperation1, class BinaryOperation2> +T inner_product(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, T init, BinaryOperation1 binary_op1, + BinaryOperation2 binary_op2) { + for ( ; first1 != last1; ++first1, ++first2) + init = binary_op1(init, binary_op2(*first1, *first2)); + return init; +} + +template <class InputIterator, class OutputIterator, class T> +OutputIterator __partial_sum(InputIterator first, InputIterator last, + OutputIterator result, T*) { + T value = *first; + while (++first != last) { + value = value + *first; + *++result = value; + } + return ++result; +} + +template <class InputIterator, class OutputIterator> +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 <class InputIterator, class OutputIterator, class T, + class BinaryOperation> +OutputIterator __partial_sum(InputIterator first, InputIterator last, + OutputIterator result, T*, + BinaryOperation binary_op) { + T value = *first; + while (++first != last) { + value = binary_op(value, *first); + *++result = value; + } + return ++result; +} + +template <class InputIterator, class OutputIterator, class BinaryOperation> +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 <class InputIterator, class OutputIterator, class T> +OutputIterator __adjacent_difference(InputIterator first, InputIterator last, + OutputIterator result, T*) { + T value = *first; + while (++first != last) { + T tmp = *first; + *++result = tmp - value; + value = tmp; + } + return ++result; +} + +template <class InputIterator, class OutputIterator> +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 <class InputIterator, class OutputIterator, class T, + class BinaryOperation> +OutputIterator __adjacent_difference(InputIterator first, InputIterator last, + OutputIterator result, T*, + BinaryOperation binary_op) { + T value = *first; + while (++first != last) { + T tmp = *first; + *++result = binary_op(tmp, value); + value = tmp; + } + return ++result; +} + +template <class InputIterator, class OutputIterator, class BinaryOperation> +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 <class T, class Integer, class MonoidOperation> +T power(T x, Integer n, MonoidOperation op) { + if (n == 0) + return identity_element(op); + else { + while ((n & 1) == 0) { + n >>= 1; + x = op(x, x); + } + + T result = x; + n >>= 1; + while (n != 0) { + x = op(x, x); + if ((n & 1) != 0) + result = op(result, x); + n >>= 1; + } + return result; + } +} + +template <class T, class Integer> +inline T power(T x, Integer n) { + return power(x, n, multiplies<T>()); +} + + +template <class ForwardIterator, class T> +void iota(ForwardIterator first, ForwardIterator last, T value) { + while (first != last) *first++ = value++; +} + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_NUMERIC_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/stl_pair.h b/contrib/libstdc++/stl/stl_pair.h new file mode 100644 index 0000000..10a9cb0 --- /dev/null +++ b/contrib/libstdc++/stl/stl_pair.h @@ -0,0 +1,73 @@ +/* + * + * 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 <class T1, class T2> +struct pair { + typedef T1 first_type; + typedef T2 second_type; + + T1 first; + T2 second; + pair() : first(T1()), second(T2()) {} + pair(const T1& a, const T2& b) : first(a), second(b) {} + +#ifdef __STL_MEMBER_TEMPLATES + template <class U1, class U2> + pair(const pair<U1, U2>& p) : first(p.first), second(p.second) {} +#endif +}; + +template <class T1, class T2> +inline bool operator==(const pair<T1, T2>& x, const pair<T1, T2>& y) { + return x.first == y.first && x.second == y.second; +} + +template <class T1, class T2> +inline bool operator<(const pair<T1, T2>& x, const pair<T1, T2>& y) { + return x.first < y.first || (!(y.first < x.first) && x.second < y.second); +} + +template <class T1, class T2> +inline pair<T1, T2> make_pair(const T1& x, const T2& y) { + return pair<T1, T2>(x, y); +} + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_PAIR_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/stl_queue.h b/contrib/libstdc++/stl/stl_queue.h new file mode 100644 index 0000000..ff6eede --- /dev/null +++ b/contrib/libstdc++/stl/stl_queue.h @@ -0,0 +1,134 @@ +/* + * + * 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 <class T, class Sequence = deque<T> > +#else +template <class T, class Sequence> +#endif +class queue { + friend bool operator== __STL_NULL_TMPL_ARGS (const queue& x, const queue& y); + friend bool operator< __STL_NULL_TMPL_ARGS (const queue& x, const queue& y); +public: + typedef typename Sequence::value_type value_type; + typedef typename Sequence::size_type size_type; + typedef typename Sequence::reference reference; + typedef typename Sequence::const_reference const_reference; +protected: + Sequence c; +public: + bool empty() const { return c.empty(); } + size_type size() const { return c.size(); } + reference front() { return c.front(); } + const_reference front() const { return c.front(); } + reference back() { return c.back(); } + const_reference back() const { return c.back(); } + void push(const value_type& x) { c.push_back(x); } + void pop() { c.pop_front(); } +}; + +template <class T, class Sequence> +bool operator==(const queue<T, Sequence>& x, const queue<T, Sequence>& y) { + return x.c == y.c; +} + +template <class T, class Sequence> +bool operator<(const queue<T, Sequence>& x, const queue<T, Sequence>& y) { + return x.c < y.c; +} + +#ifndef __STL_LIMITED_DEFAULT_TEMPLATES +template <class T, class Sequence = vector<T>, + class Compare = less<typename Sequence::value_type> > +#else +template <class T, class Sequence, class Compare> +#endif +class priority_queue { +public: + typedef typename Sequence::value_type value_type; + typedef typename Sequence::size_type size_type; + 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) {} + +#ifdef __STL_MEMBER_TEMPLATES + template <class InputIterator> + priority_queue(InputIterator first, InputIterator last, const Compare& x) + : c(first, last), comp(x) { make_heap(c.begin(), c.end(), comp); } + template <class InputIterator> + priority_queue(InputIterator first, InputIterator last) + : c(first, last) { make_heap(c.begin(), c.end(), comp); } +#else /* __STL_MEMBER_TEMPLATES */ + priority_queue(const value_type* first, const value_type* last, + const Compare& x) : c(first, last), comp(x) { + make_heap(c.begin(), c.end(), comp); + } + priority_queue(const value_type* first, const value_type* last) + : c(first, last) { make_heap(c.begin(), c.end(), comp); } +#endif /* __STL_MEMBER_TEMPLATES */ + + bool empty() const { return c.empty(); } + size_type size() const { return c.size(); } + const_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/contrib/libstdc++/stl/stl_raw_storage_iter.h b/contrib/libstdc++/stl/stl_raw_storage_iter.h new file mode 100644 index 0000000..5d3d074 --- /dev/null +++ b/contrib/libstdc++/stl/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 ForwardIterator, class T> +class raw_storage_iterator { +protected: + ForwardIterator iter; +public: + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + explicit raw_storage_iterator(ForwardIterator x) : iter(x) {} + raw_storage_iterator<ForwardIterator, T>& operator*() { return *this; } + raw_storage_iterator<ForwardIterator, T>& operator=(const T& element) { + construct(&*iter, element); + return *this; + } + raw_storage_iterator<ForwardIterator, T>& operator++() { + ++iter; + return *this; + } + raw_storage_iterator<ForwardIterator, T> operator++(int) { + raw_storage_iterator<ForwardIterator, T> tmp = *this; + ++iter; + return tmp; + } +}; + +#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION + +template <class ForwardIterator, class T> +inline output_iterator_tag +iterator_category(const raw_storage_iterator<ForwardIterator, T>&) +{ + return output_iterator_tag(); +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +#endif /* __SGI_STL_INTERNAL_RAW_STORAGE_ITERATOR_H */ + +__STL_END_NAMESPACE + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/stl_relops.h b/contrib/libstdc++/stl/stl_relops.h new file mode 100644 index 0000000..01a0c7c --- /dev/null +++ b/contrib/libstdc++/stl/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 <class T> +inline bool operator!=(const T& x, const T& y) { + return !(x == y); +} + +template <class T> +inline bool operator>(const T& x, const T& y) { + return y < x; +} + +template <class T> +inline bool operator<=(const T& x, const T& y) { + return !(y < x); +} + +template <class T> +inline bool operator>=(const T& x, const T& y) { + return !(x < y); +} + +__STL_END_RELOPS_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_RELOPS */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/stl_rope.h b/contrib/libstdc++/stl/stl_rope.h new file mode 100644 index 0000000..d37c679 --- /dev/null +++ b/contrib/libstdc++/stl/stl_rope.h @@ -0,0 +1,2112 @@ +/* + * 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_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 <mutex.h> +# endif + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1174 +#endif + +// The end-of-C-string character. +// This is what the draft standard says it should be. +template <class charT> +inline charT __eos(charT*) { return charT(); } + +// Test for basic character types. +// For basic character types leaves having a trailing eos. +template <class charT> +inline bool __is_basic_char_type(charT *) { return false; } +template <class charT> +inline bool __is_one_byte_char_type(charT *) { return false; } + +inline bool __is_basic_char_type(char *) { return true; } +inline bool __is_one_byte_char_type(char *) { return true; } +inline bool __is_basic_char_type(wchar_t *) { return true; } + +// Store an eos iff charT is a basic character type. +// Do not reference __eos if it isn't. +template <class charT> +inline void __cond_store_eos(charT&) {} + +inline void __cond_store_eos(char& c) { c = 0; } +inline void __cond_store_eos(wchar_t& c) { c = 0; } + + +// rope<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. +// The __eos function is used for those functions that +// convert to/from C-like strings to detect the end of the string. +// __compare is used as the character comparison function. +template <class charT> +class char_producer { + public: + virtual ~char_producer() {}; + virtual void operator()(size_t start_pos, size_t len, charT* buffer) + = 0; + // Buffer should really be an arbitrary output iterator. + // That way we could flatten directly into an ostream, etc. + // This is thoroughly impossible, since iterator types don't + // have runtime descriptions. +}; + +// Sequence buffers: +// +// Sequence must provide an append operation that appends an +// array to the sequence. Sequence buffers are useful only if +// appending an entire array is cheaper than appending element by element. +// This is true for many string representations. +// This should perhaps inherit from ostream<sequence::value_type> +// and be implemented correspondingly, so that they can be used +// for formatted. For the sake of portability, we don't do this yet. +// +// For now, sequence buffers behave as output iterators. But they also +// behave a little like basic_ostringstream<sequence::value_type> and a +// little like containers. + +template<class sequence, size_t buf_sz = 100 +# if defined(__sgi) && !defined(__GNUC__) +# define __TYPEDEF_WORKAROUND + ,class v = typename sequence::value_type +# endif + > +// 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 *prefix; + value_type buffer[buf_sz]; + size_t buf_count; + public: + void flush() { + prefix->append(buffer, buffer + buf_count); + buf_count = 0; + } + ~sequence_buffer() { flush(); } + sequence_buffer() : prefix(0), buf_count(0) {} + sequence_buffer(const sequence_buffer & x) { + prefix = x.prefix; + buf_count = x.buf_count; + copy(x.buffer, x.buffer + x.buf_count, buffer); + } + sequence_buffer(sequence_buffer & x) { + x.flush(); + prefix = x.prefix; + buf_count = 0; + } + sequence_buffer(sequence& s) : prefix(&s), buf_count(0) {} + sequence_buffer& operator= (sequence_buffer& x) { + x.flush(); + prefix = x.prefix; + buf_count = 0; + return *this; + } + sequence_buffer& operator= (const sequence_buffer& x) { + prefix = x.prefix; + buf_count = x.buf_count; + copy(x.buffer, x.buffer + x.buf_count, buffer); + return *this; + } + void push_back(value_type x) + { + if (buf_count < buf_sz) { + buffer[buf_count] = x; + ++buf_count; + } else { + flush(); + buffer[0] = x; + buf_count = 1; + } + } + void append(value_type *s, size_t len) + { + if (len + buf_count <= buf_sz) { + size_t i, j; + for (i = buf_count, j = 0; j < len; i++, j++) { + buffer[i] = s[j]; + } + buf_count += len; + } else if (0 == buf_count) { + prefix->append(s, s + len); + } else { + flush(); + append(s, len); + } + } + sequence_buffer& write(value_type *s, size_t len) + { + append(s, len); + return *this; + } + sequence_buffer& put(value_type x) + { + push_back(x); + return *this; + } + sequence_buffer& operator=(const value_type& rhs) + { + push_back(rhs); + return *this; + } + sequence_buffer& operator*() { return *this; } + sequence_buffer& operator++() { return *this; } + sequence_buffer& operator++(int) { return *this; } +}; + +// The following should be treated as private, at least for now. +template<class charT> +class __rope_char_consumer { + public: + // If we had member templates, these should not be virtual. + // For now we need to use run-time parametrization where + // compile-time would do. Hence this should all be private + // for now. + // The symmetry with char_producer is accidental and temporary. + virtual ~__rope_char_consumer() {}; + virtual bool operator()(const charT* buffer, size_t len) = 0; +}; + +// +// 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 CharT, class Alloc=__ALLOC> class rope; +template<class CharT, class Alloc> struct __rope_RopeConcatenation; +template<class CharT, class Alloc> struct __rope_RopeLeaf; +template<class CharT, class Alloc> struct __rope_RopeFunction; +template<class CharT, class Alloc> struct __rope_RopeSubstring; +template<class CharT, class Alloc> class __rope_iterator; +template<class CharT, class Alloc> class __rope_const_iterator; +template<class CharT, class Alloc> class __rope_charT_ref_proxy; +template<class CharT, class Alloc> class __rope_charT_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 RopeBase. Most of the more complex algorithms +// are implemented as rope members. +// +// Some of the static member functions of RopeBase have identically +// named functions in rope that simply invoke the RopeBase versions. +// + +template<class charT, class Alloc> +struct __rope_RopeBase { + typedef rope<charT,Alloc> my_rope; + typedef simple_alloc<charT, Alloc> DataAlloc; + typedef simple_alloc<__rope_RopeConcatenation<charT,Alloc>, Alloc> CAlloc; + typedef simple_alloc<__rope_RopeLeaf<charT,Alloc>, Alloc> LAlloc; + typedef simple_alloc<__rope_RopeFunction<charT,Alloc>, Alloc> FAlloc; + typedef simple_alloc<__rope_RopeSubstring<charT,Alloc>, Alloc> SAlloc; + public: + enum { max_rope_depth = 45 }; + enum {leaf, concat, substringfn, function} tag:8; + bool is_balanced:8; + unsigned char depth; + size_t size; + __GC_CONST charT * c_string; + /* Flattened version of string, if needed. */ + /* typically 0. */ + /* If it's not 0, then the memory is owned */ + /* by this node. */ + /* In the case of a leaf, this may point to */ + /* the same memory as the data field. */ +# ifndef __GC +# if defined(__STL_WIN32THREADS) + long refcount; // InterlockedIncrement wants a long * +# else + size_t refcount; +# endif + // We count references from rope instances + // and references from other rope nodes. We + // do not count const_iterator references. + // Iterator references are counted so that rope modifications + // can be detected after the fact. + // Generally function results are counted, i.e. + // a pointer returned by a function is included at the + // point at which the pointer is returned. + // The recipient should decrement the count if the + // result is not needed. + // Generally function arguments are not reflected + // in the reference count. The callee should increment + // the count before saving the argument someplace that + // will outlive the call. +# 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 init_refcount_lock() {} + void incr_refcount () + { + __add_and_fetch(&refcount, 1); + } + size_t decr_refcount () + { + return __add_and_fetch(&refcount, (size_t)(-1)); + } +# elif defined(__STL_WIN32THREADS) + void init_refcount_lock() {} + void incr_refcount () + { + InterlockedIncrement(&refcount); + } + size_t decr_refcount () + { + return InterlockedDecrement(&refcount); + } +# elif defined(__STL_PTHREADS) + // This should be portable, but performance is expected + // to be quite awful. This really needs platform specific + // code. + pthread_mutex_t refcount_lock; + void init_refcount_lock() { + pthread_mutex_init(&refcount_lock, 0); + } + void incr_refcount () + { + pthread_mutex_lock(&refcount_lock); + ++refcount; + pthread_mutex_unlock(&refcount_lock); + } + size_t decr_refcount () + { + size_t result; + pthread_mutex_lock(&refcount_lock); + result = --refcount; + pthread_mutex_unlock(&refcount_lock); + return result; + } +# else + void init_refcount_lock() {} + void incr_refcount () + { + ++refcount; + } + size_t decr_refcount () + { + --refcount; + return refcount; + } +# endif +# else + void incr_refcount () {} +# endif + static void free_string(charT *, size_t len); + // Deallocate data section of a leaf. + // This shouldn't be a member function. + // But its hard to do anything else at the + // moment, because it's templatized w.r.t. + // an allocator. + // Does nothing if __GC is defined. +# ifndef __GC + void free_c_string(); + void free_tree(); + // Deallocate t. Assumes t is not 0. + void unref_nonnil() + { + if (0 == decr_refcount()) free_tree(); + } + void ref_nonnil() + { + incr_refcount(); + } + static void unref(__rope_RopeBase* t) + { + if (0 != t) { + t -> unref_nonnil(); + } + } + static void ref(__rope_RopeBase* t) + { + if (0 != t) t -> incr_refcount(); + } + static void free_if_unref(__rope_RopeBase* t) + { + if (0 != t && 0 == t -> refcount) t -> free_tree(); + } +# else /* __GC */ + void unref_nonnil() {} + void ref_nonnil() {} + static void unref(__rope_RopeBase* t) {} + static void ref(__rope_RopeBase* t) {} + static void fn_finalization_proc(void * tree, void *); + static void free_if_unref(__rope_RopeBase* t) {} +# endif + + // The data fields of leaves are allocated with some + // extra space, to accomodate future growth and for basic + // character types, to hold a trailing eos character. + enum { alloc_granularity = 8 }; + static size_t rounded_up_size(size_t n) { + size_t size_with_eos; + + if (__is_basic_char_type((charT *)0)) { + size_with_eos = n + 1; + } else { + size_with_eos = n; + } +# ifdef __GC + return size_with_eos; +# else + // Allow slop for in-place expansion. + return (size_with_eos + alloc_granularity-1) + &~ (alloc_granularity-1); +# endif + } +}; + +template<class charT, class Alloc> +struct __rope_RopeLeaf : public __rope_RopeBase<charT,Alloc> { + public: // Apparently needed by VC++ + __GC_CONST charT* data; /* Not necessarily 0 terminated. */ + /* The allocated size is */ + /* rounded_up_size(size), except */ + /* in the GC case, in which it */ + /* doesn't matter. */ +}; + +template<class charT, class Alloc> +struct __rope_RopeConcatenation : public __rope_RopeBase<charT,Alloc> { + public: + __rope_RopeBase<charT,Alloc>* left; + __rope_RopeBase<charT,Alloc>* right; +}; + +template<class charT, class Alloc> +struct __rope_RopeFunction : public __rope_RopeBase<charT,Alloc> { + public: + char_producer<charT>* fn; +# ifndef __GC + bool 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. +# 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<class charT, class Alloc> +struct __rope_RopeSubstring: public __rope_RopeFunction<charT,Alloc>, + public char_producer<charT> { + public: + __rope_RopeBase<charT,Alloc> * base; // not 0 + size_t start; + virtual ~__rope_RopeSubstring() {} + virtual void operator()(size_t start_pos, size_t req_len, + charT *buffer) { + switch(base -> tag) { + case function: + case substringfn: + { + char_producer<charT> *fn = + ((__rope_RopeFunction<charT,Alloc> *)base) -> fn; + __stl_assert(start_pos + req_len <= size); + __stl_assert(start + size <= base -> size); + (*fn)(start_pos + start, req_len, buffer); + } + break; + case leaf: + { + __GC_CONST charT * s = + ((__rope_RopeLeaf<charT,Alloc> *)base) -> data; + uninitialized_copy_n(s + start_pos + start, req_len, + buffer); + } + break; + default: + __stl_assert(false); + } + } + __rope_RopeSubstring(__rope_RopeBase<charT,Alloc> * b, size_t s, size_t l) : + base(b), start(s) { +# ifndef __GC + refcount = 1; + init_refcount_lock(); + base -> ref_nonnil(); +# endif + size = l; + tag = substringfn; + depth = 0; + c_string = 0; + fn = this; + } +}; + + +// Self-destructing pointers to RopeBase. +// These are not conventional smart pointers. Their +// only purpose in life is to ensure that unref is called +// on the pointer either at normal exit or if an exception +// is raised. It is the caller's responsibility to +// adjust reference counts when these pointers are initialized +// or assigned to. (This convention significantly reduces +// the number of potentially expensive reference count +// updates.) +#ifndef __GC + template<class charT, class Alloc> + struct __rope_self_destruct_ptr { + __rope_RopeBase<charT,Alloc> * ptr; + ~__rope_self_destruct_ptr() { __rope_RopeBase<charT,Alloc>::unref(ptr); } +# ifdef __STL_USE_EXCEPTIONS + __rope_self_destruct_ptr() : ptr(0) {}; +# else + __rope_self_destruct_ptr() {}; +# endif + __rope_self_destruct_ptr(__rope_RopeBase<charT,Alloc> * p) : ptr(p) {} + __rope_RopeBase<charT,Alloc> & operator*() { return *ptr; } + __rope_RopeBase<charT,Alloc> * operator->() { return ptr; } + operator __rope_RopeBase<charT,Alloc> *() { return ptr; } + __rope_self_destruct_ptr & operator= (__rope_RopeBase<charT,Alloc> * x) + { ptr = x; return *this; } + }; +#endif + +// Dereferencing a nonconst iterator has to return something +// that behaves almost like a reference. It's not possible to +// return an actual reference since assignment requires extra +// work. And we would get into the same problems as with the +// CD2 version of basic_string. +template<class charT, class Alloc> +class __rope_charT_ref_proxy { + friend class rope<charT,Alloc>; + friend class __rope_iterator<charT,Alloc>; + friend class __rope_charT_ptr_proxy<charT,Alloc>; +# ifdef __GC + typedef __rope_RopeBase<charT,Alloc> * self_destruct_ptr; +# else + typedef __rope_self_destruct_ptr<charT,Alloc> self_destruct_ptr; +# endif + typedef __rope_RopeBase<charT,Alloc> RopeBase; + typedef rope<charT,Alloc> my_rope; + size_t pos; + charT current; + bool current_valid; + my_rope * root; // The whole rope. + public: + __rope_charT_ref_proxy(my_rope * r, size_t p) : + pos(p), root(r), current_valid(false) {} + __rope_charT_ref_proxy(my_rope * r, size_t p, + charT c) : + pos(p), root(r), current(c), current_valid(true) {} + operator charT () const; + __rope_charT_ref_proxy& operator= (charT c); + __rope_charT_ptr_proxy<charT,Alloc> operator& () const; + __rope_charT_ref_proxy& operator= (const __rope_charT_ref_proxy& c) { + return operator=((charT)c); + } +}; + +template<class charT, class Alloc> +class __rope_charT_ptr_proxy { + friend class __rope_charT_ref_proxy<charT,Alloc>; + size_t pos; + charT current; + bool current_valid; + rope<charT,Alloc> * root; // The whole rope. + public: + __rope_charT_ptr_proxy(const __rope_charT_ref_proxy<charT,Alloc> & x) : + pos(x.pos), root(x.root), current_valid(x.current_valid), + current(x.current) {} + __rope_charT_ptr_proxy(const __rope_charT_ptr_proxy & x) : + pos(x.pos), root(x.root), current_valid(x.current_valid), + current(x.current) {} + __rope_charT_ptr_proxy() {} + __rope_charT_ptr_proxy(charT * x) : root(0), pos(0) { + __stl_assert(0 == x); + } + __rope_charT_ptr_proxy& operator= (const __rope_charT_ptr_proxy& x) { + pos = x.pos; + current = x.current; + current_valid = x.current_valid; + root = x.root; + return *this; + } + friend bool operator== __STL_NULL_TMPL_ARGS + (const __rope_charT_ptr_proxy<charT,Alloc> & x, + const __rope_charT_ptr_proxy<charT,Alloc> & y); + __rope_charT_ref_proxy<charT,Alloc> operator *() const { + if (current_valid) { + return __rope_charT_ref_proxy<charT,Alloc>(root, pos, current); + } else { + return __rope_charT_ref_proxy<charT,Alloc>(root, 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 charT, class Alloc> +class __rope_iterator_base: + public random_access_iterator<charT, ptrdiff_t> { + friend class rope<charT, Alloc>; + public: + typedef __rope_RopeBase<charT,Alloc> RopeBase; + // Borland doesnt want this to be protected. + protected: + enum { path_cache_len = 4 }; // Must be <= 9. + enum { iterator_buf_len = 15 }; + size_t current_pos; + RopeBase * root; // The whole rope. + size_t leaf_pos; // Starting position for current leaf + __GC_CONST charT * buf_start; + // Buffer possibly + // containing current char. + __GC_CONST charT * buf_ptr; + // Pointer to current char in buffer. + // != 0 ==> buffer valid. + __GC_CONST charT * buf_end; + // One past last valid char in buffer. + // What follows is the path cache. We go out of our + // way to make this compact. + // Path_end contains the bottom section of the path from + // the root to the current leaf. + const RopeBase * path_end[path_cache_len]; + int leaf_index; // Last valid pos in path_end; + // path_end[0] ... path_end[leaf_index-1] + // point to concatenation nodes. + unsigned char path_directions; + // (path_directions >> i) & 1 is 1 + // iff we got from path_end[leaf_index - i - 1] + // to path_end[leaf_index - i] by going to the + // right. Assumes path_cache_len <= 9. + charT tmp_buf[iterator_buf_len]; + // Short buffer for surrounding chars. + // This is useful primarily for + // RopeFunctions. We put the buffer + // here to avoid locking in the + // multithreaded case. + // The cached path is generally assumed to be valid + // only if the buffer is valid. + static void setbuf(__rope_iterator_base &x); + // Set buffer contents given + // path cache. + static void setcache(__rope_iterator_base &x); + // Set buffer contents and + // path cache. + static void setcache_for_incr(__rope_iterator_base &x); + // As above, but assumes path + // cache is valid for previous posn. + __rope_iterator_base() {} + __rope_iterator_base(RopeBase * root, size_t pos): + root(root), current_pos(pos), buf_ptr(0) {} + __rope_iterator_base(const __rope_iterator_base& x) { + if (0 != x.buf_ptr) { + *this = x; + } else { + current_pos = x.current_pos; + root = x.root; + buf_ptr = 0; + } + } + void incr(size_t n); + void decr(size_t n); + public: + size_t index() const { return current_pos; } +}; + +template<class charT, class Alloc> class __rope_iterator; + +template<class charT, class Alloc> +class __rope_const_iterator : public __rope_iterator_base<charT,Alloc> { + friend class rope<charT,Alloc>; + protected: + __rope_const_iterator(const RopeBase * root, size_t pos): + __rope_iterator_base<charT,Alloc>( + const_cast<RopeBase *>(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.tree_ptr, pos) {} + __rope_const_iterator& operator= (const __rope_const_iterator & x) { + if (0 != x.buf_ptr) { + *this = x; + } else { + current_pos = x.current_pos; + root = x.root; + buf_ptr = 0; + } + return(*this); + } + reference operator*() { + if (0 == buf_ptr) setcache(*this); + return *buf_ptr; + } + __rope_const_iterator& operator++() { + __GC_CONST charT * next; + if (0 != buf_ptr && (next = buf_ptr + 1) < buf_end) { + buf_ptr = next; + ++current_pos; + } else { + incr(1); + } + return *this; + } + __rope_const_iterator& operator+=(ptrdiff_t n) { + if (n >= 0) { + incr(n); + } else { + decr(-n); + } + return *this; + } + __rope_const_iterator& operator--() { + decr(1); + return *this; + } + __rope_const_iterator& operator-=(ptrdiff_t n) { + if (n >= 0) { + decr(n); + } else { + incr(-n); + } + return *this; + } + __rope_const_iterator operator++(int) { + size_t old_pos = current_pos; + incr(1); + return __rope_const_iterator<charT,Alloc>(root, old_pos); + // This makes a subsequent dereference expensive. + // Perhaps we should instead copy the iterator + // if it has a valid cache? + } + __rope_const_iterator operator--(int) { + size_t old_pos = current_pos; + decr(1); + return __rope_const_iterator<charT,Alloc>(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>::fetch(root, 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 charT, class Alloc> +class __rope_iterator : public __rope_iterator_base<charT,Alloc> { + friend class rope<charT,Alloc>; + protected: + rope<charT,Alloc> * 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 -> tree_ptr, pos), + root_rope(r) { + RopeBase::ref(root); + } + void check(); + public: + typedef __rope_charT_ref_proxy<charT,Alloc> reference; + typedef __rope_charT_ref_proxy<charT,Alloc>* pointer; + + public: + rope<charT,Alloc>& container() { return *root_rope; } + __rope_iterator() { + root = 0; // Needed for reference counting. + }; + __rope_iterator(const __rope_iterator & x) : + __rope_iterator_base<charT,Alloc>(x) { + root_rope = x.root_rope; + RopeBase::ref(root); + } + __rope_iterator(rope<charT,Alloc>& r, size_t pos); + ~__rope_iterator() { + RopeBase::unref(root); + } + __rope_iterator& operator= (const __rope_iterator & x) { + RopeBase *old = root; + + RopeBase::ref(x.root); + if (0 != x.buf_ptr) { + *this = x; + } else { + current_pos = x.current_pos; + root = x.root; + root_rope = x.root_rope; + buf_ptr = 0; + } + RopeBase::unref(old); + return(*this); + } + reference operator*() { + check(); + if (0 == buf_ptr) { + return __rope_charT_ref_proxy<charT,Alloc>(root_rope, current_pos); + } else { + return __rope_charT_ref_proxy<charT,Alloc>(root_rope, + current_pos, *buf_ptr); + } + } + __rope_iterator& operator++() { + incr(1); + return *this; + } + __rope_iterator& operator+=(difference_type n) { + if (n >= 0) { + incr(n); + } else { + decr(-n); + } + return *this; + } + __rope_iterator& operator--() { + decr(1); + return *this; + } + __rope_iterator& operator-=(difference_type n) { + if (n >= 0) { + decr(n); + } else { + incr(-n); + } + return *this; + } + __rope_iterator operator++(int) { + size_t old_pos = current_pos; + incr(1); + return __rope_iterator<charT,Alloc>(root_rope, old_pos); + } + __rope_iterator operator--(int) { + size_t old_pos = current_pos; + decr(1); + return __rope_iterator<charT,Alloc>(root_rope, old_pos); + } + reference operator[](ptrdiff_t n) { + return __rope_charT_ref_proxy<charT,Alloc>(root_rope, 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 + +template <class charT, class Alloc> +class rope { + 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_charT_ref_proxy<charT,Alloc> reference; + typedef __rope_charT_ptr_proxy<charT,Alloc> pointer; + + friend class __rope_iterator<charT,Alloc>; + friend class __rope_const_iterator<charT,Alloc>; + friend struct __rope_RopeBase<charT,Alloc>; + friend class __rope_iterator_base<charT,Alloc>; + friend class __rope_charT_ptr_proxy<charT,Alloc>; + friend class __rope_charT_ref_proxy<charT,Alloc>; + friend struct __rope_RopeSubstring<charT,Alloc>; + + protected: + typedef __GC_CONST charT * cstrptr; +# ifdef __STL_SGI_THREADS + static cstrptr 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 atomic_swap(cstrptr *p, cstrptr q) { + return (cstrptr) InterlockedExchange((LPLONG)p, (LONG)q); + } +# elif defined(__STL_PTHREADS) + // This should be portable, but performance is expected + // to be quite awful. This really needs platform specific + // code. + static pthread_mutex_t swap_lock; + static cstrptr atomic_swap(cstrptr *p, cstrptr q) { + pthread_mutex_lock(&swap_lock); + cstrptr result = *p; + *p = q; + pthread_mutex_unlock(&swap_lock); + return result; + } +# else + static cstrptr atomic_swap(cstrptr *p, cstrptr q) { + cstrptr result = *p; + *p = q; + return result; + } +# endif + + static charT empty_c_str[1]; + + typedef simple_alloc<charT, Alloc> DataAlloc; + typedef simple_alloc<__rope_RopeConcatenation<charT,Alloc>, Alloc> CAlloc; + typedef simple_alloc<__rope_RopeLeaf<charT,Alloc>, Alloc> LAlloc; + typedef simple_alloc<__rope_RopeFunction<charT,Alloc>, Alloc> FAlloc; + typedef simple_alloc<__rope_RopeSubstring<charT,Alloc>, Alloc> SAlloc; + static bool is0(charT c) { return c == __eos((charT *)0); } + enum { copy_max = 23 }; + // For strings shorter than copy_max, we copy to + // concatenate. + + typedef __rope_RopeBase<charT,Alloc> RopeBase; + typedef __rope_RopeConcatenation<charT,Alloc> RopeConcatenation; + typedef __rope_RopeLeaf<charT,Alloc> RopeLeaf; + typedef __rope_RopeFunction<charT,Alloc> RopeFunction; + typedef __rope_RopeSubstring<charT,Alloc> RopeSubstring; + + // The only data member of a rope: + RopeBase *tree_ptr; + + // Retrieve a character at the indicated position. + static charT fetch(RopeBase * r, size_type pos); + +# ifndef __GC + // Obtain a pointer to the character at the indicated position. + // The pointer can be used to change the character. + // If such a pointer cannot be produced, as is frequently the + // case, 0 is returned instead. + // (Returns nonzero only if all nodes in the path have a refcount + // of 1.) + static charT * fetch_ptr(RopeBase * r, size_type pos); +# endif + + static bool apply_to_pieces( + // should be template parameter + __rope_char_consumer<charT>& c, + const RopeBase * r, + size_t begin, size_t end); + // begin and end are assumed to be in range. + +# ifndef __GC + static void unref(RopeBase* t) + { + RopeBase::unref(t); + } + static void ref(RopeBase* t) + { + RopeBase::ref(t); + } +# else /* __GC */ + static void unref(RopeBase* t) {} + static void ref(RopeBase* t) {} +# endif + + +# ifdef __GC + typedef __rope_RopeBase<charT,Alloc> * self_destruct_ptr; +# else + typedef __rope_self_destruct_ptr<charT,Alloc> self_destruct_ptr; +# endif + + // Result is counted in refcount. + static RopeBase * substring(RopeBase * base, + size_t start, size_t endp1); + + static RopeBase * concat_char_iter(RopeBase * r, + const charT *iter, size_t slen); + // Concatenate rope and char ptr, copying s. + // Should really take an arbitrary iterator. + // Result is counted in refcount. + static RopeBase * destr_concat_char_iter(RopeBase * r, + const charT *iter, size_t slen) + // As above, but one reference to r is about to be + // destroyed. Thus the pieces may be recycled if all + // relevent reference counts are 1. +# ifdef __GC + // We can't really do anything since refcounts are unavailable. + { return concat_char_iter(r, iter, slen); } +# else + ; +# endif + + static RopeBase * concat(RopeBase *left, RopeBase *right); + // General concatenation on RopeBase. Result + // has refcount of 1. Adjusts argument refcounts. + + public: + void apply_to_pieces( size_t begin, size_t end, + __rope_char_consumer<charT>& c) const { + apply_to_pieces(c, tree_ptr, begin, end); + } + + + protected: + + static size_t rounded_up_size(size_t n) { + return RopeBase::rounded_up_size(n); + } + + static size_t allocated_capacity(size_t n) { + if (__is_basic_char_type((charT *)0)) { + return rounded_up_size(n) - 1; + } else { + return rounded_up_size(n); + } + } + + // s should really be an arbitrary input iterator. + // Adds a trailing NULL for basic char types. + static charT * alloc_copy(const charT *s, size_t size) + { + charT * result = DataAlloc::allocate(rounded_up_size(size)); + + uninitialized_copy_n(s, size, result); + __cond_store_eos(result[size]); + return(result); + } + + // Basic constructors for rope tree nodes. + // These return tree nodes with a 0 reference count. + static RopeLeaf * RopeLeaf_from_char_ptr(__GC_CONST charT *s, + size_t size); + // Takes ownership of its argument. + // Result has refcount 1. + // In the nonGC, basic_char_type case it assumes that s + // is eos-terminated. + // In the nonGC case, it was allocated from Alloc with + // rounded_up_size(size). + + static RopeLeaf * RopeLeaf_from_unowned_char_ptr(const charT *s, + size_t size) { + charT * buf = alloc_copy(s, size); + __STL_TRY { + return RopeLeaf_from_char_ptr(buf, size); + } + __STL_UNWIND(RopeBase::free_string(buf, size)) + } + + + // Concatenation of nonempty strings. + // Always builds a concatenation node. + // Rebalances if the result is too deep. + // Result has refcount 1. + // Does not increment left and right ref counts even though + // they are referenced. + static RopeBase * tree_concat(RopeBase * left, RopeBase * right); + + // Result has refcount 1. + // If delete_fn is true, then fn is deleted when the rope + // becomes inaccessible. + static RopeFunction * RopeFunction_from_fn + (char_producer<charT> *fn, size_t size, + bool delete_fn); + + // Concatenation helper functions + static RopeLeaf * leaf_concat_char_iter + (RopeLeaf * r, const charT * iter, size_t slen); + // Concatenate by copying leaf. + // should take an arbitrary iterator + // result has refcount 1. +# ifndef __GC + static RopeLeaf * destr_leaf_concat_char_iter + (RopeLeaf * r, const charT * iter, size_t slen); + // A version that potentially clobbers r if r -> refcount == 1. +# endif + + // A helper function for exponentiating strings. + // This uses a nonstandard refcount convention. + // The result has refcount 0. + struct concat_fn; + friend struct rope<charT,Alloc>::concat_fn; + + struct concat_fn + : public binary_function<rope<charT,Alloc>, rope<charT,Alloc>, + rope<charT,Alloc> > { + rope operator() (const rope& x, const rope& y) { + return x + y; + } + }; + + friend rope identity_element(concat_fn) { return rope<charT,Alloc>(); } + + static size_t char_ptr_len(const charT * s); + // slightly generalized strlen + + rope(RopeBase *t) : tree_ptr(t) { } + + + // Copy r to the CharT buffer. + // Returns buffer + r -> size. + // Assumes that buffer is uninitialized. + static charT * flatten(RopeBase * r, charT * buffer); + + // Again, with explicit starting position and length. + // Assumes that buffer is uninitialized. + static charT * flatten(RopeBase * r, + size_t start, size_t len, + charT * buffer); + + static const unsigned long min_len[RopeBase::max_rope_depth + 1]; + + static bool is_balanced(RopeBase *r) + { return (r -> size >= min_len[r -> depth]); } + + static bool is_almost_balanced(RopeBase *r) + { return (r -> depth == 0 || + r -> size >= min_len[r -> depth - 1]); } + + static bool is_roughly_balanced(RopeBase *r) + { return (r -> depth <= 1 || + r -> size >= min_len[r -> depth - 2]); } + + // Assumes the result is not empty. + static RopeBase * concat_and_set_balanced(RopeBase *left, + RopeBase *right) + { + RopeBase * result = concat(left, right); + if (is_balanced(result)) result -> is_balanced = true; + return result; + } + + // The basic rebalancing operation. Logically copies the + // rope. The result has refcount of 1. The client will + // usually decrement the reference count of r. + // The result isd within height 2 of balanced by the above + // definition. + static RopeBase * balance(RopeBase * r); + + // Add all unbalanced subtrees to the forest of balanceed trees. + // Used only by balance. + static void add_to_forest(RopeBase *r, RopeBase **forest); + + // Add r to forest, assuming r is already balanced. + static void add_leaf_to_forest(RopeBase *r, RopeBase **forest); + + // Print to stdout, exposing structure + static void dump(RopeBase * r, int indent = 0); + + // Return -1, 0, or 1 if x < y, x == y, or x > y resp. + static int compare(const RopeBase *x, const RopeBase *y); + + public: + bool empty() const { return 0 == tree_ptr; } + + // Comparison member function. This is public only for those + // clients that need a ternary comparison. Others + // should use the comparison operators below. + int compare(const rope &y) const { + return compare(tree_ptr, y.tree_ptr); + } + + rope(const charT *s) + { + size_t len = char_ptr_len(s); + + if (0 == len) { + tree_ptr = 0; + } else { + tree_ptr = RopeLeaf_from_unowned_char_ptr(s, len); +# ifndef __GC + __stl_assert(1 == tree_ptr -> refcount); +# endif + } + } + + rope(const charT *s, size_t len) + { + if (0 == len) { + tree_ptr = 0; + } else { + tree_ptr = RopeLeaf_from_unowned_char_ptr(s, len); + } + } + + rope(const charT *s, charT *e) + { + size_t len = e - s; + + if (0 == len) { + tree_ptr = 0; + } else { + tree_ptr = RopeLeaf_from_unowned_char_ptr(s, len); + } + } + + rope(const const_iterator& s, const const_iterator& e) + { + tree_ptr = substring(s.root, s.current_pos, e.current_pos); + } + + rope(const iterator& s, const iterator& e) + { + tree_ptr = substring(s.root, s.current_pos, e.current_pos); + } + + rope(charT c) + { + charT * buf = DataAlloc::allocate(rounded_up_size(1)); + + construct(buf, c); + __STL_TRY { + tree_ptr = RopeLeaf_from_char_ptr(buf, 1); + } + __STL_UNWIND(RopeBase::free_string(buf, 1)) + } + + rope(size_t n, charT c); + + // Should really be templatized with respect to the iterator type + // and use sequence_buffer. (It should perhaps use sequence_buffer + // even now.) + rope(const charT *i, const charT *j) + { + if (i == j) { + tree_ptr = 0; + } else { + size_t len = j - i; + tree_ptr = RopeLeaf_from_unowned_char_ptr(i, len); + } + } + + rope() + { + tree_ptr = 0; + } + + // Construct a rope from a function that can compute its members + rope(char_producer<charT> *fn, size_t len, bool delete_fn) + { + tree_ptr = RopeFunction_from_fn(fn, len, delete_fn); + } + + rope(const rope &x) + { + tree_ptr = x.tree_ptr; + ref(tree_ptr); + } + + ~rope() + { + unref(tree_ptr); + } + + rope& operator=(const rope& x) + { + RopeBase *old = tree_ptr; + tree_ptr = x.tree_ptr; + ref(tree_ptr); + unref(old); + return(*this); + } + + void push_back(charT x) + { + RopeBase *old = tree_ptr; + tree_ptr = concat_char_iter(tree_ptr, &x, 1); + unref(old); + } + + void pop_back() + { + RopeBase *old = tree_ptr; + tree_ptr = substring(tree_ptr, 0, tree_ptr -> size - 1); + unref(old); + } + + charT back() const + { + return fetch(tree_ptr, tree_ptr -> size - 1); + } + + void push_front(charT x) + { + RopeBase *old = tree_ptr; + RopeBase *left; + + left = RopeLeaf_from_unowned_char_ptr(&x, 1); + __STL_TRY { + tree_ptr = concat(left, tree_ptr); + unref(old); + unref(left); + } + __STL_UNWIND(unref(left)) + } + + void pop_front() + { + RopeBase *old = tree_ptr; + tree_ptr = substring(tree_ptr, 1, tree_ptr -> size); + unref(old); + } + + charT front() const + { + return fetch(tree_ptr, 0); + } + + void balance() + { + RopeBase *old = tree_ptr; + tree_ptr = balance(tree_ptr); + unref(old); + } + + void copy(charT * buffer) const { + destroy(buffer, buffer + size()); + flatten(tree_ptr, buffer); + } + + // This is the copy function from the standard, but + // with the arguments reordered to make it consistent with the + // rest of the interface. + // Note that this guaranteed not to compile if the draft standard + // order is assumed. + size_type copy(size_type pos, size_type n, charT *buffer) const { + size_t sz = size(); + size_t len = (pos + n > sz? sz - pos : n); + + destroy(buffer, buffer + len); + flatten(tree_ptr, pos, len, buffer); + return len; + } + + // Print to stdout, exposing structure. May be useful for + // performance debugging. + void dump() { + dump(tree_ptr); + } + + // Convert to 0 terminated string in new allocated memory. + // Embedded 0s in the input do not terminate the copy. + const charT * c_str() const; + + // As above, but lso use the flattened representation as the + // the new rope representation. + const charT * replace_with_c_str(); + + // Reclaim memory for the c_str generated flattened string. + // Intentionally undocumented, since it's hard to say when this + // is safe for multiple threads. + void delete_c_str () { + if (0 == tree_ptr) return; + if (RopeBase::leaf == tree_ptr -> tag + && ((RopeLeaf *)tree_ptr) -> data == tree_ptr -> c_string) { + // Representation shared + return; + } +# ifndef __GC + tree_ptr -> free_c_string(); +# endif + tree_ptr -> c_string = 0; + } + + charT operator[] (size_type pos) const { + return fetch(tree_ptr, pos); + } + + charT at(size_type pos) const { + // if (pos >= size()) throw out_of_range; + return (*this)[pos]; + } + + const_iterator begin() const { + return(const_iterator(tree_ptr, 0)); + } + + // An easy way to get a const iterator from a non-const container. + const_iterator const_begin() const { + return(const_iterator(tree_ptr, 0)); + } + + const_iterator end() const { + return(const_iterator(tree_ptr, size())); + } + + const_iterator const_end() const { + return(const_iterator(tree_ptr, size())); + } + + size_type size() const { + return(0 == tree_ptr? 0 : tree_ptr -> size); + } + + size_type length() const { + return size(); + } + + size_type max_size() const { + return min_len[RopeBase::max_rope_depth-1] - 1; + // Guarantees that the result can be sufficirntly + // balanced. Longer ropes will probably still work, + // but it's harder to make guarantees. + } + +# ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + typedef reverse_iterator<const_iterator> const_reverse_iterator; +# else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + typedef reverse_iterator<const_iterator, value_type, const_reference, + difference_type> 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) { + RopeBase* result = destr_concat_char_iter(tree_ptr, iter, n); + unref(tree_ptr); + tree_ptr = result; + return *this; + } + + rope& append(const charT* c_string) { + size_t len = char_ptr_len(c_string); + append(c_string, len); + return(*this); + } + + rope& append(const charT* s, const charT* e) { + RopeBase* result = + destr_concat_char_iter(tree_ptr, s, e - s); + unref(tree_ptr); + tree_ptr = result; + return *this; + } + + rope& append(const_iterator s, const_iterator e) { + __stl_assert(s.root == e.root); + self_destruct_ptr appendee(substring(s.root, s.current_pos, + e.current_pos)); + RopeBase* result = concat(tree_ptr, (RopeBase *)appendee); + unref(tree_ptr); + tree_ptr = result; + return *this; + } + + rope& append(charT c) { + RopeBase* result = destr_concat_char_iter(tree_ptr, &c, 1); + unref(tree_ptr); + tree_ptr = result; + return *this; + } + + rope& append() { return append(charT()); } + + rope& append(const rope& y) { + RopeBase* result = concat(tree_ptr, y.tree_ptr); + unref(tree_ptr); + tree_ptr = result; + return *this; + } + + rope& append(size_t n, charT c) { + rope<charT,Alloc> last(n, c); + return append(last); + } + + void swap(rope& b) { + RopeBase * tmp = tree_ptr; + tree_ptr = b.tree_ptr; + b.tree_ptr = tmp; + } + + + protected: + // Result is included in refcount. + static RopeBase * replace(RopeBase *old, size_t pos1, + size_t pos2, RopeBase *r) { + if (0 == old) { ref(r); return r; } + self_destruct_ptr left(substring(old, 0, pos1)); + self_destruct_ptr right(substring(old, pos2, old -> size)); + RopeBase * result; + + if (0 == r) { + result = concat(left, right); + } else { + self_destruct_ptr left_result(concat(left, r)); + result = concat(left_result, right); + } + return result; + } + + public: + void insert(size_t p, const rope& r) { + RopeBase * result = replace(tree_ptr, p, p, + r.tree_ptr); + unref(tree_ptr); + tree_ptr = result; + } + + void insert(size_t p, size_t n, charT c) { + rope<charT,Alloc> r(n,c); + insert(p, r); + } + + void insert(size_t p, const charT * i, size_t n) { + self_destruct_ptr left(substring(tree_ptr, 0, p)); + self_destruct_ptr right(substring(tree_ptr, p, size())); + self_destruct_ptr left_result(concat_char_iter(left, i, n)); + RopeBase * result = + concat(left_result, right); + unref(tree_ptr); + tree_ptr = result; + } + + void insert(size_t p, const charT * c_string) { + insert(p, c_string, char_ptr_len(c_string)); + } + + void insert(size_t p, charT c) { + insert(p, &c, 1); + } + + void insert(size_t p) { + charT c = charT(); + insert(p, &c, 1); + } + + void insert(size_t p, const charT *i, const charT *j) { + rope r(i, j); + insert(p, r); + } + + void insert(size_t p, const const_iterator& i, + const const_iterator& j) { + rope r(i, j); + insert(p, r); + } + + void insert(size_t p, const iterator& i, + const iterator& j) { + rope r(i, j); + insert(p, r); + } + + // (position, length) versions of replace operations: + + void replace(size_t p, size_t n, const rope& r) { + RopeBase * result = replace(tree_ptr, p, p + n, + r.tree_ptr); + unref(tree_ptr); + tree_ptr = result; + } + + void replace(size_t p, size_t n, const charT *i, size_t i_len) { + rope r(i, i_len); + replace(p, n, r); + } + + void replace(size_t p, size_t n, charT c) { + rope r(c); + replace(p, n, r); + } + + void replace(size_t p, size_t n, const charT *c_string) { + rope r(c_string); + replace(p, n, r); + } + + void replace(size_t p, size_t n, const charT *i, const charT *j) { + rope r(i, j); + replace(p, n, r); + } + + void replace(size_t p, size_t n, + const const_iterator& i, const const_iterator& j) { + rope r(i, j); + replace(p, n, r); + } + + void replace(size_t p, size_t n, + const iterator& i, const iterator& j) { + rope r(i, j); + replace(p, n, r); + } + + // Single character variants: + void replace(size_t p, charT c) { + iterator i(this, p); + *i = c; + } + + void replace(size_t p, const rope& r) { + replace(p, 1, r); + } + + void replace(size_t p, const charT *i, size_t i_len) { + replace(p, 1, i, i_len); + } + + void replace(size_t p, const charT *c_string) { + replace(p, 1, c_string); + } + + void replace(size_t p, const charT *i, const charT *j) { + replace(p, 1, i, j); + } + + void replace(size_t p, const const_iterator& i, + const const_iterator& j) { + replace(p, 1, i, j); + } + + void replace(size_t p, const iterator& i, + const iterator& j) { + replace(p, 1, i, j); + } + + // Erase, (position, size) variant. + void erase(size_t p, size_t n) { + RopeBase * result = replace(tree_ptr, p, p + n, 0); + unref(tree_ptr); + tree_ptr = result; + } + + // Erase, single character + void erase(size_t p) { + erase(p, p + 1); + } + + // Insert, iterator variants. + iterator insert(const iterator& p, const rope& r) + { insert(p.index(), r); return p; } + iterator insert(const iterator& p, size_t n, charT c) + { insert(p.index(), n, c); return p; } + iterator insert(const iterator& p, charT c) + { insert(p.index(), c); return p; } + iterator insert(const iterator& p ) + { insert(p.index()); return p; } + iterator insert(const iterator& p, const charT *c_string) + { insert(p.index(), c_string); return p; } + iterator insert(const iterator& p, const charT *i, size_t n) + { insert(p.index(), i, n); return p; } + iterator insert(const iterator& p, const charT *i, const charT *j) + { insert(p.index(), i, j); return p; } + iterator insert(const iterator& p, + const const_iterator& i, const const_iterator& j) + { insert(p.index(), i, j); return p; } + iterator insert(const iterator& p, + const iterator& i, const iterator& j) + { insert(p.index(), i, j); return p; } + + // Replace, range variants. + void replace(const iterator& p, const iterator& q, + const rope& r) + { replace(p.index(), q.index() - p.index(), r); } + void replace(const iterator& p, const iterator& q, charT c) + { replace(p.index(), q.index() - p.index(), c); } + void replace(const iterator& p, const iterator& q, + const charT * c_string) + { replace(p.index(), q.index() - p.index(), c_string); } + void replace(const iterator& p, const iterator& q, + const charT *i, size_t n) + { replace(p.index(), q.index() - p.index(), i, n); } + void replace(const iterator& p, const iterator& q, + const charT *i, const charT *j) + { replace(p.index(), q.index() - p.index(), i, j); } + void replace(const iterator& p, const iterator& q, + const const_iterator& i, const const_iterator& j) + { replace(p.index(), q.index() - p.index(), i, j); } + void replace(const iterator& p, const iterator& q, + const iterator& i, const iterator& j) + { replace(p.index(), q.index() - p.index(), i, j); } + + // Replace, iterator variants. + void replace(const iterator& p, const rope& r) + { replace(p.index(), r); } + void replace(const iterator& p, charT c) + { replace(p.index(), c); } + void replace(const iterator& p, const charT * c_string) + { replace(p.index(), c_string); } + void replace(const iterator& p, const charT *i, size_t n) + { replace(p.index(), i, n); } + void replace(const iterator& p, const charT *i, const charT *j) + { replace(p.index(), i, j); } + void replace(const iterator& p, const_iterator i, const_iterator j) + { replace(p.index(), i, j); } + void replace(const iterator& p, iterator i, iterator j) + { replace(p.index(), i, j); } + + // Iterator and range variants of erase + iterator erase(const iterator &p, const iterator &q) { + size_t p_index = p.index(); + erase(p_index, q.index() - p_index); + return iterator(this, p_index); + } + iterator erase(const iterator &p) { + size_t p_index = p.index(); + erase(p_index, 1); + return iterator(this, p_index); + } + + rope substr(size_t start, size_t len = 1) const { + return rope<charT,Alloc>( + substring(tree_ptr, start, start + len)); + } + + rope substr(iterator start, iterator end) const { + return rope<charT,Alloc>( + substring(tree_ptr, start.index(), end.index())); + } + + rope substr(iterator start) const { + size_t pos = start.index(); + return rope<charT,Alloc>( + substring(tree_ptr, pos, pos + 1)); + } + + rope substr(const_iterator start, const_iterator end) const { + // This might eventually take advantage of the cache in the + // iterator. + return rope<charT,Alloc> + (substring(tree_ptr, start.index(), end.index())); + } + + rope<charT,Alloc> substr(const_iterator start) { + size_t pos = start.index(); + return rope<charT,Alloc>(substring(tree_ptr, pos, pos + 1)); + } + + size_type find(charT c, size_type pos = 0) const; + size_type find(charT *s, size_type pos = 0) const { + const_iterator result = search(const_begin() + pos, const_end(), + s, s + char_ptr_len(s)); + return result.index(); + } + + iterator mutable_begin() { + return(iterator(this, 0)); + } + + iterator mutable_end() { + return(iterator(this, size())); + } + +# ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + typedef reverse_iterator<iterator> reverse_iterator; +# else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + typedef reverse_iterator<iterator, value_type, reference, + difference_type> 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 charT_ref_proxy(this, pos); + } + + reference at(size_type pos) { + // if (pos >= size()) throw out_of_range; + return (*this)[pos]; + } + + void resize(size_type n, charT c) {} + void resize(size_type n) {} + void reserve(size_type res_arg = 0) {} + size_type capacity() const { + return max_size(); + } + + // Stuff below this line is dangerous because it's error prone. + // I would really like to get rid of it. + // copy function with funny arg ordering. + size_type copy(charT *buffer, size_type n, size_type pos = 0) + const { + return copy(pos, n, buffer); + } + + iterator end() { return mutable_end(); } + + iterator begin() { return mutable_begin(); } + + reverse_iterator rend() { return mutable_rend(); } + + reverse_iterator rbegin() { return mutable_rbegin(); } + +# else + + const_iterator end() { return const_end(); } + + const_iterator begin() { return const_begin(); } + + const_reverse_iterator rend() { return const_rend(); } + + const_reverse_iterator rbegin() { return const_rbegin(); } + +# endif + +}; + +template <class charT, class Alloc> +inline bool operator== (const __rope_const_iterator<charT,Alloc> & x, + const __rope_const_iterator<charT,Alloc> & y) { + return (x.current_pos == y.current_pos && x.root == y.root); +} + +template <class charT, class Alloc> +inline bool operator< (const __rope_const_iterator<charT,Alloc> & x, + const __rope_const_iterator<charT,Alloc> & y) { + return (x.current_pos < y.current_pos); +} + +template <class charT, class Alloc> +inline ptrdiff_t operator-(const __rope_const_iterator<charT,Alloc> & x, + const __rope_const_iterator<charT,Alloc> & y) { + return x.current_pos - y.current_pos; +} + +template <class charT, class Alloc> +inline __rope_const_iterator<charT,Alloc> +operator-(const __rope_const_iterator<charT,Alloc> & x, + ptrdiff_t n) { + return __rope_const_iterator<charT,Alloc>(x.root, x.current_pos - n); +} + +template <class charT, class Alloc> +inline __rope_const_iterator<charT,Alloc> +operator+(const __rope_const_iterator<charT,Alloc> & x, + ptrdiff_t n) { + return __rope_const_iterator<charT,Alloc>(x.root, x.current_pos + n); +} + +template <class charT, class Alloc> +inline __rope_const_iterator<charT,Alloc> +operator+(ptrdiff_t n, + const __rope_const_iterator<charT,Alloc> & x) { + return __rope_const_iterator<charT,Alloc>(x.root, x.current_pos + n); +} + +template <class charT, class Alloc> +inline bool operator== (const __rope_iterator<charT,Alloc> & x, + const __rope_iterator<charT,Alloc> & y) { + return (x.current_pos == y.current_pos && x.root_rope == y.root_rope); +} + +template <class charT, class Alloc> +inline bool operator< (const __rope_iterator<charT,Alloc> & x, + const __rope_iterator<charT,Alloc> & y) { + return (x.current_pos < y.current_pos); +} + +template <class charT, class Alloc> +inline ptrdiff_t operator-(const __rope_iterator<charT,Alloc> & x, + const __rope_iterator<charT,Alloc> & y) { + return x.current_pos - y.current_pos; +} + +template <class charT, class Alloc> +inline __rope_iterator<charT,Alloc> +operator-(const __rope_iterator<charT,Alloc> & x, + ptrdiff_t n) { + return __rope_iterator<charT,Alloc>(x.root_rope, x.current_pos - n); +} + +template <class charT, class Alloc> +inline __rope_iterator<charT,Alloc> +operator+(const __rope_iterator<charT,Alloc> & x, + ptrdiff_t n) { + return __rope_iterator<charT,Alloc>(x.root_rope, x.current_pos + n); +} + +template <class charT, class Alloc> +inline __rope_iterator<charT,Alloc> +operator+(ptrdiff_t n, + const __rope_iterator<charT,Alloc> & x) { + return __rope_iterator<charT,Alloc>(x.root_rope, x.current_pos + n); +} + +template <class charT, class Alloc> +inline +rope<charT,Alloc> +operator+ (const rope<charT,Alloc> &left, + const rope<charT,Alloc> &right) +{ + return rope<charT,Alloc> + (rope<charT,Alloc>::concat(left.tree_ptr, right.tree_ptr)); + // Inlining this should make it possible to keep left and + // right in registers. +} + +template <class charT, class Alloc> +inline +rope<charT,Alloc>& +operator+= (rope<charT,Alloc> &left, + const rope<charT,Alloc> &right) +{ + left.append(right); + return left; +} + +template <class charT, class Alloc> +inline +rope<charT,Alloc> +operator+ (const rope<charT,Alloc> &left, + const charT* right) { + size_t rlen = rope<charT,Alloc>::char_ptr_len(right); + return rope<charT,Alloc> + (rope<charT,Alloc>::concat_char_iter(left.tree_ptr, right, rlen)); +} + +template <class charT, class Alloc> +inline +rope<charT,Alloc>& +operator+= (rope<charT,Alloc> &left, + const charT* right) { + left.append(right); + return left; +} + +template <class charT, class Alloc> +inline +rope<charT,Alloc> +operator+ (const rope<charT,Alloc> &left, charT right) { + return rope<charT,Alloc> + (rope<charT,Alloc>::concat_char_iter(left.tree_ptr, &right, 1)); +} + +template <class charT, class Alloc> +inline +rope<charT,Alloc>& +operator+= (rope<charT,Alloc> &left, charT right) { + left.append(right); + return left; +} + +template <class charT, class Alloc> +bool +operator< (const rope<charT,Alloc> &left, const rope<charT,Alloc> &right) { + return left.compare(right) < 0; +} + +template <class charT, class Alloc> +bool +operator== (const rope<charT,Alloc> &left, const rope<charT,Alloc> &right) { + return left.compare(right) == 0; +} + +template <class charT, class Alloc> +inline bool operator== (const __rope_charT_ptr_proxy<charT,Alloc> & x, + const __rope_charT_ptr_proxy<charT,Alloc> & y) { + return (x.pos == y.pos && x.root == y.root); +} + +template<class charT, class Alloc> +ostream& operator<< (ostream& o, const rope<charT, Alloc>& r); + +typedef rope<char, __ALLOC> crope; +typedef rope<wchar_t, __ALLOC> 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 <class charT, class Alloc> +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<crope> +{ + size_t operator()(const crope& str) const + { + size_t sz = str.size(); + + if (0 == sz) return 0; + return 13*str[0] + 5*str[sz - 1] + sz; + } +}; + + +__STL_TEMPLATE_NULL struct hash<wrope> +{ + size_t operator()(const wrope& str) const + { + size_t sz = str.size(); + + if (0 == sz) return 0; + return 13*str[0] + 5*str[sz - 1] + sz; + } +}; + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#endif + +__STL_END_NAMESPACE + +# include <ropeimpl.h> +# endif /* __SGI_STL_INTERNAL_ROPE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/stl_set.h b/contrib/libstdc++/stl/stl_set.h new file mode 100644 index 0000000..9ffeaa7 --- /dev/null +++ b/contrib/libstdc++/stl/stl_set.h @@ -0,0 +1,198 @@ +/* + * + * 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 +#endif + +#ifndef __STL_LIMITED_DEFAULT_TEMPLATES +template <class Key, class Compare = less<Key>, class Alloc = alloc> +#else +template <class Key, class Compare, class Alloc = alloc> +#endif +class set { +public: + // typedefs: + + typedef Key key_type; + typedef Key value_type; + typedef Compare key_compare; + typedef Compare value_compare; +private: + typedef rb_tree<key_type, value_type, + identity<value_type>, key_compare, Alloc> rep_type; + rep_type t; // red-black tree representing set +public: + typedef 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; + + // allocation/deallocation + + set() : t(Compare()) {} + explicit set(const Compare& comp) : t(comp) {} + +#ifdef __STL_MEMBER_TEMPLATES + template <class InputIterator> + set(InputIterator first, InputIterator last) + : t(Compare()) { t.insert_unique(first, last); } + + template <class InputIterator> + set(InputIterator first, InputIterator last, const Compare& comp) + : t(comp) { t.insert_unique(first, last); } +#else + set(const value_type* first, const value_type* last) + : t(Compare()) { t.insert_unique(first, last); } + set(const value_type* first, const value_type* last, const Compare& comp) + : t(comp) { t.insert_unique(first, last); } + + set(const_iterator first, const_iterator last) + : t(Compare()) { t.insert_unique(first, last); } + set(const_iterator first, const_iterator last, const Compare& comp) + : t(comp) { t.insert_unique(first, last); } +#endif /* __STL_MEMBER_TEMPLATES */ + + set(const set<Key, Compare, Alloc>& x) : t(x.t) {} + set<Key, Compare, Alloc>& operator=(const set<Key, Compare, Alloc>& x) { + t = x.t; + return *this; + } + + // accessors: + + key_compare key_comp() const { return t.key_comp(); } + value_compare value_comp() const { return t.key_comp(); } + iterator begin() const { return t.begin(); } + iterator end() const { return t.end(); } + reverse_iterator rbegin() const { return t.rbegin(); } + reverse_iterator rend() const { return t.rend(); } + bool empty() const { return t.empty(); } + size_type size() const { return t.size(); } + size_type max_size() const { return t.max_size(); } + void swap(set<Key, Compare, Alloc>& x) { t.swap(x.t); } + + // insert/erase + typedef pair<iterator, bool> pair_iterator_bool; + pair<iterator,bool> insert(const value_type& x) { + pair<typename rep_type::iterator, bool> p = t.insert_unique(x); + return pair<iterator, bool>(p.first, p.second); + } + iterator insert(iterator position, const value_type& x) { + typedef typename rep_type::iterator rep_iterator; + return t.insert_unique((rep_iterator&)position, x); + } +#ifdef __STL_MEMBER_TEMPLATES + template <class InputIterator> + void insert(InputIterator first, InputIterator last) { + t.insert_unique(first, last); + } +#else + void insert(const_iterator first, const_iterator last) { + t.insert_unique(first, last); + } + void insert(const value_type* first, const value_type* last) { + t.insert_unique(first, last); + } +#endif /* __STL_MEMBER_TEMPLATES */ + void erase(iterator position) { + typedef typename rep_type::iterator rep_iterator; + t.erase((rep_iterator&)position); + } + size_type erase(const key_type& x) { + return t.erase(x); + } + void erase(iterator first, iterator last) { + typedef typename rep_type::iterator rep_iterator; + t.erase((rep_iterator&)first, (rep_iterator&)last); + } + void clear() { t.clear(); } + + // set operations: + + iterator find(const key_type& x) const { return t.find(x); } + size_type count(const key_type& x) const { return t.count(x); } + iterator lower_bound(const key_type& x) const { + return t.lower_bound(x); + } + iterator upper_bound(const key_type& x) const { + return t.upper_bound(x); + } + pair<iterator,iterator> equal_range(const key_type& x) const { + return t.equal_range(x); + } + friend bool operator== __STL_NULL_TMPL_ARGS (const set&, const set&); + friend bool operator< __STL_NULL_TMPL_ARGS (const set&, const set&); +}; + +template <class Key, class Compare, class Alloc> +inline bool operator==(const set<Key, Compare, Alloc>& x, + const set<Key, Compare, Alloc>& y) { + return x.t == y.t; +} + +template <class Key, class Compare, class Alloc> +inline bool operator<(const set<Key, Compare, Alloc>& x, + const set<Key, Compare, Alloc>& y) { + return x.t < y.t; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template <class Key, class Compare, class Alloc> +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 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_SET_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/stl_slist.h b/contrib/libstdc++/stl/stl_slist.h new file mode 100644 index 0000000..f31ea9e --- /dev/null +++ b/contrib/libstdc++/stl/stl_slist.h @@ -0,0 +1,740 @@ +/* + * 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 +#endif + +struct __slist_node_base +{ + __slist_node_base* next; +}; + +inline __slist_node_base* __slist_make_link(__slist_node_base* prev_node, + __slist_node_base* new_node) +{ + new_node->next = prev_node->next; + prev_node->next = new_node; + return new_node; +} + +inline __slist_node_base* __slist_previous(__slist_node_base* head, + const __slist_node_base* node) +{ + while (head && head->next != node) + head = head->next; + return head; +} + +inline const __slist_node_base* __slist_previous(const __slist_node_base* head, + const __slist_node_base* node) +{ + while (head && head->next != node) + head = head->next; + return head; +} + +inline void __slist_splice_after(__slist_node_base* pos, + __slist_node_base* before_first, + __slist_node_base* before_last) +{ + if (pos != before_first && pos != before_last) { + __slist_node_base* first = before_first->next; + __slist_node_base* after = pos->next; + before_first->next = before_last->next; + pos->next = first; + before_last->next = after; + } +} + +inline __slist_node_base* __slist_reverse(__slist_node_base* node) +{ + __slist_node_base* result = node; + node = node->next; + result->next = 0; + while(node) { + __slist_node_base* next = node->next; + node->next = result; + result = node; + node = next; + } + return result; +} + +template <class T> +struct __slist_node : public __slist_node_base +{ + T data; +}; + +struct __slist_iterator_base +{ + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef forward_iterator_tag iterator_category; + + __slist_node_base* node; + + __slist_iterator_base(__slist_node_base* x) : node(x) {} + void incr() { node = node->next; } + + bool operator==(const __slist_iterator_base& x) const { + return node == x.node; + } + bool operator!=(const __slist_iterator_base& x) const { + return node != x.node; + } +}; + +template <class T, class Ref, class Ptr> +struct __slist_iterator : public __slist_iterator_base +{ + typedef __slist_iterator<T, T&, T*> iterator; + typedef __slist_iterator<T, const T&, const T*> const_iterator; + typedef __slist_iterator<T, Ref, Ptr> self; + + typedef T value_type; + typedef Ptr pointer; + typedef Ref reference; + typedef __slist_node<T> list_node; + + __slist_iterator(list_node* x) : __slist_iterator_base(x) {} + __slist_iterator() : __slist_iterator_base(0) {} + __slist_iterator(const iterator& x) : __slist_iterator_base(x.node) {} + + reference operator*() const { return ((list_node*) node)->data; } +#ifndef __SGI_STL_NO_ARROW_OPERATOR + pointer operator->() const { return &(operator*()); } +#endif /* __SGI_STL_NO_ARROW_OPERATOR */ + + self& operator++() + { + incr(); + return *this; + } + self operator++(int) + { + self tmp = *this; + incr(); + return tmp; + } +}; + +#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION + +inline ptrdiff_t* +distance_type(const __slist_iterator_base&) +{ + return 0; +} + +inline forward_iterator_tag +iterator_category(const __slist_iterator_base&) +{ + return forward_iterator_tag(); +} + +template <class T, class Ref, class Ptr> +inline T* +value_type(const __slist_iterator<T, Ref, Ptr>&) { + return 0; +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +inline size_t __slist_size(__slist_node_base* node) +{ + size_t result = 0; + for ( ; node != 0; node = node->next) + ++result; + return result; +} + +template <class T, class Alloc = alloc> +class slist +{ +public: + typedef T value_type; + typedef value_type* pointer; + typedef 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<T, T&, T*> iterator; + typedef __slist_iterator<T, const T&, const T*> const_iterator; + +private: + typedef __slist_node<T> list_node; + typedef __slist_node_base list_node_base; + typedef __slist_iterator_base iterator_base; + typedef simple_alloc<list_node, Alloc> list_node_allocator; + + static list_node* create_node(const value_type& x) { + list_node* node = list_node_allocator::allocate(); + __STL_TRY { + construct(&node->data, x); + node->next = 0; + } + __STL_UNWIND(list_node_allocator::deallocate(node)); + return node; + } + + static void destroy_node(list_node* node) { + destroy(&node->data); + list_node_allocator::deallocate(node); + } + + void fill_initialize(size_type n, const value_type& x) { + head.next = 0; + __STL_TRY { + _insert_after_fill(&head, n, x); + } + __STL_UNWIND(clear()); + } + +#ifdef __STL_MEMBER_TEMPLATES + template <class InputIterator> + void range_initialize(InputIterator first, InputIterator last) { + head.next = 0; + __STL_TRY { + _insert_after_range(&head, first, last); + } + __STL_UNWIND(clear()); + } +#else /* __STL_MEMBER_TEMPLATES */ + void range_initialize(const value_type* first, const value_type* last) { + head.next = 0; + __STL_TRY { + _insert_after_range(&head, first, last); + } + __STL_UNWIND(clear()); + } + void range_initialize(const_iterator first, const_iterator last) { + head.next = 0; + __STL_TRY { + _insert_after_range(&head, first, last); + } + __STL_UNWIND(clear()); + } +#endif /* __STL_MEMBER_TEMPLATES */ + +private: + list_node_base head; + +public: + slist() { head.next = 0; } + + slist(size_type n, const value_type& x) { fill_initialize(n, x); } + slist(int n, const value_type& x) { fill_initialize(n, x); } + slist(long n, const value_type& x) { fill_initialize(n, x); } + explicit slist(size_type n) { fill_initialize(n, value_type()); } + +#ifdef __STL_MEMBER_TEMPLATES + template <class InputIterator> + slist(InputIterator first, InputIterator last) { + range_initialize(first, last); + } + +#else /* __STL_MEMBER_TEMPLATES */ + slist(const_iterator first, const_iterator last) { + range_initialize(first, last); + } + slist(const value_type* first, const value_type* last) { + range_initialize(first, last); + } +#endif /* __STL_MEMBER_TEMPLATES */ + + slist(const slist& L) { range_initialize(L.begin(), L.end()); } + + slist& operator= (const slist& L); + + ~slist() { clear(); } + +public: + + iterator begin() { return iterator((list_node*)head.next); } + const_iterator begin() const { return const_iterator((list_node*)head.next);} + + iterator end() { return iterator(0); } + const_iterator end() const { return const_iterator(0); } + + size_type size() const { return __slist_size(head.next); } + + size_type max_size() const { return size_type(-1); } + + bool empty() const { return head.next == 0; } + + void swap(slist& L) + { + list_node_base* tmp = head.next; + head.next = L.head.next; + L.head.next = tmp; + } + +public: + friend bool operator== __STL_NULL_TMPL_ARGS(const slist<T, Alloc>& L1, + const slist<T, Alloc>& L2); + +public: + + reference front() { return ((list_node*) head.next)->data; } + const_reference front() const { return ((list_node*) head.next)->data; } + void push_front(const value_type& x) { + __slist_make_link(&head, create_node(x)); + } + void pop_front() { + list_node* node = (list_node*) head.next; + head.next = node->next; + destroy_node(node); + } + + iterator previous(const_iterator pos) { + return iterator((list_node*) __slist_previous(&head, pos.node)); + } + const_iterator previous(const_iterator pos) const { + return const_iterator((list_node*) __slist_previous(&head, pos.node)); + } + +private: + list_node* _insert_after(list_node_base* pos, const value_type& x) { + return (list_node*) (__slist_make_link(pos, create_node(x))); + } + + void _insert_after_fill(list_node_base* pos, + size_type n, const value_type& x) { + for (size_type i = 0; i < n; ++i) + pos = __slist_make_link(pos, create_node(x)); + } + +#ifdef __STL_MEMBER_TEMPLATES + template <class InIter> + void _insert_after_range(list_node_base* pos, InIter first, InIter last) { + while (first != last) { + pos = __slist_make_link(pos, create_node(*first)); + ++first; + } + } +#else /* __STL_MEMBER_TEMPLATES */ + void _insert_after_range(list_node_base* pos, + const_iterator first, const_iterator last) { + while (first != last) { + pos = __slist_make_link(pos, create_node(*first)); + ++first; + } + } + void _insert_after_range(list_node_base* pos, + const value_type* first, const value_type* last) { + while (first != last) { + pos = __slist_make_link(pos, create_node(*first)); + ++first; + } + } +#endif /* __STL_MEMBER_TEMPLATES */ + + list_node_base* erase_after(list_node_base* pos) { + list_node* next = (list_node*) (pos->next); + list_node_base* next_next = next->next; + pos->next = next_next; + destroy_node(next); + return next_next; + } + + list_node_base* erase_after(list_node_base* before_first, + list_node_base* last_node) { + list_node* cur = (list_node*) (before_first->next); + while (cur != last_node) { + list_node* tmp = cur; + cur = (list_node*) cur->next; + destroy_node(tmp); + } + before_first->next = last_node; + return last_node; + } + + +public: + + iterator insert_after(iterator pos, const value_type& x) { + return iterator(_insert_after(pos.node, x)); + } + + iterator insert_after(iterator pos) { + return insert_after(pos, value_type()); + } + + void insert_after(iterator pos, size_type n, const value_type& x) { + _insert_after_fill(pos.node, n, x); + } + void insert_after(iterator pos, int n, const value_type& x) { + _insert_after_fill(pos.node, (size_type) n, x); + } + void insert_after(iterator pos, long n, const value_type& x) { + _insert_after_fill(pos.node, (size_type) n, x); + } + +#ifdef __STL_MEMBER_TEMPLATES + template <class InIter> + void insert_after(iterator pos, InIter first, InIter last) { + _insert_after_range(pos.node, first, last); + } +#else /* __STL_MEMBER_TEMPLATES */ + void insert_after(iterator pos, const_iterator first, const_iterator last) { + _insert_after_range(pos.node, first, last); + } + void insert_after(iterator pos, + const value_type* first, const value_type* last) { + _insert_after_range(pos.node, first, last); + } +#endif /* __STL_MEMBER_TEMPLATES */ + + iterator insert(iterator pos, const value_type& x) { + return iterator(_insert_after(__slist_previous(&head, pos.node), x)); + } + + iterator insert(iterator pos) { + return iterator(_insert_after(__slist_previous(&head, pos.node), + value_type())); + } + + void insert(iterator pos, size_type n, const value_type& x) { + _insert_after_fill(__slist_previous(&head, pos.node), n, x); + } + void insert(iterator pos, int n, const value_type& x) { + _insert_after_fill(__slist_previous(&head, pos.node), (size_type) n, x); + } + void insert(iterator pos, long n, const value_type& x) { + _insert_after_fill(__slist_previous(&head, pos.node), (size_type) n, x); + } + +#ifdef __STL_MEMBER_TEMPLATES + template <class InIter> + void insert(iterator pos, InIter first, InIter last) { + _insert_after_range(__slist_previous(&head, pos.node), first, last); + } +#else /* __STL_MEMBER_TEMPLATES */ + void insert(iterator pos, const_iterator first, const_iterator last) { + _insert_after_range(__slist_previous(&head, pos.node), first, last); + } + void insert(iterator pos, const value_type* first, const value_type* last) { + _insert_after_range(__slist_previous(&head, pos.node), first, last); + } +#endif /* __STL_MEMBER_TEMPLATES */ + + +public: + iterator erase_after(iterator pos) { + return iterator((list_node*)erase_after(pos.node)); + } + iterator erase_after(iterator before_first, iterator last) { + return iterator((list_node*)erase_after(before_first.node, last.node)); + } + + iterator erase(iterator pos) { + return (list_node*) erase_after(__slist_previous(&head, pos.node)); + } + iterator erase(iterator first, iterator last) { + return (list_node*) erase_after(__slist_previous(&head, first.node), + last.node); + } + + void resize(size_type new_size, const T& x); + void resize(size_type new_size) { resize(new_size, T()); } + void clear() { erase_after(&head, 0); } + +public: + // Moves the range [before_first + 1, before_last + 1) to *this, + // inserting it immediately after pos. This is constant time. + void splice_after(iterator pos, + iterator before_first, iterator before_last) + { + if (before_first != before_last) + __slist_splice_after(pos.node, before_first.node, before_last.node); + } + + // Moves the element that follows prev to *this, inserting it immediately + // after pos. This is constant time. + void splice_after(iterator pos, iterator prev) + { + __slist_splice_after(pos.node, prev.node, prev.node->next); + } + + + // Linear in distance(begin(), pos), and linear in L.size(). + void splice(iterator pos, slist& L) { + if (L.head.next) + __slist_splice_after(__slist_previous(&head, pos.node), + &L.head, + __slist_previous(&L.head, 0)); + } + + // Linear in distance(begin(), pos), and in distance(L.begin(), i). + void splice(iterator pos, slist& L, iterator i) { + __slist_splice_after(__slist_previous(&head, pos.node), + __slist_previous(&L.head, i.node), + i.node); + } + + // Linear in distance(begin(), pos), in distance(L.begin(), first), + // and in distance(first, last). + void splice(iterator pos, slist& L, iterator first, iterator last) + { + if (first != last) + __slist_splice_after(__slist_previous(&head, pos.node), + __slist_previous(&L.head, first.node), + __slist_previous(first.node, last.node)); + } + +public: + void reverse() { if (head.next) head.next = __slist_reverse(head.next); } + + void remove(const T& val); + void unique(); + void merge(slist& L); + void sort(); + +#ifdef __STL_MEMBER_TEMPLATES + template <class Predicate> void remove_if(Predicate pred); + template <class BinaryPredicate> void unique(BinaryPredicate pred); + template <class StrictWeakOrdering> void merge(slist&, StrictWeakOrdering); + template <class StrictWeakOrdering> void sort(StrictWeakOrdering comp); +#endif /* __STL_MEMBER_TEMPLATES */ +}; + +template <class T, class Alloc> +slist<T, Alloc>& slist<T,Alloc>::operator=(const slist<T, Alloc>& L) +{ + if (&L != this) { + list_node_base* p1 = &head; + list_node* n1 = (list_node*) head.next; + const list_node* n2 = (const list_node*) L.head.next; + while (n1 && n2) { + n1->data = n2->data; + p1 = n1; + n1 = (list_node*) n1->next; + n2 = (const list_node*) n2->next; + } + if (n2 == 0) + erase_after(p1, 0); + else + _insert_after_range(p1, + const_iterator((list_node*)n2), const_iterator(0)); + } + return *this; +} + +template <class T, class Alloc> +bool operator==(const slist<T, Alloc>& L1, const slist<T, Alloc>& L2) +{ + typedef typename slist<T,Alloc>::list_node list_node; + list_node* n1 = (list_node*) L1.head.next; + list_node* n2 = (list_node*) L2.head.next; + while (n1 && n2 && n1->data == n2->data) { + n1 = (list_node*) n1->next; + n2 = (list_node*) n2->next; + } + return n1 == 0 && n2 == 0; +} + +template <class T, class Alloc> +inline bool operator<(const slist<T, Alloc>& L1, const slist<T, Alloc>& L2) +{ + return lexicographical_compare(L1.begin(), L1.end(), L2.begin(), L2.end()); +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template <class T, class Alloc> +inline void swap(slist<T, Alloc>& x, slist<T, Alloc>& y) { + x.swap(y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + + +template <class T, class Alloc> +void slist<T, Alloc>::resize(size_type len, const T& x) +{ + list_node_base* cur = &head; + while (cur->next != 0 && len > 0) { + --len; + cur = cur->next; + } + if (cur->next) + erase_after(cur, 0); + else + _insert_after_fill(cur, len, x); +} + +template <class T, class Alloc> +void slist<T,Alloc>::remove(const T& val) +{ + list_node_base* cur = &head; + while (cur && cur->next) { + if (((list_node*) cur->next)->data == val) + erase_after(cur); + else + cur = cur->next; + } +} + +template <class T, class Alloc> +void slist<T,Alloc>::unique() +{ + list_node_base* cur = head.next; + if (cur) { + while (cur->next) { + if (((list_node*)cur)->data == ((list_node*)(cur->next))->data) + erase_after(cur); + else + cur = cur->next; + } + } +} + +template <class T, class Alloc> +void slist<T,Alloc>::merge(slist<T,Alloc>& L) +{ + list_node_base* n1 = &head; + while (n1->next && L.head.next) { + if (((list_node*) L.head.next)->data < ((list_node*) n1->next)->data) + __slist_splice_after(n1, &L.head, L.head.next); + n1 = n1->next; + } + if (L.head.next) { + n1->next = L.head.next; + L.head.next = 0; + } +} + +template <class T, class Alloc> +void slist<T,Alloc>::sort() +{ + if (head.next && head.next->next) { + slist carry; + slist counter[64]; + int fill = 0; + while (!empty()) { + __slist_splice_after(&carry.head, &head, head.next); + int i = 0; + while (i < fill && !counter[i].empty()) { + counter[i].merge(carry); + carry.swap(counter[i]); + ++i; + } + carry.swap(counter[i]); + if (i == fill) + ++fill; + } + + for (int i = 1; i < fill; ++i) + counter[i].merge(counter[i-1]); + this->swap(counter[fill-1]); + } +} + +#ifdef __STL_MEMBER_TEMPLATES + +template <class T, class Alloc> +template <class Predicate> void slist<T,Alloc>::remove_if(Predicate pred) +{ + list_node_base* cur = &head; + while (cur->next) { + if (pred(((list_node*) cur->next)->data)) + erase_after(cur); + else + cur = cur->next; + } +} + +template <class T, class Alloc> template <class BinaryPredicate> +void slist<T,Alloc>::unique(BinaryPredicate pred) +{ + list_node* cur = (list_node*) head.next; + if (cur) { + while (cur->next) { + if (pred(((list_node*)cur)->data, ((list_node*)(cur->next))->data)) + erase_after(cur); + else + cur = (list_node*) cur->next; + } + } +} + +template <class T, class Alloc> template <class StrictWeakOrdering> +void slist<T,Alloc>::merge(slist<T,Alloc>& L, StrictWeakOrdering comp) +{ + list_node_base* n1 = &head; + while (n1->next && L.head.next) { + if (comp(((list_node*) L.head.next)->data, + ((list_node*) n1->next)->data)) + __slist_splice_after(n1, &L.head, L.head.next); + n1 = n1->next; + } + if (L.head.next) { + n1->next = L.head.next; + L.head.next = 0; + } +} + +template <class T, class Alloc> template <class StrictWeakOrdering> +void slist<T,Alloc>::sort(StrictWeakOrdering comp) +{ + if (head.next && head.next->next) { + slist carry; + slist counter[64]; + int fill = 0; + while (!empty()) { + __slist_splice_after(&carry.head, &head, head.next); + int i = 0; + while (i < fill && !counter[i].empty()) { + counter[i].merge(carry, comp); + carry.swap(counter[i]); + ++i; + } + carry.swap(counter[i]); + if (i == fill) + ++fill; + } + + for (int i = 1; i < fill; ++i) + counter[i].merge(counter[i-1], comp); + this->swap(counter[fill-1]); + } +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_SLIST_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/stl_stack.h b/contrib/libstdc++/stl/stl_stack.h new file mode 100644 index 0000000..d380e81 --- /dev/null +++ b/contrib/libstdc++/stl/stl_stack.h @@ -0,0 +1,76 @@ +/* + * + * 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 <class T, class Sequence = deque<T> > +#else +template <class T, class Sequence> +#endif +class stack { + friend bool operator== __STL_NULL_TMPL_ARGS (const stack&, const stack&); + friend bool operator< __STL_NULL_TMPL_ARGS (const stack&, const stack&); +public: + typedef typename Sequence::value_type value_type; + typedef typename Sequence::size_type size_type; + typedef typename Sequence::reference reference; + typedef typename Sequence::const_reference const_reference; +protected: + Sequence c; +public: + bool empty() const { return c.empty(); } + size_type size() const { return c.size(); } + reference top() { return c.back(); } + const_reference top() const { return c.back(); } + void push(const value_type& x) { c.push_back(x); } + void pop() { c.pop_back(); } +}; + +template <class T, class Sequence> +bool operator==(const stack<T, Sequence>& x, const stack<T, Sequence>& y) { + return x.c == y.c; +} + +template <class T, class Sequence> +bool operator<(const stack<T, Sequence>& x, const stack<T, Sequence>& y) { + return x.c < y.c; +} + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_STACK_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/stl_tempbuf.h b/contrib/libstdc++/stl/stl_tempbuf.h new file mode 100644 index 0000000..9dbc238 --- /dev/null +++ b/contrib/libstdc++/stl/stl_tempbuf.h @@ -0,0 +1,123 @@ +/* + * + * 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 <class T> +pair<T*, ptrdiff_t> get_temporary_buffer(ptrdiff_t len, T*) { + if (len > ptrdiff_t(INT_MAX / sizeof(T))) + len = INT_MAX / sizeof(T); + + while (len > 0) { + T* tmp = (T*) malloc((size_t)len * sizeof(T)); + if (tmp != 0) + return pair<T*, ptrdiff_t>(tmp, len); + len /= 2; + } + + return pair<T*, ptrdiff_t>((T*)0, 0); +} + +template <class T> +void return_temporary_buffer(T* p) { + free(p); +} + +template <class ForwardIterator, + class T +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + = iterator_traits<ForwardIterator>::value_type +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + > +class temporary_buffer { +private: + ptrdiff_t original_len; + ptrdiff_t len; + T* buffer; + + void allocate_buffer() { + original_len = len; + buffer = 0; + + if (len > (ptrdiff_t)(INT_MAX / sizeof(T))) + len = INT_MAX / sizeof(T); + + while (len > 0) { + buffer = (T*) malloc(len * sizeof(T)); + if (buffer) + break; + len /= 2; + } + } + + void initialize_buffer(const T&, __true_type) {} + void initialize_buffer(const T& val, __false_type) { + uninitialized_fill_n(buffer, len, val); + } + +public: + ptrdiff_t size() const { return len; } + ptrdiff_t requested_size() const { return original_len; } + T* begin() { return buffer; } + T* end() { return buffer + len; } + + temporary_buffer(ForwardIterator first, ForwardIterator last) { + __STL_TRY { + len = 0; + distance(first, last, len); + allocate_buffer(); + if (len > 0) + initialize_buffer(*first, + typename __type_traits<T>::has_trivial_default_constructor()); + } + __STL_UNWIND(free(buffer); buffer = 0; len = 0); + } + + ~temporary_buffer() { + destroy(buffer, buffer + len); + free(buffer); + } + +private: + temporary_buffer(const temporary_buffer&) {} + void operator=(const temporary_buffer&) {} +}; + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_TEMPBUF_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/stl_tree.h b/contrib/libstdc++/stl/stl_tree.h new file mode 100644 index 0000000..55a6c0e --- /dev/null +++ b/contrib/libstdc++/stl/stl_tree.h @@ -0,0 +1,1099 @@ +/* + * + * 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 <stl_algobase.h> +#include <stl_alloc.h> +#include <stl_construct.h> +#include <stl_function.h> + +__STL_BEGIN_NAMESPACE + +typedef bool __rb_tree_color_type; +const __rb_tree_color_type __rb_tree_red = false; +const __rb_tree_color_type __rb_tree_black = true; + +struct __rb_tree_node_base +{ + typedef __rb_tree_color_type color_type; + typedef __rb_tree_node_base* base_ptr; + + color_type color; + base_ptr parent; + base_ptr left; + base_ptr right; + + static base_ptr minimum(base_ptr x) + { + while (x->left != 0) x = x->left; + return x; + } + + static base_ptr maximum(base_ptr x) + { + while (x->right != 0) x = x->right; + return x; + } +}; + +template <class Value> +struct __rb_tree_node : public __rb_tree_node_base +{ + typedef __rb_tree_node<Value>* link_type; + Value 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 node; + + void increment() + { + if (node->right != 0) { + node = node->right; + while (node->left != 0) + node = node->left; + } + else { + base_ptr y = node->parent; + while (node == y->right) { + node = y; + y = y->parent; + } + if (node->right != y) + node = y; + } + } + + void decrement() + { + if (node->color == __rb_tree_red && + node->parent->parent == node) + node = node->right; + else if (node->left != 0) { + base_ptr y = node->left; + while (y->right != 0) + y = y->right; + node = y; + } + else { + base_ptr y = node->parent; + while (node == y->left) { + node = y; + y = y->parent; + } + node = y; + } + } +}; + +template <class Value, class Ref, class Ptr> +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) { node = x; } + __rb_tree_iterator(const iterator& it) { node = it.node; } + + reference operator*() const { return link_type(node)->value_field; } +#ifndef __SGI_STL_NO_ARROW_OPERATOR + pointer operator->() const { return &(operator*()); } +#endif /* __SGI_STL_NO_ARROW_OPERATOR */ + + self& operator++() { increment(); return *this; } + self operator++(int) { + self tmp = *this; + increment(); + return tmp; + } + + self& operator--() { decrement(); return *this; } + self operator--(int) { + self tmp = *this; + decrement(); + return tmp; + } +}; + +inline bool operator==(const __rb_tree_base_iterator& x, + const __rb_tree_base_iterator& y) { + return x.node == y.node; +} + +inline bool operator!=(const __rb_tree_base_iterator& x, + const __rb_tree_base_iterator& y) { + return x.node != y.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 <class Value, class Ref, class Ptr> +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->right; + x->right = y->left; + if (y->left !=0) + y->left->parent = x; + y->parent = x->parent; + + if (x == root) + root = y; + else if (x == x->parent->left) + x->parent->left = y; + else + x->parent->right = y; + y->left = x; + x->parent = y; +} + +inline void +__rb_tree_rotate_right(__rb_tree_node_base* x, __rb_tree_node_base*& root) +{ + __rb_tree_node_base* y = x->left; + x->left = y->right; + if (y->right != 0) + y->right->parent = x; + y->parent = x->parent; + + if (x == root) + root = y; + else if (x == x->parent->right) + x->parent->right = y; + else + x->parent->left = y; + y->right = x; + x->parent = y; +} + +inline void +__rb_tree_rebalance(__rb_tree_node_base* x, __rb_tree_node_base*& root) +{ + x->color = __rb_tree_red; + while (x != root && x->parent->color == __rb_tree_red) { + if (x->parent == x->parent->parent->left) { + __rb_tree_node_base* y = x->parent->parent->right; + if (y && y->color == __rb_tree_red) { + x->parent->color = __rb_tree_black; + y->color = __rb_tree_black; + x->parent->parent->color = __rb_tree_red; + x = x->parent->parent; + } + else { + if (x == x->parent->right) { + x = x->parent; + __rb_tree_rotate_left(x, root); + } + x->parent->color = __rb_tree_black; + x->parent->parent->color = __rb_tree_red; + __rb_tree_rotate_right(x->parent->parent, root); + } + } + else { + __rb_tree_node_base* y = x->parent->parent->left; + if (y && y->color == __rb_tree_red) { + x->parent->color = __rb_tree_black; + y->color = __rb_tree_black; + x->parent->parent->color = __rb_tree_red; + x = x->parent->parent; + } + else { + if (x == x->parent->left) { + x = x->parent; + __rb_tree_rotate_right(x, root); + } + x->parent->color = __rb_tree_black; + x->parent->parent->color = __rb_tree_red; + __rb_tree_rotate_left(x->parent->parent, root); + } + } + } + root->color = __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->left == 0) // z has at most one non-null child. y == z. + x = y->right; // x might be null. + else + if (y->right == 0) // z has exactly one non-null child. y == z. + x = y->left; // x is not null. + else { // z has two non-null children. Set y to + y = y->right; // z's successor. x might be null. + while (y->left != 0) + y = y->left; + x = y->right; + } + if (y != z) { // relink y in place of z. y is z's successor + z->left->parent = y; + y->left = z->left; + if (y != z->right) { + x_parent = y->parent; + if (x) x->parent = y->parent; + y->parent->left = x; // y must be a left child + y->right = z->right; + z->right->parent = y; + } + else + x_parent = y; + if (root == z) + root = y; + else if (z->parent->left == z) + z->parent->left = y; + else + z->parent->right = y; + y->parent = z->parent; + __STD::swap(y->color, z->color); + y = z; + // y now points to node to be actually deleted + } + else { // y == z + x_parent = y->parent; + if (x) x->parent = y->parent; + if (root == z) + root = x; + else + if (z->parent->left == z) + z->parent->left = x; + else + z->parent->right = x; + if (leftmost == z) + if (z->right == 0) // z->left must be null also + leftmost = z->parent; + // makes leftmost == header if z == root + else + leftmost = __rb_tree_node_base::minimum(x); + if (rightmost == z) + if (z->left == 0) // z->right must be null also + rightmost = z->parent; + // makes rightmost == header if z == root + else // x == z->left + rightmost = __rb_tree_node_base::maximum(x); + } + if (y->color != __rb_tree_red) { + while (x != root && (x == 0 || x->color == __rb_tree_black)) + if (x == x_parent->left) { + __rb_tree_node_base* w = x_parent->right; + if (w->color == __rb_tree_red) { + w->color = __rb_tree_black; + x_parent->color = __rb_tree_red; + __rb_tree_rotate_left(x_parent, root); + w = x_parent->right; + } + if ((w->left == 0 || w->left->color == __rb_tree_black) && + (w->right == 0 || w->right->color == __rb_tree_black)) { + w->color = __rb_tree_red; + x = x_parent; + x_parent = x_parent->parent; + } else { + if (w->right == 0 || w->right->color == __rb_tree_black) { + if (w->left) w->left->color = __rb_tree_black; + w->color = __rb_tree_red; + __rb_tree_rotate_right(w, root); + w = x_parent->right; + } + w->color = x_parent->color; + x_parent->color = __rb_tree_black; + if (w->right) w->right->color = __rb_tree_black; + __rb_tree_rotate_left(x_parent, root); + break; + } + } else { // same as above, with right <-> left. + __rb_tree_node_base* w = x_parent->left; + if (w->color == __rb_tree_red) { + w->color = __rb_tree_black; + x_parent->color = __rb_tree_red; + __rb_tree_rotate_right(x_parent, root); + w = x_parent->left; + } + if ((w->right == 0 || w->right->color == __rb_tree_black) && + (w->left == 0 || w->left->color == __rb_tree_black)) { + w->color = __rb_tree_red; + x = x_parent; + x_parent = x_parent->parent; + } else { + if (w->left == 0 || w->left->color == __rb_tree_black) { + if (w->right) w->right->color = __rb_tree_black; + w->color = __rb_tree_red; + __rb_tree_rotate_left(w, root); + w = x_parent->left; + } + w->color = x_parent->color; + x_parent->color = __rb_tree_black; + if (w->left) w->left->color = __rb_tree_black; + __rb_tree_rotate_right(x_parent, root); + break; + } + } + if (x) x->color = __rb_tree_black; + } + return y; +} + +template <class Key, class Value, class KeyOfValue, class Compare, + class Alloc = alloc> +class rb_tree { +protected: + typedef void* void_pointer; + typedef __rb_tree_node_base* base_ptr; + typedef __rb_tree_node<Value> rb_tree_node; + typedef simple_alloc<rb_tree_node, Alloc> rb_tree_node_allocator; + 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; +protected: + link_type get_node() { return rb_tree_node_allocator::allocate(); } + void put_node(link_type p) { rb_tree_node_allocator::deallocate(p); } + + link_type create_node(const value_type& x) { + link_type tmp = get_node(); + __STL_TRY { + construct(&tmp->value_field, x); + } + __STL_UNWIND(put_node(tmp)); + return tmp; + } + + link_type clone_node(link_type x) { + link_type tmp = create_node(x->value_field); + tmp->color = x->color; + tmp->left = 0; + tmp->right = 0; + return tmp; + } + + void destroy_node(link_type p) { + destroy(&p->value_field); + put_node(p); + } + +protected: + size_type node_count; // keeps track of size of tree + link_type header; + Compare key_compare; + + link_type& root() const { return (link_type&) header->parent; } + link_type& leftmost() const { return (link_type&) header->left; } + link_type& rightmost() const { return (link_type&) header->right; } + + static link_type& left(link_type x) { return (link_type&)(x->left); } + static link_type& right(link_type x) { return (link_type&)(x->right); } + static link_type& parent(link_type x) { return (link_type&)(x->parent); } + static reference value(link_type x) { return x->value_field; } + static const Key& key(link_type x) { return KeyOfValue()(value(x)); } + static color_type& color(link_type x) { return (color_type&)(x->color); } + + static link_type& left(base_ptr x) { return (link_type&)(x->left); } + static link_type& right(base_ptr x) { return (link_type&)(x->right); } + static link_type& parent(base_ptr x) { return (link_type&)(x->parent); } + static reference value(base_ptr x) { return ((link_type)x)->value_field; } + static const Key& key(base_ptr x) { return KeyOfValue()(value(link_type(x)));} + static color_type& color(base_ptr x) { return (color_type&)(link_type(x)->color); } + + static link_type minimum(link_type x) { + return (link_type) __rb_tree_node_base::minimum(x); + } + static link_type maximum(link_type x) { + return (link_type) __rb_tree_node_base::maximum(x); + } + +public: + typedef __rb_tree_iterator<value_type, reference, pointer> iterator; + typedef __rb_tree_iterator<value_type, const_reference, const_pointer> + const_iterator; + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + typedef reverse_iterator<const_iterator> const_reverse_iterator; + typedef reverse_iterator<iterator> reverse_iterator; +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + typedef reverse_bidirectional_iterator<iterator, value_type, reference, + difference_type> + reverse_iterator; + typedef reverse_bidirectional_iterator<const_iterator, value_type, + const_reference, difference_type> + const_reverse_iterator; +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ +private: + iterator __insert(base_ptr x, base_ptr y, const value_type& v); + link_type __copy(link_type x, link_type p); + void __erase(link_type x); + void init() { + header = get_node(); + color(header) = __rb_tree_red; // used to distinguish header from + // root, in iterator.operator++ + root() = 0; + leftmost() = header; + rightmost() = header; + } +public: + // allocation/deallocation + rb_tree(const Compare& comp = Compare()) + : node_count(0), key_compare(comp) { init(); } + + rb_tree(const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& x) + : node_count(0), key_compare(x.key_compare) + { + header = get_node(); + color(header) = __rb_tree_red; + if (x.root() == 0) { + root() = 0; + leftmost() = header; + rightmost() = header; + } + else { + __STL_TRY { + root() = __copy(x.root(), header); + } + __STL_UNWIND(put_node(header)); + leftmost() = minimum(root()); + rightmost() = maximum(root()); + } + node_count = x.node_count; + } + ~rb_tree() { + clear(); + put_node(header); + } + rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& + operator=(const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& x); + +public: + // accessors: + Compare key_comp() const { return key_compare; } + iterator begin() { return leftmost(); } + const_iterator begin() const { return leftmost(); } + iterator end() { return header; } + const_iterator end() const { return header; } + reverse_iterator rbegin() { return reverse_iterator(end()); } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } + reverse_iterator rend() { return reverse_iterator(begin()); } + const_reverse_iterator rend() const { + return const_reverse_iterator(begin()); + } + bool empty() const { return node_count == 0; } + size_type size() const { return node_count; } + size_type max_size() const { return size_type(-1); } + + void swap(rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& t) { + __STD::swap(header, t.header); + __STD::swap(node_count, t.node_count); + __STD::swap(key_compare, t.key_compare); + } + +public: + // insert/erase + pair<iterator,bool> 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 <class InputIterator> + void insert_unique(InputIterator first, InputIterator last); + template <class InputIterator> + 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 (node_count != 0) { + __erase(root()); + leftmost() = header; + root() = 0; + rightmost() = header; + 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<iterator,iterator> equal_range(const key_type& x); + pair<const_iterator, const_iterator> equal_range(const key_type& x) const; + +public: + // Debugging. + bool __rb_verify() const; +}; + +template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> +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 <class Key, class Value, class KeyOfValue, class Compare, class Alloc> +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 <class Key, class Value, class KeyOfValue, class Compare, class Alloc> +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 <class Key, class Value, class KeyOfValue, class Compare, class Alloc> +rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& +rb_tree<Key, Value, KeyOfValue, Compare, Alloc>:: +operator=(const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& x) { + if (this != &x) { + // Note that Key may be a constant type. + clear(); + node_count = 0; + key_compare = x.key_compare; + if (x.root() == 0) { + root() = 0; + leftmost() = header; + rightmost() = header; + } + else { + root() = __copy(x.root(), header); + leftmost() = minimum(root()); + rightmost() = maximum(root()); + node_count = x.node_count; + } + } + return *this; +} + +template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> +typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator +rb_tree<Key, Value, KeyOfValue, Compare, Alloc>:: +__insert(base_ptr x_, base_ptr y_, const Value& v) { + link_type x = (link_type) x_; + link_type y = (link_type) y_; + link_type z; + + if (y == header || x != 0 || key_compare(KeyOfValue()(v), key(y))) { + z = create_node(v); + left(y) = z; // also makes leftmost() = z when y == header + if (y == header) { + root() = z; + rightmost() = z; + } + else if (y == leftmost()) + leftmost() = z; // maintain leftmost() pointing to min node + } + else { + z = create_node(v); + right(y) = z; + if (y == rightmost()) + rightmost() = z; // maintain rightmost() pointing to max node + } + parent(z) = y; + left(z) = 0; + right(z) = 0; + __rb_tree_rebalance(z, header->parent); + ++node_count; + return iterator(z); +} + +template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> +typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator +rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::insert_equal(const Value& v) +{ + link_type y = header; + link_type x = root(); + while (x != 0) { + y = x; + x = key_compare(KeyOfValue()(v), key(x)) ? left(x) : right(x); + } + return __insert(x, y, v); +} + + +template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> +pair<typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator, bool> +rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::insert_unique(const Value& v) +{ + link_type y = header; + link_type x = root(); + bool comp = true; + while (x != 0) { + y = x; + comp = key_compare(KeyOfValue()(v), key(x)); + x = comp ? left(x) : right(x); + } + iterator j = iterator(y); + if (comp) + if (j == begin()) + return pair<iterator,bool>(__insert(x, y, v), true); + else + --j; + if (key_compare(key(j.node), KeyOfValue()(v))) + return pair<iterator,bool>(__insert(x, y, v), true); + return pair<iterator,bool>(j, false); +} + + +template <class Key, class Val, class KeyOfValue, class Compare, class Alloc> +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.node == header->left) // begin() + if (size() > 0 && key_compare(KeyOfValue()(v), key(position.node))) + return __insert(position.node, position.node, v); + // first argument just needs to be non-null + else + return insert_unique(v).first; + else if (position.node == header) // end() + if (key_compare(key(rightmost()), KeyOfValue()(v))) + return __insert(0, rightmost(), v); + else + return insert_unique(v).first; + else { + iterator before = position; + --before; + if (key_compare(key(before.node), KeyOfValue()(v)) + && key_compare(KeyOfValue()(v), key(position.node))) + if (right(before.node) == 0) + return __insert(0, before.node, v); + else + return __insert(position.node, position.node, v); + // first argument just needs to be non-null + else + return insert_unique(v).first; + } +} + +template <class Key, class Val, class KeyOfValue, class Compare, class Alloc> +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.node == header->left) // begin() + if (size() > 0 && key_compare(KeyOfValue()(v), key(position.node))) + return __insert(position.node, position.node, v); + // first argument just needs to be non-null + else + return insert_equal(v); + else if (position.node == header) // end() + if (!key_compare(KeyOfValue()(v), key(rightmost()))) + return __insert(0, rightmost(), v); + else + return insert_equal(v); + else { + iterator before = position; + --before; + if (!key_compare(KeyOfValue()(v), key(before.node)) + && !key_compare(key(position.node), KeyOfValue()(v))) + if (right(before.node) == 0) + return __insert(0, before.node, v); + else + return __insert(position.node, position.node, v); + // first argument just needs to be non-null + else + return insert_equal(v); + } +} + +#ifdef __STL_MEMBER_TEMPLATES + +template <class K, class V, class KoV, class Cmp, class Al> template<class II> +void rb_tree<K, V, KoV, Cmp, Al>::insert_equal(II first, II last) { + for ( ; first != last; ++first) + insert_equal(*first); +} + +template <class K, class V, class KoV, class Cmp, class Al> template<class II> +void rb_tree<K, V, KoV, Cmp, Al>::insert_unique(II first, II last) { + for ( ; first != last; ++first) + insert_unique(*first); +} + +#else /* __STL_MEMBER_TEMPLATES */ + +template <class K, class V, class KoV, class Cmp, class Al> +void +rb_tree<K, V, KoV, Cmp, Al>::insert_equal(const V* first, const V* last) { + for ( ; first != last; ++first) + insert_equal(*first); +} + +template <class K, class V, class KoV, class Cmp, class Al> +void +rb_tree<K, V, KoV, Cmp, Al>::insert_equal(const_iterator first, + const_iterator last) { + for ( ; first != last; ++first) + insert_equal(*first); +} + +template <class K, class V, class KoV, class Cmp, class A> +void +rb_tree<K, V, KoV, Cmp, A>::insert_unique(const V* first, const V* last) { + for ( ; first != last; ++first) + insert_unique(*first); +} + +template <class K, class V, class KoV, class Cmp, class A> +void +rb_tree<K, V, KoV, Cmp, A>::insert_unique(const_iterator first, + const_iterator last) { + for ( ; first != last; ++first) + insert_unique(*first); +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> +inline void +rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::erase(iterator position) { + link_type y = (link_type) __rb_tree_rebalance_for_erase(position.node, + header->parent, + header->left, + header->right); + destroy_node(y); + --node_count; +} + +template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> +typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::size_type +rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::erase(const Key& x) { + pair<iterator,iterator> p = equal_range(x); + size_type n = 0; + distance(p.first, p.second, n); + erase(p.first, p.second); + return n; +} + +template <class K, class V, class KeyOfValue, class Compare, class Alloc> +typename rb_tree<K, V, KeyOfValue, Compare, Alloc>::link_type +rb_tree<K, V, KeyOfValue, Compare, Alloc>::__copy(link_type x, link_type p) { + // structural copy. x and p must be non-null. + link_type top = clone_node(x); + top->parent = p; + + __STL_TRY { + if (x->right) + top->right = __copy(right(x), top); + p = top; + x = left(x); + + while (x != 0) { + link_type y = clone_node(x); + p->left = y; + y->parent = p; + if (x->right) + y->right = __copy(right(x), y); + p = y; + x = left(x); + } + } + __STL_UNWIND(__erase(top)); + + return top; +} + +template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> +void rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::__erase(link_type x) { + // erase without rebalancing + while (x != 0) { + __erase(right(x)); + link_type y = left(x); + destroy_node(x); + x = y; + } +} + +template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> +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 <class Key, class Value, class KeyOfValue, class Compare, class Alloc> +void rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::erase(const Key* first, + const Key* last) { + while (first != last) erase(*first++); +} + +template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> +typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator +rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::find(const Key& k) { + link_type y = header; // Last node which is not less than k. + link_type x = root(); // Current node. + + while (x != 0) + if (!key_compare(key(x), k)) + y = x, x = left(x); + else + x = right(x); + + iterator j = iterator(y); + return (j == end() || key_compare(k, key(j.node))) ? end() : j; +} + +template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> +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 = header; /* Last node which is not less than k. */ + link_type x = root(); /* Current node. */ + + while (x != 0) { + if (!key_compare(key(x), k)) + y = x, x = left(x); + else + x = right(x); + } + const_iterator j = const_iterator(y); + return (j == end() || key_compare(k, key(j.node))) ? end() : j; +} + +template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> +typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::size_type +rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::count(const Key& k) const { + pair<const_iterator, const_iterator> p = equal_range(k); + size_type n = 0; + distance(p.first, p.second, n); + return n; +} + +template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> +typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator +rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::lower_bound(const Key& k) { + link_type y = header; /* Last node which is not less than k. */ + link_type x = root(); /* Current node. */ + + while (x != 0) + if (!key_compare(key(x), k)) + y = x, x = left(x); + else + x = right(x); + + return iterator(y); +} + +template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> +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 = header; /* Last node which is not less than k. */ + link_type x = root(); /* Current node. */ + + while (x != 0) + if (!key_compare(key(x), k)) + y = x, x = left(x); + else + x = right(x); + + return const_iterator(y); +} + +template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> +typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator +rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::upper_bound(const Key& k) { + link_type y = header; /* Last node which is greater than k. */ + link_type x = root(); /* Current node. */ + + while (x != 0) + if (key_compare(k, key(x))) + y = x, x = left(x); + else + x = right(x); + + return iterator(y); +} + +template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> +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 = header; /* Last node which is greater than k. */ + link_type x = root(); /* Current node. */ + + while (x != 0) + if (key_compare(k, key(x))) + y = x, x = left(x); + else + x = right(x); + + return const_iterator(y); +} + +template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> +inline pair<typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator, + typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator> +rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::equal_range(const Key& k) { + return pair<iterator, iterator>(lower_bound(k), upper_bound(k)); +} + +template <class Key, class Value, class KoV, class Compare, class Alloc> +inline pair<typename rb_tree<Key, Value, KoV, Compare, Alloc>::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<const_iterator,const_iterator>(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->color == __rb_tree_black ? 1 : 0; + if (node == root) + return bc; + else + return bc + __black_count(node->parent, root); + } +} + +template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> +bool +rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::__rb_verify() const +{ + if (node_count == 0 || begin() == end()) + return node_count == 0 && begin() == end() && + header->left == header && header->right == header; + + int len = __black_count(leftmost(), root()); + for (const_iterator it = begin(); it != end(); ++it) { + link_type x = (link_type) it.node; + link_type L = left(x); + link_type R = right(x); + + if (x->color == __rb_tree_red) + if ((L && L->color == __rb_tree_red) || + (R && R->color == __rb_tree_red)) + return false; + + if (L && key_compare(key(x), key(L))) + return false; + if (R && key_compare(key(R), key(x))) + return false; + + if (!L && !R && __black_count(x, root()) != len) + return false; + } + + if (leftmost() != __rb_tree_node_base::minimum(root())) + return false; + if (rightmost() != __rb_tree_node_base::maximum(root())) + return false; + + return true; +} + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_TREE_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/stl_uninitialized.h b/contrib/libstdc++/stl/stl_uninitialized.h new file mode 100644 index 0000000..661bbe9 --- /dev/null +++ b/contrib/libstdc++/stl/stl_uninitialized.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_UNINITIALIZED_H +#define __SGI_STL_INTERNAL_UNINITIALIZED_H + +__STL_BEGIN_NAMESPACE + +// Valid if copy construction is equivalent to assignment, and if the +// destructor is trivial. +template <class InputIterator, class ForwardIterator> +inline ForwardIterator +__uninitialized_copy_aux(InputIterator first, InputIterator last, + ForwardIterator result, + __true_type) { + return copy(first, last, result); +} + +template <class InputIterator, class ForwardIterator> +ForwardIterator +__uninitialized_copy_aux(InputIterator first, InputIterator last, + ForwardIterator result, + __false_type) { + ForwardIterator cur = result; + __STL_TRY { + for ( ; first != last; ++first, ++cur) + construct(&*cur, *first); + return cur; + } + __STL_UNWIND(destroy(result, cur)); +} + + +template <class InputIterator, class ForwardIterator, class T> +inline ForwardIterator +__uninitialized_copy(InputIterator first, InputIterator last, + ForwardIterator result, T*) { + typedef typename __type_traits<T>::is_POD_type is_POD; + return __uninitialized_copy_aux(first, last, result, is_POD()); +} + +template <class InputIterator, class ForwardIterator> +inline ForwardIterator + uninitialized_copy(InputIterator first, InputIterator last, + ForwardIterator result) { + return __uninitialized_copy(first, last, result, value_type(result)); +} + +inline char* uninitialized_copy(const char* first, const char* last, + char* result) { + memmove(result, first, last - first); + return result + (last - first); +} + +inline wchar_t* uninitialized_copy(const wchar_t* first, const wchar_t* last, + wchar_t* result) { + memmove(result, first, sizeof(wchar_t) * (last - first)); + return result + (last - first); +} + +template <class InputIterator, class Size, class ForwardIterator> +pair<InputIterator, ForwardIterator> +__uninitialized_copy_n(InputIterator first, Size count, + ForwardIterator result, + input_iterator_tag) { + ForwardIterator cur = result; + __STL_TRY { + for ( ; count > 0 ; --count, ++first, ++cur) + construct(&*cur, *first); + return pair<InputIterator, ForwardIterator>(first, cur); + } + __STL_UNWIND(destroy(result, cur)); +} + +template <class RandomAccessIterator, class Size, class ForwardIterator> +inline pair<RandomAccessIterator, ForwardIterator> +__uninitialized_copy_n(RandomAccessIterator first, Size count, + ForwardIterator result, + random_access_iterator_tag) { + RandomAccessIterator last = first + count; + return make_pair(last, uninitialized_copy(first, last, result)); +} + +template <class InputIterator, class Size, class ForwardIterator> +inline pair<InputIterator, ForwardIterator> +uninitialized_copy_n(InputIterator first, Size count, + ForwardIterator result) { + return __uninitialized_copy_n(first, count, result, + iterator_category(first)); +} + +// Valid if copy construction is equivalent to assignment, and if the +// destructor is trivial. +template <class ForwardIterator, class T> +inline void +__uninitialized_fill_aux(ForwardIterator first, ForwardIterator last, + const T& x, __true_type) +{ + fill(first, last, x); +} + +template <class ForwardIterator, class T> +void +__uninitialized_fill_aux(ForwardIterator first, ForwardIterator last, + const T& x, __false_type) +{ + ForwardIterator cur = first; + __STL_TRY { + for ( ; cur != last; ++cur) + construct(&*cur, x); + } + __STL_UNWIND(destroy(first, cur)); +} + +template <class ForwardIterator, class T, class T1> +inline void __uninitialized_fill(ForwardIterator first, ForwardIterator last, + const T& x, T1*) { + typedef typename __type_traits<T1>::is_POD_type is_POD; + __uninitialized_fill_aux(first, last, x, is_POD()); + +} + +template <class ForwardIterator, class T> +inline void uninitialized_fill(ForwardIterator first, ForwardIterator last, + const T& x) { + __uninitialized_fill(first, last, x, value_type(first)); +} + +// Valid if copy construction is equivalent to assignment, and if the +// destructor is trivial. +template <class ForwardIterator, class Size, class T> +inline ForwardIterator +__uninitialized_fill_n_aux(ForwardIterator first, Size n, + const T& x, __true_type) { + return fill_n(first, n, x); +} + +template <class ForwardIterator, class Size, class T> +ForwardIterator +__uninitialized_fill_n_aux(ForwardIterator first, Size n, + const T& x, __false_type) { + ForwardIterator cur = first; + __STL_TRY { + for ( ; n > 0; --n, ++cur) + construct(&*cur, x); + return cur; + } + __STL_UNWIND(destroy(first, cur)); +} + +template <class ForwardIterator, class Size, class T, class T1> +inline ForwardIterator __uninitialized_fill_n(ForwardIterator first, Size n, + const T& x, T1*) { + typedef typename __type_traits<T1>::is_POD_type is_POD; + return __uninitialized_fill_n_aux(first, n, x, is_POD()); + +} + +template <class ForwardIterator, class Size, class T> +inline ForwardIterator uninitialized_fill_n(ForwardIterator first, Size n, + const T& x) { + return __uninitialized_fill_n(first, n, x, value_type(first)); +} + +// Copies [first1, last1) into [result, result + (last1 - first1)), and +// copies [first2, last2) into +// [result, result + (last1 - first1) + (last2 - first2)). + +template <class InputIterator1, class InputIterator2, class ForwardIterator> +inline ForwardIterator +__uninitialized_copy_copy(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + ForwardIterator result) { + ForwardIterator mid = uninitialized_copy(first1, last1, result); + __STL_TRY { + return uninitialized_copy(first2, last2, mid); + } + __STL_UNWIND(destroy(result, mid)); +} + +// Fills [result, mid) with x, and copies [first, last) into +// [mid, mid + (last - first)). +template <class ForwardIterator, class T, class InputIterator> +inline ForwardIterator +__uninitialized_fill_copy(ForwardIterator result, ForwardIterator mid, + const T& x, + InputIterator first, InputIterator last) { + uninitialized_fill(result, mid, x); + __STL_TRY { + return uninitialized_copy(first, last, mid); + } + __STL_UNWIND(destroy(result, mid)); +} + +// Copies [first1, last1) into [first2, first2 + (last1 - first1)), and +// fills [first2 + (last1 - first1), last2) with x. +template <class InputIterator, class ForwardIterator, class T> +inline void +__uninitialized_copy_fill(InputIterator first1, InputIterator last1, + ForwardIterator first2, ForwardIterator last2, + const T& x) { + ForwardIterator mid2 = uninitialized_copy(first1, last1, first2); + __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/contrib/libstdc++/stl/stl_vector.h b/contrib/libstdc++/stl/stl_vector.h new file mode 100644 index 0000000..cfa7fdb --- /dev/null +++ b/contrib/libstdc++/stl/stl_vector.h @@ -0,0 +1,534 @@ +/* + * + * 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 +#endif + +template <class T, class Alloc = alloc> +class vector { +public: + typedef T 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; + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + typedef reverse_iterator<const_iterator> const_reverse_iterator; + typedef reverse_iterator<iterator> reverse_iterator; +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + typedef reverse_iterator<const_iterator, value_type, const_reference, + difference_type> const_reverse_iterator; + typedef reverse_iterator<iterator, value_type, reference, difference_type> + reverse_iterator; +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ +protected: + typedef simple_alloc<value_type, Alloc> data_allocator; + iterator start; + iterator finish; + iterator end_of_storage; + void insert_aux(iterator position, const T& x); + void deallocate() { + if (start) data_allocator::deallocate(start, end_of_storage - start); + } + + void fill_initialize(size_type n, const T& value) { + start = allocate_and_fill(n, value); + finish = start + n; + end_of_storage = finish; + } +public: + iterator begin() { return start; } + const_iterator begin() const { return start; } + iterator end() { return finish; } + const_iterator end() const { return finish; } + reverse_iterator rbegin() { return reverse_iterator(end()); } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } + reverse_iterator rend() { return reverse_iterator(begin()); } + const_reverse_iterator rend() const { + return const_reverse_iterator(begin()); + } + size_type size() const { return size_type(end() - begin()); } + size_type max_size() const { return size_type(-1) / sizeof(T); } + size_type capacity() const { return size_type(end_of_storage - begin()); } + bool empty() const { return begin() == end(); } + reference operator[](size_type n) { return *(begin() + n); } + const_reference operator[](size_type n) const { return *(begin() + n); } + + vector() : start(0), finish(0), end_of_storage(0) {} + vector(size_type n, const T& value) { fill_initialize(n, value); } + vector(int n, const T& value) { fill_initialize(n, value); } + vector(long n, const T& value) { fill_initialize(n, value); } + explicit vector(size_type n) { fill_initialize(n, T()); } + + vector(const vector<T, Alloc>& x) { + start = allocate_and_copy(x.end() - x.begin(), x.begin(), x.end()); + finish = start + (x.end() - x.begin()); + end_of_storage = finish; + } +#ifdef __STL_MEMBER_TEMPLATES + template <class InputIterator> + vector(InputIterator first, InputIterator last) : + start(0), finish(0), end_of_storage(0) + { + range_initialize(first, last, iterator_category(first)); + } +#else /* __STL_MEMBER_TEMPLATES */ + vector(const_iterator first, const_iterator last) { + size_type n = 0; + distance(first, last, n); + start = allocate_and_copy(n, first, last); + finish = start + n; + end_of_storage = finish; + } +#endif /* __STL_MEMBER_TEMPLATES */ + ~vector() { + destroy(start, finish); + deallocate(); + } + vector<T, Alloc>& operator=(const vector<T, Alloc>& x); + void reserve(size_type n) { + if (capacity() < n) { + const size_type old_size = size(); + iterator tmp = allocate_and_copy(n, start, finish); + destroy(start, finish); + deallocate(); + start = tmp; + finish = tmp + old_size; + end_of_storage = start + n; + } + } + reference front() { return *begin(); } + const_reference front() const { return *begin(); } + reference back() { return *(end() - 1); } + const_reference back() const { return *(end() - 1); } + void push_back(const T& x) { + if (finish != end_of_storage) { + construct(finish, x); + ++finish; + } + else + insert_aux(end(), x); + } + void swap(vector<T, Alloc>& x) { + __STD::swap(start, x.start); + __STD::swap(finish, x.finish); + __STD::swap(end_of_storage, x.end_of_storage); + } + iterator insert(iterator position, const T& x) { + size_type n = position - begin(); + if (finish != end_of_storage && position == end()) { + construct(finish, x); + ++finish; + } + else + insert_aux(position, x); + return begin() + n; + } + iterator insert(iterator position) { return insert(position, T()); } +#ifdef __STL_MEMBER_TEMPLATES + template <class InputIterator> + void insert(iterator position, InputIterator first, InputIterator last) { + range_insert(position, first, last, iterator_category(first)); + } +#else /* __STL_MEMBER_TEMPLATES */ + void insert(iterator position, + const_iterator first, const_iterator last); +#endif /* __STL_MEMBER_TEMPLATES */ + + void insert (iterator pos, size_type n, const T& x); + void insert (iterator pos, int n, const T& x) { + insert(pos, (size_type) n, x); + } + void insert (iterator pos, long n, const T& x) { + insert(pos, (size_type) n, x); + } + + void pop_back() { + --finish; + destroy(finish); + } + iterator erase(iterator position) { + if (position + 1 != end()) + copy(position + 1, finish, position); + --finish; + destroy(finish); + return position; + } + iterator erase(iterator first, iterator last) { + iterator i = copy(last, finish, first); + destroy(i, finish); + finish = finish - (last - first); + return first; + } + void resize(size_type new_size, const T& x) { + if (new_size < size()) + erase(begin() + new_size, end()); + else + insert(end(), new_size - size(), x); + } + void resize(size_type new_size) { resize(new_size, T()); } + void clear() { erase(begin(), end()); } + +protected: + iterator allocate_and_fill(size_type n, const T& x) { + iterator result = data_allocator::allocate(n); + __STL_TRY { + uninitialized_fill_n(result, n, x); + return result; + } + __STL_UNWIND(data_allocator::deallocate(result, n)); + } + +#ifdef __STL_MEMBER_TEMPLATES + template <class ForwardIterator> + iterator allocate_and_copy(size_type n, + ForwardIterator first, ForwardIterator last) { + iterator result = data_allocator::allocate(n); + __STL_TRY { + uninitialized_copy(first, last, result); + return result; + } + __STL_UNWIND(data_allocator::deallocate(result, n)); + } +#else /* __STL_MEMBER_TEMPLATES */ + iterator allocate_and_copy(size_type n, + const_iterator first, const_iterator last) { + iterator result = data_allocator::allocate(n); + __STL_TRY { + uninitialized_copy(first, last, result); + return result; + } + __STL_UNWIND(data_allocator::deallocate(result, n)); + } +#endif /* __STL_MEMBER_TEMPLATES */ + + +#ifdef __STL_MEMBER_TEMPLATES + template <class InputIterator> + void range_initialize(InputIterator first, InputIterator last, + input_iterator_tag) { + for ( ; first != last; ++first) + push_back(*first); + } + + // This function is only called by the constructor. We have to worry + // about resource leaks, but not about maintaining invariants. + template <class ForwardIterator> + void range_initialize(ForwardIterator first, ForwardIterator last, + forward_iterator_tag) { + size_type n = 0; + distance(first, last, n); + start = allocate_and_copy(n, first, last); + finish = start + n; + end_of_storage = finish; + } + + template <class InputIterator> + void range_insert(iterator pos, + InputIterator first, InputIterator last, + input_iterator_tag); + + template <class ForwardIterator> + void range_insert(iterator pos, + ForwardIterator first, ForwardIterator last, + forward_iterator_tag); + +#endif /* __STL_MEMBER_TEMPLATES */ +}; + +template <class T, class Alloc> +inline bool operator==(const vector<T, Alloc>& x, const vector<T, Alloc>& y) { + return x.size() == y.size() && equal(x.begin(), x.end(), y.begin()); +} + +template <class T, class Alloc> +inline bool operator<(const vector<T, Alloc>& x, const vector<T, Alloc>& y) { + return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template <class T, class Alloc> +inline void swap(vector<T, Alloc>& x, vector<T, Alloc>& y) { + x.swap(y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +template <class T, class Alloc> +vector<T, Alloc>& vector<T, Alloc>::operator=(const vector<T, Alloc>& x) { + if (&x != this) { + if (x.size() > capacity()) { + iterator tmp = allocate_and_copy(x.end() - x.begin(), + x.begin(), x.end()); + destroy(start, finish); + deallocate(); + start = tmp; + end_of_storage = start + (x.end() - x.begin()); + } + else if (size() >= x.size()) { + iterator i = copy(x.begin(), x.end(), begin()); + destroy(i, finish); + } + else { + copy(x.begin(), x.begin() + size(), start); + uninitialized_copy(x.begin() + size(), x.end(), finish); + } + finish = start + x.size(); + } + return *this; +} + +template <class T, class Alloc> +void vector<T, Alloc>::insert_aux(iterator position, const T& x) { + if (finish != end_of_storage) { + construct(finish, *(finish - 1)); + ++finish; + T x_copy = x; + copy_backward(position, finish - 2, finish - 1); + *position = x_copy; + } + else { + const size_type old_size = size(); + const size_type len = old_size != 0 ? 2 * old_size : 1; + iterator new_start = data_allocator::allocate(len); + iterator new_finish = new_start; + __STL_TRY { + new_finish = uninitialized_copy(start, position, new_start); + construct(new_finish, x); + ++new_finish; + new_finish = uninitialized_copy(position, finish, new_finish); + } + +# ifdef __STL_USE_EXCEPTIONS + catch(...) { + destroy(new_start, new_finish); + data_allocator::deallocate(new_start, len); + throw; + } +# endif /* __STL_USE_EXCEPTIONS */ + destroy(begin(), end()); + deallocate(); + start = new_start; + finish = new_finish; + end_of_storage = new_start + len; + } +} + +template <class T, class Alloc> +void vector<T, Alloc>::insert(iterator position, size_type n, const T& x) { + if (n != 0) { + if (size_type(end_of_storage - finish) >= n) { + T x_copy = x; + const size_type elems_after = finish - position; + iterator old_finish = finish; + if (elems_after > n) { + uninitialized_copy(finish - n, finish, finish); + finish += n; + copy_backward(position, old_finish - n, old_finish); + fill(position, position + n, x_copy); + } + else { + uninitialized_fill_n(finish, n - elems_after, x_copy); + finish += n - elems_after; + uninitialized_copy(position, old_finish, finish); + finish += elems_after; + fill(position, old_finish, x_copy); + } + } + else { + const size_type old_size = size(); + const size_type len = old_size + max(old_size, n); + iterator new_start = data_allocator::allocate(len); + iterator new_finish = new_start; + __STL_TRY { + new_finish = uninitialized_copy(start, position, new_start); + new_finish = uninitialized_fill_n(new_finish, n, x); + new_finish = uninitialized_copy(position, finish, new_finish); + } +# ifdef __STL_USE_EXCEPTIONS + catch(...) { + destroy(new_start, new_finish); + data_allocator::deallocate(new_start, len); + throw; + } +# endif /* __STL_USE_EXCEPTIONS */ + destroy(start, finish); + deallocate(); + start = new_start; + finish = new_finish; + end_of_storage = new_start + len; + } + } +} + +#ifdef __STL_MEMBER_TEMPLATES + +template <class T, class Alloc> template <class InputIterator> +void vector<T, Alloc>::range_insert(iterator pos, + InputIterator first, InputIterator last, + input_iterator_tag) { + for ( ; first != last; ++first) { + pos = insert(pos, *first); + ++pos; + } +} + +template <class T, class Alloc> template <class ForwardIterator> +void vector<T, Alloc>::range_insert(iterator position, + ForwardIterator first, + ForwardIterator last, + forward_iterator_tag) { + if (first != last) { + size_type n = 0; + distance(first, last, n); + if (size_type(end_of_storage - finish) >= n) { + const size_type elems_after = finish - position; + iterator old_finish = finish; + if (elems_after > n) { + uninitialized_copy(finish - n, finish, finish); + finish += n; + copy_backward(position, old_finish - n, old_finish); + copy(first, last, position); + } + else { + ForwardIterator mid = first; + advance(mid, elems_after); + uninitialized_copy(mid, last, finish); + finish += n - elems_after; + uninitialized_copy(position, old_finish, finish); + finish += elems_after; + copy(first, mid, position); + } + } + else { + const size_type old_size = size(); + const size_type len = old_size + max(old_size, n); + iterator new_start = data_allocator::allocate(len); + iterator new_finish = new_start; + __STL_TRY { + new_finish = uninitialized_copy(start, position, new_start); + new_finish = uninitialized_copy(first, last, new_finish); + new_finish = uninitialized_copy(position, finish, new_finish); + } +# ifdef __STL_USE_EXCEPTIONS + catch(...) { + destroy(new_start, new_finish); + data_allocator::deallocate(new_start, len); + throw; + } +# endif /* __STL_USE_EXCEPTIONS */ + destroy(start, finish); + deallocate(); + start = new_start; + finish = new_finish; + end_of_storage = new_start + len; + } + } +} + +#else /* __STL_MEMBER_TEMPLATES */ + +template <class T, class Alloc> +void vector<T, Alloc>::insert(iterator position, + const_iterator first, + const_iterator last) { + if (first != last) { + size_type n = 0; + distance(first, last, n); + if (size_type(end_of_storage - finish) >= n) { + const size_type elems_after = finish - position; + iterator old_finish = finish; + if (elems_after > n) { + uninitialized_copy(finish - n, finish, finish); + finish += n; + copy_backward(position, old_finish - n, old_finish); + copy(first, last, position); + } + else { + uninitialized_copy(first + elems_after, last, finish); + finish += n - elems_after; + uninitialized_copy(position, old_finish, finish); + finish += elems_after; + copy(first, first + elems_after, position); + } + } + else { + const size_type old_size = size(); + const size_type len = old_size + max(old_size, n); + iterator new_start = data_allocator::allocate(len); + iterator new_finish = new_start; + __STL_TRY { + new_finish = uninitialized_copy(start, position, new_start); + new_finish = uninitialized_copy(first, last, new_finish); + new_finish = uninitialized_copy(position, finish, new_finish); + } +# ifdef __STL_USE_EXCEPTIONS + catch(...) { + destroy(new_start, new_finish); + data_allocator::deallocate(new_start, len); + throw; + } +# endif /* __STL_USE_EXCEPTIONS */ + destroy(start, finish); + deallocate(); + start = new_start; + finish = new_finish; + end_of_storage = new_start + len; + } + } +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1174 +#endif + +__STL_END_NAMESPACE + +#endif /* __SGI_STL_INTERNAL_VECTOR_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/tempbuf.h b/contrib/libstdc++/stl/tempbuf.h new file mode 100644 index 0000000..8799393 --- /dev/null +++ b/contrib/libstdc++/stl/tempbuf.h @@ -0,0 +1,58 @@ +/* + * + * 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 <pair.h> +#endif +#include <limits.h> +#include <stddef.h> +#include <stdlib.h> +#ifndef __TYPE_TRAITS_H +#include <type_traits.h> +#endif +#ifndef __SGI_STL_INTERNAL_CONSTRUCT_H +#include <stl_construct.h> +#endif +#ifndef __SGI_STL_INTERNAL_TEMPBUF_H +#include <stl_tempbuf.h> +#endif + +#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/contrib/libstdc++/stl/tree.h b/contrib/libstdc++/stl/tree.h new file mode 100644 index 0000000..77c57cb --- /dev/null +++ b/contrib/libstdc++/stl/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 <stl_tree.h> +#endif +#include <algobase.h> +#include <alloc.h> + +#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/contrib/libstdc++/stl/type_traits.h b/contrib/libstdc++/stl/type_traits.h new file mode 100644 index 0000000..40c6339 --- /dev/null +++ b/contrib/libstdc++/stl/type_traits.h @@ -0,0 +1,233 @@ +/* + * + * 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 <stl_config.h> +#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 <class T> void copy(T* source,T* destination,int n,__false_type); +//Copy an array of elements which have trivial copy constructors. Use memcpy. +template <class T> void copy(T* source,T* destination,int n,__true_type); + +//Copy an array of any type by using the most efficient copy mechanism +template <class T> inline void copy(T* source,T* destination,int n) { + copy(source,destination,n,typename __type_traits<T>::has_trivial_copy_constructor()); +} +*/ + + +struct __true_type { +}; + +struct __false_type { +}; + +template <class type> +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. + +__STL_TEMPLATE_NULL struct __type_traits<char> { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits<signed char> { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits<unsigned char> { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits<short> { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits<unsigned short> { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits<int> { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits<unsigned int> { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits<long> { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits<unsigned long> { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits<float> { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits<double> { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits<long double> { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + +template <class T> +struct __type_traits<T*> { + 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 */ + +struct __type_traits<char*> { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +struct __type_traits<signed char*> { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +struct __type_traits<unsigned char*> { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + + +#endif /* __TYPE_TRAITS_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/utility b/contrib/libstdc++/stl/utility new file mode 100644 index 0000000..df8c224 --- /dev/null +++ b/contrib/libstdc++/stl/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 <stl_config.h> +#include <stl_relops.h> +#include <stl_pair.h> + +#endif /* __SGI_STL_UTILITY */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/vector b/contrib/libstdc++/stl/vector new file mode 100644 index 0000000..4bcdebc --- /dev/null +++ b/contrib/libstdc++/stl/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 <stl_algobase.h> +#include <stl_alloc.h> +#include <stl_construct.h> +#include <stl_uninitialized.h> +#include <stl_vector.h> +#include <stl_bvector.h> + +#endif /* __SGI_STL_VECTOR */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/vector.h b/contrib/libstdc++/stl/vector.h new file mode 100644 index 0000000..231a227 --- /dev/null +++ b/contrib/libstdc++/stl/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 <algobase.h> +#include <alloc.h> +#include <stl_vector.h> + +#ifdef __STL_USE_NAMESPACES +using __STD::vector; +#endif /* __STL_USE_NAMESPACES */ + +#endif /* __SGI_STL_VECTOR_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stlinst.cc b/contrib/libstdc++/stlinst.cc new file mode 100644 index 0000000..b71dc7e --- /dev/null +++ b/contrib/libstdc++/stlinst.cc @@ -0,0 +1,8 @@ +// Instantiation file for the -*- C++ -*- Standard Library allocator templates +// This file is part of the GNU ANSI C++ Library. + +#include <alloc.h> + +template class __default_alloc_template<__NODE_ALLOCATOR_THREADS, 0>; + +template class __malloc_alloc_template<0>; diff --git a/contrib/libstdc++/string b/contrib/libstdc++/string new file mode 100644 index 0000000..fa6f1ab --- /dev/null +++ b/contrib/libstdc++/string @@ -0,0 +1,13 @@ +// Main header for the -*- C++ -*- string classes. + +#ifndef __STRING__ +#define __STRING__ + +#include <std/bastring.h> + +extern "C++" { +typedef basic_string <char> string; +// typedef basic_string <wchar_t> wstring; +} // extern "C++" + +#endif diff --git a/contrib/libstdc++/strstream b/contrib/libstdc++/strstream new file mode 100644 index 0000000..ee360e0 --- /dev/null +++ b/contrib/libstdc++/strstream @@ -0,0 +1,7 @@ +// -*- C++ -*- forwarding header. +// This file is part of the GNU ANSI C++ Library. + +#ifndef __STRSTREAM__ +#define __STRSTREAM__ +#include <strstream.h> +#endif diff --git a/contrib/libstdc++/tests/ChangeLog b/contrib/libstdc++/tests/ChangeLog new file mode 100644 index 0000000..8c036b7 --- /dev/null +++ b/contrib/libstdc++/tests/ChangeLog @@ -0,0 +1,116 @@ +Sun Mar 14 02:38:07 PST 1999 Jeff Law (law@cygnus.com) + + * egcs-1.1.2 Released. + +1998-07-17 Jason Merrill <jason@yorick.cygnus.com> + + * tmap.cc: Use less<int>. + * tlist.cc (main): Use remove_if. + +1998-07-13 Manfred Hollstein <manfred@s-direktnet.de> + + * Makefile.in (VERSION): Bump to 2.9.0. + +1998-07-12 Bob Sidebotham <rns@fore.com> + + * tstring.cc (findtest): New fn. + +1998-06-01 Jason Merrill <jason@yorick.cygnus.com> + + * tlist.cc, tvector.cc, tmap.cc: Remove explicit instantiations. + +Fri Oct 10 00:40:31 1997 Jason Merrill <jason@yorick.cygnus.com> + + * tstring.cc (identitytest): s/remove/erase/. + +Thu Sep 25 19:48:22 1997 Jason Merrill <jason@yorick.cygnus.com> + + * tstring.cc: Add some tests for the member templates. + +Wed Jun 11 11:00:10 1997 Jason Merrill <jason@yorick.cygnus.com> + + * tmap.cc: Explicitly instantiate allocator classes. + * tvector.cc, tlist.cc: Likewise. + +Fri May 16 18:38:05 1997 Bob Manson <manson@charmed.cygnus.com> + + * tcomplex.cc (main): If we're using short doubles, compensate for + roundoff in result of pow(a,b). + +Thu May 1 17:37:53 1997 Jason Merrill <jason@yorick.cygnus.com> + + * configure.in (CHECK): Add $(CXXFLAGS). + * Makefile.in (tcomplex): Add $(CXXFLAGS). + +Fri Apr 25 16:07:46 1997 Bob Manson <manson@charmed.cygnus.com> + + * configure.in: Change "check" to "check-old". Add do-nothing + check target. + +Sun Nov 3 12:44:48 1996 Jason Merrill <jason@yorick.cygnus.com> + + * tstring.cc: Treat string literals as const. + +Tue Sep 24 18:00:20 1996 Jason Merrill <jason@yorick.cygnus.com> + + * tstring.cc, tcomplex.cc: Remove gratuitous uses of std/. + +Mon Jun 17 14:05:50 1996 Per Bothner <bothner@deneb.cygnus.com> + + * tlist.cc (test_splice): New test. + +Fri Mar 22 16:08:36 1996 Jason Merrill <jason@yorick.cygnus.com> + + * Makefile.in (VERSION): 2.8.0. + + * tlist.cc, tmap.cc, tvector.cc: Remove explicit instantiation + directive. + +Sat Nov 18 19:52:26 1995 Mike Stump <mrs@cygnus.com> + + * Makefile.in: Update version to 2.7.1. + +Tue May 9 19:36:54 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * tstring.cc (decltest): Adjust single-character test. + +Fri May 5 14:35:19 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * tcomplex.*: Update to reflect that operator<< now + accepts more forms of input. + +Thu Apr 27 15:34:58 1995 Brendan Kehoe (brendan@lisa.cygnus.com) + + * configure.in: Update to stay in sync with config.shared. + +Thu Feb 16 00:08:28 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * Makefile.in (VERSION, SHLIB): Define. + +Tue Jan 24 02:36:24 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * Makefile.in (CXXFLAGS): Don't set. + +Mon Jan 23 04:12:10 1995 Jason Merrill <jason@python.cygnus.com> + + * tlist.cc (plus): Remove. + +Thu Jan 19 19:41:07 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * Makefile.in: Don't set LD_LIBRARY_PATH. Users will have to set + it themselves. + +Mon Jan 16 13:57:34 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * Makefile.in: Update to reflect header movement. + +Wed Dec 14 19:55:45 1994 Per Bothner <bothner@kalessin.cygnus.com> + + * configure.in: Fix quoting problem. Reported nu H.J.Lu. + +Tue Nov 29 16:46:56 1994 Per Bothner <bothner@kalessin.cygnus.com> + + * Makefile.in, configure.in: Re-write to avoid duplication. + * {tvector,tmap,tlist}.{cc,exp}, configure.in: New tests for STL. + + diff --git a/contrib/libstdc++/tests/Makefile.in b/contrib/libstdc++/tests/Makefile.in new file mode 100644 index 0000000..057482f --- /dev/null +++ b/contrib/libstdc++/tests/Makefile.in @@ -0,0 +1,35 @@ +# 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. + +VERSION = 2.9.0 +SHLIB = libstdc++.so.$(VERSION) + +DEPLIBS = ../libstdc++.a +LDLIBS = -L.. -lstdc++ +MDEPLIBS = $(DEPLIBS) +MLDLIBS = $(LDLIBS) -lm + +#### package, host, target, and site dependent Makefile fragments come in here. +## + +tcomplex.o: ${srcdir}/../std/complext.h ${srcdir}/../std/dcomplex.h +tcomplex: tcomplex.o $(MDEPLIBS) + $(CXX) $(CXXFLAGS) -o tcomplex tcomplex.o $(MLDLIBS) + +tstring.o: ${srcdir}/../std/bastring.h + +# NOTE: Rules for following tests are generated by $(srcdir)/configure.in !!! + diff --git a/contrib/libstdc++/tests/configure.in b/contrib/libstdc++/tests/configure.in new file mode 100644 index 0000000..06c5619 --- /dev/null +++ b/contrib/libstdc++/tests/configure.in @@ -0,0 +1,65 @@ +# This file is a shell script fragment that supplies the information +# necessary for a configure script to process the program in +# this directory. For more information, look at ../../configure. + +configdirs= +srctrigger=tcomplex.cc +srcname="tests for ANSI C++ library" +package_makefile_frag=Make.pack +package_makefile_rules_frag=Make.pack.r + +# per-host: + +# per-target: + +target_makefile_frag=../target-mkfrag + +TO_TOPDIR=../../ +ALL=' ' +XCXXINCLUDES="-I${srcdir}/.. -I${srcdir}/../stl -I${TO_TOPDIR}libio -I${srcdir}/${TO_TOPDIR}libio" +SIMPLE_TESTS='tstring tlist tmap tvector' +TESTS="tcomplex ${SIMPLE_TESTS}" +MOSTLYCLEAN="*.o core ${TESTS} *.out" +(. ${srcdir}/${TO_TOPDIR}libio/config.shared) >${package_makefile_frag} 2>${package_makefile_rules_frag} + +# post-target: + +CHECK="" + +for TEST in ${SIMPLE_TESTS} ; do + echo "${TEST}: ${TEST}.o" '$(DEPLIBS) + $(CXX) $(CXXFLAGS) -o' "${TEST} ${TEST}.o" '$(LDLIBS) +' >> Makefile +done + +for TEST in ${TESTS} ; do + echo ".PHONY: check-${TEST}" >>Makefile + if [ -f ${srcdir}/${TEST}.inp ] ; then + echo "check-${TEST}: ${TEST}" '$(srcdir)'"/${TEST}.inp + ./${TEST} < "'$(srcdir)'"/${TEST}.inp > ${TEST}.out 2>&1" >>Makefile + else + echo "check-${TEST}: ${TEST} + ./${TEST} > ${TEST}.out 2>&1" >>Makefile + fi + echo ' diff -c $(srcdir)/'"${TEST}.exp ${TEST}.out" >>Makefile + CHECK="${CHECK} check-${TEST}" +done + +if [ "${srcdir}" = "." ] ; then + if [ "${with_target_subdir}" != "." ] ; then + topsrcdir=${with_multisrctop}../../.. + else + topsrcdir=${with_multisrctop}../.. + fi +else + topsrcdir=${srcdir}/../.. +fi + +if [ -d ${topsrcdir}/gcc ] ; then + echo " +check: +check-old: ${CHECK}" >>Makefile +else + echo " +check: ${CHECK}" >>Makefile +fi diff --git a/contrib/libstdc++/tests/tcomplex.cc b/contrib/libstdc++/tests/tcomplex.cc new file mode 100644 index 0000000..5311f0d --- /dev/null +++ b/contrib/libstdc++/tests/tcomplex.cc @@ -0,0 +1,151 @@ +// Tests 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. + +#include <assert.h> +#include <iostream.h> +#include <complex> + +// to test near-equality + +const double eps = 0.000001; + +static void close_enough(const double_complex& a, const double_complex& b) +{ + assert(fabs(real(a) - real(b)) < eps && + fabs(imag(a) - imag(b)) < eps); +} + + +void test3(double_complex& a, double_complex& b, double_complex& c) +{ + + close_enough(-(-a) , a); + close_enough((a + b) , (b + a)); + close_enough((a + (-b)) , (a - b)); + close_enough((a * b) , (b * a)); + close_enough((a * (-b)) , -(a * b)); + close_enough((a / (-b)) , -(a / b)); + close_enough((a - b) , -(b - a)); + close_enough((a + (b + c)) , ((a + b) + c)); + close_enough((a * (b * c)) , ((a * b) * c)); + close_enough((a * (b + c)) , ((a * b) + (a * c))); + close_enough(((a - b) + b) , a); + close_enough(((a + b) - b) , a); + close_enough(((a * b) / b) , a); + close_enough(((a / b) * b) , a); + + + double_complex x = a; + x *= b; + close_enough(x , (a * b)); + x += c; + close_enough(x , ((a * b) + c)); + x -= a; + close_enough(x , (((a * b) + c) - a)); + x /= b; + close_enough(x , ((((a * b) + c) - a) / b)); + +} + +main() +{ + double_complex one = 1.0; + double_complex i (0.0, 1.0); + double_complex neg_one = -1.0; + + cout << "double_complex one = " << one << "\n"; + cout << "i = " << i << "\n"; + cout << "neg_one = " << neg_one << "\n"; + cout << "sqrt(neg_one) = " << sqrt(neg_one) << "\n"; + + double_complex a (2.0, 3.0); + double_complex b (4.0, 5.0); + + cout << "a = " << a << "\n"; + cout << "b = " << b << "\n"; + + cout << "a + one = " << (a + one) << "\n"; + (close_enough((a+one), double_complex(3.0, 3.0))); + cout << "a - one = " << (a - one) << "\n"; + (close_enough((a-one), double_complex(1.0, 3.0))); + cout << "a * one = " << (a * one) << "\n"; + (close_enough((a*one), a)); + cout << "a / one = " << (a / one) << "\n"; + (close_enough((a/one), a)); + + cout << "a + b = " << (a + b) << "\n"; + (close_enough((a+b), double_complex(6.0, 8.0))); + cout << "a - b = " << (a - b) << "\n"; + (close_enough((a-b), double_complex(-2.0, -2.0))); + cout << "a * b = " << (a * b) << "\n"; + (close_enough((a*b), double_complex(-7.0, 22.0))); + cout << "a / b = " << (a / b) << "\n"; + (close_enough((a/b), double_complex(0.5609760976, 0.0487804878))); + + double_complex c; + + c = a; cout << "c = a; c += b = " << (c += b) << "\n"; + c = a; cout << "c = a; c -= b = " << (c -= b) << "\n"; + c = a; cout << "c = a; c *= b = " << (c *= b) << "\n"; + c = a; cout << "c = a; c /= b = " << (c /= b) << "\n"; + + cout << "-a = " << (-a) << "\n"; + cout << "real(a) = " << real(a) << "\n"; + assert(real(a) == 2.0); + cout << "imag(a) = " << imag(a) << "\n"; + assert(imag(a) == 3.0); + cout << "conj(a) = " << conj(a) << "\n"; + assert(conj(a) == double_complex(2.0, -3.0)); + cout << "norm(a) = " << norm(a) << "\n"; + assert(norm(a) == 13.0); + + cout << "abs(a) = " << abs(a) << "\n"; + cout << "arg(a) = " << arg(a) << "\n"; + cout << "cos(a) = " << cos(a) << "\n"; + cout << "sin(a) = " << sin(a) << "\n"; + cout << "cosh(a) = " << cosh(a) << "\n"; + cout << "sinh(a) = " << sinh(a) << "\n"; + cout << "log(a) = " << log(a) << "\n"; + cout << "exp(a) = " << exp(a) << "\n"; + cout << "sqrt(a) = " << sqrt(a) << "\n"; + cout << "pow(a, 2) = " << pow(a, 2) << "\n"; + { + double_complex p = pow(a, b); + if(sizeof(float)==sizeof(double)) { + long w = (long)(p.imag()*100000); + if (w==-98642) + p=double_complex(-0.753046,-0.986429); + } + cout << "pow(a, b) = " << p << "\n"; + } + + double_complex d (10, 20); + double_complex e = pow(a, 2); + + test3(one, one, one); + test3(a, a, a); + test3(a, b, d); + test3(e, i, b); + test3(d, d, i); + + cout << "enter a complex number in form a or (a) or (a, b): "; + cin >> c; + cout << "number = " << c << "\n"; + + cout << "\nEnd of test\n"; + return 0; +} diff --git a/contrib/libstdc++/tests/tcomplex.exp b/contrib/libstdc++/tests/tcomplex.exp new file mode 100644 index 0000000..5bef15c --- /dev/null +++ b/contrib/libstdc++/tests/tcomplex.exp @@ -0,0 +1,37 @@ +double_complex one = (1,0) +i = (0,1) +neg_one = (-1,0) +sqrt(neg_one) = (0,1) +a = (2,3) +b = (4,5) +a + one = (3,3) +a - one = (1,3) +a * one = (2,3) +a / one = (2,3) +a + b = (6,8) +a - b = (-2,-2) +a * b = (-7,22) +a / b = (0.560976,0.0487805) +c = a; c += b = (6,8) +c = a; c -= b = (-2,-2) +c = a; c *= b = (-7,22) +c = a; c /= b = (0.560976,0.0487805) +-a = (-2,-3) +real(a) = 2 +imag(a) = 3 +conj(a) = (2,-3) +norm(a) = 13 +abs(a) = 3.60555 +arg(a) = 0.982794 +cos(a) = (-4.18963,-9.10923) +sin(a) = (9.1545,-4.16891) +cosh(a) = (-3.72455,0.511823) +sinh(a) = (-3.59056,0.530921) +log(a) = (1.28247,0.982794) +exp(a) = (-7.31511,1.04274) +sqrt(a) = (1.67415,0.895977) +pow(a, 2) = (-5,12) +pow(a, b) = (-0.753046,-0.986429) +enter a complex number in form a or (a) or (a, b): number = (1.2,-34) + +End of test diff --git a/contrib/libstdc++/tests/tcomplex.inp b/contrib/libstdc++/tests/tcomplex.inp new file mode 100644 index 0000000..c4e1d84 --- /dev/null +++ b/contrib/libstdc++/tests/tcomplex.inp @@ -0,0 +1 @@ +(1.2, -34) diff --git a/contrib/libstdc++/tests/tlist.cc b/contrib/libstdc++/tests/tlist.cc new file mode 100644 index 0000000..a37c999 --- /dev/null +++ b/contrib/libstdc++/tests/tlist.cc @@ -0,0 +1,151 @@ +// test/demo of generic lists + +#include <assert.h> + +#define tassert(ex) {if ((ex)) cerr << #ex << "\n"; \ + else _assert(#ex, __FILE__,__LINE__); } + +#include <iostream.h> +#include <list.h> +#include <algo.h> + +bool int_compare(int a, int b) +{ + return a < b; +} + +int inc(int x) +{ + return x + 1; +} + +void print(list<int>& l) +{ + for (list<int>::iterator it = l.begin(); it != l.end(); it++) + cout << *it << " "; + cout << "\n"; +} + +int is_odd(int x) +{ + return x & 1; +} + +int is_even(int x) +{ + return (x & 1) == 0; +} + +void sequence(list<int>& a, int lo, int hi) +{ + back_insert_iterator<list<int> > it(a); + while (lo <= hi) + *it++ = lo++; +} + +int old_rand = 9999; + +int get_rand() +{ + old_rand = ((long)old_rand * (long)1243) % (long)971; + return old_rand; +} + +void randseq(list<int>& a, int n) +{ + back_insert_iterator<list<int> > it(a); + while (--n >= 0) + *it++ = get_rand() % 50; +} + +int array1 [] = { 9, 16, 36 }; +int array2 [] = { 1, 4 }; + +int test_splice () +{ + list<int> l1 (array1, array1 + 3); + list<int> l2 (array2, array2 + 2); + list<int>::iterator i1 = l1.begin (); + l1.splice (i1, l2); + list<int>::iterator i2 = l1.begin (); + while (i2 != l1.end ()) + cout << *i2++ << endl; + return 0; +} + +main() +{ + list<int> a; int i; + list<int>::iterator it, bit; + sequence(a, 1, 20); + cout << "\nlist<int> a = sequence(1, 20);\n"; print(a); + for (it = a.begin (), i = 0; it != a.end (); it++, i++) + assert (*it == i + 1); + list<int> b; + randseq(b, 20); + cout << "\nlist<int> b = randseq(20);\n"; print(b); + list<int> c; + c.insert (c.end(), a.begin(), a.end()); + c.insert (c.end(), b.begin(), b.end()); + cout << "\nlist<int> c = a and b;\n"; print(c); + + list<int> d; + for (it = a.begin(); it != a.end(); it++) + d.insert(d.end (), inc(*it)); + cout << "\nlist<int> d = map(inc, a);\n"; print(d); + + list<int> e; + back_insert_iterator<list<int> > e_insertor (e); + reverse_copy (a.begin(), a.end (), e_insertor); + cout << "\nlist<int> e = reverse(a);\n"; print(e); + + list<int> f; + for (it = a.begin(); it != a.end(); it++) + if (is_odd (*it)) + f.insert(f.end (), *it); + cout << "\nlist<int> f = select(is_odd, a);\n"; print(f); + list<int> ff; + for (it = f.begin(); it != f.end(); it++) + if (is_even (*it)) + ff.insert(ff.end (), *it); + assert(ff.empty()); + + int red = 0; + for (it = a.begin(); it != a.end(); it++) + red += *it; + cout << "\nint red = a.reduce(plus, 0);\n"; cout << red; + it = a.begin(); ++it; ++it; + int second = *it; + cout << "\nint second = a[2];\n"; cout << second; + list<int> g; + for (it = a.begin(), bit = b.begin(); it != a.end () && bit != b.end (); ) + g.insert (g.end (), *it++ + *bit++); + cout << "\nlist<int> g = combine(plus, a, b);\n"; print(g); + g.remove_if (is_odd); + cout << "\ng.del(is_odd);\n"; print(g); + + ff.erase (ff.begin (), ff.end()); + for (it = g.begin(); it != g.end(); it++) + if (is_odd (*it)) + ff.insert (ff.end (), *it); + assert(ff.empty()); + + b.sort(); + for (it = b.begin(); bit = it++, it != b.end (); ) assert (*it >= *bit); + cout << "\nb.sort(int_compare);\n"; print(b); + + list<int> h; + back_insert_iterator<list<int> > h_insertor (h); + merge (a.begin (), a.end (), b.begin (), b.end (), h_insertor, int_compare); + cout << "\nlist<int> h = merge(a, b, int_compare);\n"; print(h); + for (it = h.begin(); bit = it++, it != h.end (); ) assert (*it >= *bit); + + cout << "\nh via iterator:\n"; + for (it = h.begin(); it != h.end (); it++) + cout << *it << ", "; + cout << "\n"; + + test_splice (); + + cout << "\ndone\n"; +} diff --git a/contrib/libstdc++/tests/tlist.exp b/contrib/libstdc++/tests/tlist.exp new file mode 100644 index 0000000..65f7806 --- /dev/null +++ b/contrib/libstdc++/tests/tlist.exp @@ -0,0 +1,44 @@ + +list<int> a = sequence(1, 20); +1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 + +list<int> b = randseq(20); +28 27 5 17 44 6 9 40 15 26 49 35 15 48 13 27 25 25 9 6 + +list<int> c = a and b; +1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 28 27 5 17 44 6 9 40 15 26 49 35 15 48 13 27 25 25 9 6 + +list<int> d = map(inc, a); +2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 + +list<int> e = reverse(a); +20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 + +list<int> f = select(is_odd, a); +1 3 5 7 9 11 13 15 17 19 + +int red = a.reduce(plus, 0); +210 +int second = a[2]; +3 +list<int> g = combine(plus, a, b); +29 29 8 21 49 12 16 48 24 36 60 47 28 62 28 43 42 43 28 26 + +g.del(is_odd); +8 12 16 48 24 36 60 28 62 28 42 28 26 + +b.sort(int_compare); +5 6 6 9 9 13 15 15 17 25 25 26 27 27 28 35 40 44 48 49 + +list<int> h = merge(a, b, int_compare); +1 2 3 4 5 5 6 6 6 7 8 9 9 9 10 11 12 13 13 14 15 15 15 16 17 17 18 19 20 25 25 26 27 27 28 35 40 44 48 49 + +h via iterator: +1, 2, 3, 4, 5, 5, 6, 6, 6, 7, 8, 9, 9, 9, 10, 11, 12, 13, 13, 14, 15, 15, 15, 16, 17, 17, 18, 19, 20, 25, 25, 26, 27, 27, 28, 35, 40, 44, 48, 49, +1 +4 +9 +16 +36 + +done diff --git a/contrib/libstdc++/tests/tmap.cc b/contrib/libstdc++/tests/tmap.cc new file mode 100644 index 0000000..900e66f --- /dev/null +++ b/contrib/libstdc++/tests/tmap.cc @@ -0,0 +1,59 @@ +#include <map.h> +#include <algo.h> +#include <iostream.h> +#include <function.h> + +#define int_less less<int> +struct str_less { + bool operator() (char* x, char* y) const { return strcmp(x,y) < 0; } +}; + +#if 0 +int SIZE; + +void add(int x[], int y[], map<int,int, int_less>& a) +{ + for (int i = 0; i < SIZE; ++i) a[x[i]] = y[i]; +} +#endif + +int +main(int argv, char** argc) +{ +#if 0 + if (argv > 1) + { + SIZE = abs(atoi(argc[1])); + SIZE &= ~1; + } + else + SIZE = 100; + nums = new int[SIZE]; + odds = new int[SIZE]; + perm = new int[SIZE]; +#endif + + map<int, int, int_less> my_map; + + map<char*, int, str_less> phones; + + my_map[4] = 40; + my_map[2] = 20; + + // The (char*) is needed because g++ doesn't + // convert char[] to char* in this context. + phones[(char*)"tom"] = 2345; + phones[(char*)"dick"] = 5678; + phones[(char*)"harry"] = 7654; + + cout << "2 -> " << my_map[2] << endl; + cout << "4 -> " << my_map[4] << endl; + + map<int, int, int_less>::iterator it = my_map.begin(); + for ( ; it != my_map.end(); it++) + cout << "my_map[" << (*it).first << "] = " << (*it).second << endl; + + map<char*, int, str_less>::iterator pit = phones.begin(); + for ( ; pit != phones.end(); pit++) + cout << "phones[" << (*pit).first << "] = " << (*pit).second << endl; +} diff --git a/contrib/libstdc++/tests/tmap.exp b/contrib/libstdc++/tests/tmap.exp new file mode 100644 index 0000000..b7b5df2 --- /dev/null +++ b/contrib/libstdc++/tests/tmap.exp @@ -0,0 +1,7 @@ +2 -> 20 +4 -> 40 +my_map[2] = 20 +my_map[4] = 40 +phones[dick] = 5678 +phones[harry] = 7654 +phones[tom] = 2345 diff --git a/contrib/libstdc++/tests/tstring.cc b/contrib/libstdc++/tests/tstring.cc new file mode 100644 index 0000000..833d3d9 --- /dev/null +++ b/contrib/libstdc++/tests/tstring.cc @@ -0,0 +1,249 @@ +// Tests 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. + +#include <string> +#include <algorithm> +#include <iostream.h> +#include <stdlib.h> +#include <assert.h> + +string X = "Hello"; +string Y = "world"; +string N = "123"; +string c; +const char* s = ","; + +void decltest() +{ + string x; + cout << "an empty string:" << x << "\n"; + assert(x == ""); + + string y = "Hello"; + cout << "A string initialized to Hello:" << y << "\n"; + assert(y == "Hello"); + + if (y[y.length()-1] == 'o') + y = y + '\n'; + assert(y == "Hello\n"); + y = "Hello"; + + string a = y; + cout << "A string initialized to previous string:" << a << "\n"; + assert(a == "Hello"); + assert(a == y); + + string b (a, 1, 2); + cout << "A string initialized to (previous string, 1, 2):" << b << "\n"; + assert(b == "el"); + + char ch = '@'; + string z (1, ch); + cout << "A string initialized to @:" << z << "\n"; + assert (z == "@"); + + string n ("20"); + cout << "A string initialized to 20:" << n << "\n"; + assert(n == "20"); + + int i = atoi(n.c_str ()); + double f = atof(n.c_str ()); + cout << "n = " << n << " atoi(n) = " << i << " atof(n) = " << f << "\n"; + assert(i == 20); + assert(f == 20); + + int ar[] = { 'H', 'e', 'l', 'l', 'o' }; + string is (ar, ar+sizeof(ar)/sizeof(ar[0])); + cout << "is = " << is << endl; + assert (is == "Hello"); +} + +void cattest() +{ + string x = X; + string y = Y; + string z = x + y; + cout << "z = x + y = " << z << "\n"; + assert(z == "Helloworld"); + + x += y; + cout << "x += y; x = " << x << "\n"; + assert(x == "Helloworld"); + + y = Y; + x = X; + y.insert (0, x); + cout << "y.insert (0, x); y = " << y << "\n"; + assert(y == "Helloworld"); + + y = Y; + x = X; + x = x + y + x; + cout << "x = x + y + x; x = " << x << "\n"; + assert(x == "HelloworldHello"); + + y = Y; + x = X; + x = y + x + x; + cout << "x = y + x + x; x = " << x << "\n"; + assert(x == "worldHelloHello"); + + x = X; + y = Y; + z = x + s + ' ' + y.substr (y.find ('w'), 1) + y.substr (y.find ('w') + 1) + "."; + cout << "z = x + s + + y.substr (y.find (w), 1) + y.substr (y.find (w) + 1) + . = " << z << "\n"; + assert(z == "Hello, world."); +} + +void +findtest() +{ + string x; + string::size_type pos; + pos = x.find_last_not_of('X'); + assert(pos == string::npos); + pos = x.find_last_not_of("XYZ"); + assert(pos == string::npos); + + string y("a"); + pos = y.find_last_not_of('X'); + assert(pos == 0); + pos = y.find_last_not_of('a'); + assert(pos == string::npos); + pos = y.find_last_not_of("XYZ"); + assert(pos == 0); + pos = y.find_last_not_of("a"); + assert(pos == string::npos); + + string z("ab"); + pos = z.find_last_not_of('X'); + assert(pos == 1); + pos = z.find_last_not_of("XYZ"); + assert(pos == 1); + pos = z.find_last_not_of('b'); + assert(pos == 0); + pos = z.find_last_not_of("Xb"); + assert(pos == 0); + pos = z.find_last_not_of("Xa"); + assert(pos == 1); + pos = z.find_last_of("ab"); + assert(pos == 1); + pos = z.find_last_of("Xa"); + assert(pos == 0); + pos = z.find_last_of("Xb"); + assert(pos == 1); + pos = z.find_last_of("XYZ"); + assert(pos == string::npos); + pos = z.find_last_of('a'); + assert(pos == 0); + pos = z.find_last_of('b'); + assert(pos == 1); + pos = z.find_last_of('X'); + assert(pos == string::npos); +} + +void comparetest() +{ + string x = X; + string y = Y; + string n = N; + string z = x + y; + + assert(x != y); + assert(x == "Hello"); + assert(x != z.substr (0, 4)); + assert(x.compare (y) < 0); + assert(x.compare (z.substr (0, 6)) < 0); + + assert(x.find ("lo") == 3); + assert(x.find ("l", 2) == 2); + assert(x.rfind ("l") == 3); +} + +void substrtest() +{ + string x = X; + + char ch = x[0]; + cout << "ch = x[0] = " << ch << "\n"; + assert(ch == 'H'); + + string z = x.substr (2, 3); + cout << "z = x.substr (2, 3) = " << z << "\n"; + assert(z == "llo"); + + x.replace (2, 2, "r"); + cout << "x.replace (2, 2, r); x = " << x << "\n"; + assert(x == "Hero"); + + x = X; + x.replace (0, 1, 'j'); + cout << "x.replace (0, 1, 'j'); x = " << x << "\n"; + assert(x == "jello"); + + int ar[] = { 'H', 'e', 'l', 'l', 'o' }; + x.replace (find (x.begin (), x.end (), 'l'), + find (x.rbegin (), x.rend (), 'l').base (), + ar, ar+sizeof(ar)/sizeof(ar[0])); + cout << "x = " << x << endl; + assert (x == "jeHelloo"); +} + +void iotest() +{ + string z; + cout << "enter a word:"; + cin >> z; + cout << "word =" << z << " "; + cout << "length = " << z.length() << "\n"; +} + +void identitytest(string a, string b) +{ + string x = a; + string y = b; + x += b; + y.insert (0, a); + assert((a + b) == x); + assert((a + b) == y); + assert(x == y); + + assert((a + b + a) == (a + (b + a))); + + x.erase (x.rfind (b)); + assert(x == a); + + y.replace (0, y.rfind (b), b); + assert(y == (b + b)); + y.replace (y.find (b), b.length (), a); + assert(y == (a + b)); +} + +int main() +{ + decltest(); + cattest(); + comparetest(); + findtest(); + substrtest(); + identitytest(X, X); + identitytest(X, Y); + identitytest(X+Y+N+X+Y+N, "A string that will be used in identitytest but is otherwise just another useless string."); + iotest(); + cout << "\nEnd of test\n"; + return 0; +} diff --git a/contrib/libstdc++/tests/tstring.exp b/contrib/libstdc++/tests/tstring.exp new file mode 100644 index 0000000..4526279 --- /dev/null +++ b/contrib/libstdc++/tests/tstring.exp @@ -0,0 +1,22 @@ +an empty string: +A string initialized to Hello:Hello +A string initialized to previous string:Hello +A string initialized to (previous string, 1, 2):el +A string initialized to @:@ +A string initialized to 20:20 +n = 20 atoi(n) = 20 atof(n) = 20 +is = Hello +z = x + y = Helloworld +x += y; x = Helloworld +y.insert (0, x); y = Helloworld +x = x + y + x; x = HelloworldHello +x = y + x + x; x = worldHelloHello +z = x + s + + y.substr (y.find (w), 1) + y.substr (y.find (w) + 1) + . = Hello, world. +ch = x[0] = H +z = x.substr (2, 3) = llo +x.replace (2, 2, r); x = Hero +x.replace (0, 1, 'j'); x = jello +x = jeHelloo +enter a word:word =abcdefghijklmnopqrstuvwxyz length = 26 + +End of test diff --git a/contrib/libstdc++/tests/tstring.inp b/contrib/libstdc++/tests/tstring.inp new file mode 100644 index 0000000..b0883f3 --- /dev/null +++ b/contrib/libstdc++/tests/tstring.inp @@ -0,0 +1 @@ +abcdefghijklmnopqrstuvwxyz diff --git a/contrib/libstdc++/tests/tvector.cc b/contrib/libstdc++/tests/tvector.cc new file mode 100644 index 0000000..ef238ef --- /dev/null +++ b/contrib/libstdc++/tests/tvector.cc @@ -0,0 +1,20 @@ +#include <vector.h> +#include <iostream.h> +#include <algo.h> + +main () +{ + cout << "Fill of C array:\n"; + char x[50]; + fill (x, x+50, '/'); + fill (x+1, x+49, '*'); + copy (x, x+50, ostream_iterator<char>(cout)); + + cout << "\nFill of vector<char>:\n"; + + vector<char> cvec; + cvec.insert (cvec.begin(), 50, '/'); + fill (cvec.begin()+1, cvec.end()-1, '-'); + copy (cvec.begin(), cvec.end(), ostream_iterator<char>(cout)); + cout << endl; +} diff --git a/contrib/libstdc++/tests/tvector.exp b/contrib/libstdc++/tests/tvector.exp new file mode 100644 index 0000000..84a9d1b --- /dev/null +++ b/contrib/libstdc++/tests/tvector.exp @@ -0,0 +1,4 @@ +Fill of C array: +/************************************************/ +Fill of vector<char>: +/------------------------------------------------/ diff --git a/contrib/libstdc++/testsuite/ChangeLog b/contrib/libstdc++/testsuite/ChangeLog new file mode 100644 index 0000000..5809989 --- /dev/null +++ b/contrib/libstdc++/testsuite/ChangeLog @@ -0,0 +1,74 @@ +Sun Mar 14 02:38:07 PST 1999 Jeff Law (law@cygnus.com) + + * egcs-1.1.2 Released. + +Sun Jun 28 00:00:10 1998 Carlo Wood <carlo@runaway.xs4all.nl> + + * lib/libstdc++.exp: Use global variable ld_library_path (not local) + that is a lot more persistent; dejagnu-980528 needs this. + * lib/libstdc++.exp (test_stdc++): Use regular expression " -lstdc.." + to remove -lstdc++ arguments (not " -lstdc.*"). + +Thu Dec 25 00:34:03 1997 Jeffrey A Law (law@cygnus.com) + + * lib/libstdc++.exp (test_libstdc++): Set LD_LIBRARY_PATH + and SHLIB_PATH appropriately. + +Wed Sep 3 09:39:36 1997 Jeffrey A Law (law@cygnus.com) + + * lib/libstdc++.exp: Remove libg++_link_flags. + +Wed Aug 6 18:43:23 1997 Jason Merrill <jason@yorick.cygnus.com> + + * lib/libstdc++.exp: Remove libio_link_flags. + +Thu Jul 17 14:54:58 1997 Brendan Kehoe <brendan@lisa.cygnus.com> + + * lib/libstdc++.exp (base_dir): Move from here... + (test_libstdc++): To here. + (LIBSTDCPP): Delete unused global decl. + +Tue Jun 17 01:46:49 1997 Bob Manson <manson@farmer> + + * lib/libstdc++.exp: Strip off leading LFs from both the pattern + being matched against and the output from the board. Find the + correct multilib libstdc++ to link with. Use g++_link_flags + and libio_link_flags. Link in the status wrapper if needed. + (libstdc++_init): New procedure. + +Tue Jun 3 17:16:39 1997 Bob Manson <manson@charmed.cygnus.com> + + * lib/libstdc++.exp: Don't use global exec_output variable; the + output is returned from remote_load instead. + +Tue Apr 29 17:20:05 1997 Mike Stump <mrs@cygnus.com> + + * lib/libstdc++.exp: Fixup so that $compile_args works better. + * libstdc++.tests/test.exp: Also run with -O. + +Tue Apr 29 16:34:37 1997 Mike Stump <mrs@cygnus.com> + + * testsuite/lib/libstdc++.exp: Fixup so that we always have the + same number of testcases, and so that we have meaningful testcase + names. + +Tue Apr 29 13:05:14 1997 Bob Manson <manson@charmed.cygnus.com> + + * lib/libstdc++.exp: Add support for --tool_opts. + +Mon Apr 28 11:10:25 1997 Bob Manson <manson@charmed.cygnus.com> + + * Makefile.in: Add comment so target Makefile fragments get added. + Removed clean rule, because it is added by configure. + + * configure.in (TESTS): Add. + +Sun Apr 27 15:03:10 1997 Brendan Kehoe <brendan@lisa.cygnus.com> + + * Makefile.in (clean): Add empty rule for now. + +Fri Apr 25 18:59:14 1997 Bob Manson <manson@charmed.cygnus.com> + + * lib/libstdc++.exp(test_libstdc++): Return on error. Generate a + FAIL if the compile fails. Remove CRs from the output from the + testcase. diff --git a/contrib/libstdc++/testsuite/Makefile.in b/contrib/libstdc++/testsuite/Makefile.in new file mode 100644 index 0000000..b279d72 --- /dev/null +++ b/contrib/libstdc++/testsuite/Makefile.in @@ -0,0 +1,66 @@ +# Copyright (C) 1997 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 GNU CC; see the file COPYING. If not, write to +# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + +srcdir = libstdc++.tests + +EXPECT = `if [ -f $${rootme}/../../expect/expect ] ; then \ + echo $${rootme}/../../expect/expect ; \ + else echo expect ; fi` + +RUNTEST = `if [ -f $${srcdir}/../../dejagnu/runtest ] ; then \ + echo $${srcdir}/../../dejagnu/runtest ; \ + else echo runtest; fi` +RUNTESTFLAGS = + +#### package, host, target, and site dependent Makefile fragments come in here. +## + +.PHONY: all +all: + +.PHONY: check +check: all just-check + +site.exp: ./config.status Makefile + @echo "Making a new config file..." + -@rm -f ./tmp? + @touch site.exp + -@mv site.exp site.bak + @echo "## these variables are automatically generated by make ##" > ./tmp0 + @echo "# Do not edit here. If you wish to override these values" >> ./tmp0 + @echo "# add them to the last section" >> ./tmp0 + @echo "set host_alias $(host_alias)" >> ./tmp0 + @echo "set host_triplet ${host_canonical}" >> ./tmp0 + @echo "set target_alias $(target_alias)" >> ./tmp0 + @echo "set target_triplet ${target_canonical}" >> ./tmp0 + @echo "set build_triplet ${build_canonical}" >> ./tmp0 + @echo "set srcdir ${srcdir}" >> ./tmp0 + @echo "set tool libstdc++" >> ./tmp0 + @echo "## All variables above are generated by configure. Do Not Edit ##" >> ./tmp0 + @cat ./tmp0 > site.exp + @cat site.bak | sed \ + -e '1,/^## All variables above are.*##/ d' >> site.exp + -@rm -f ./tmp? + +just-check: site.exp + rootme=`pwd`; export rootme; \ + srcdir=${srcdir} ; export srcdir ; \ + EXPECT=${EXPECT} ; export EXPECT ; \ + if [ -f $${rootme}/../../expect/expect ] ; then \ + TCL_LIBRARY=$${srcdir}/../../tcl/library ; \ + export TCL_LIBRARY ; fi ; \ + $(RUNTEST) $(RUNTESTFLAGS) diff --git a/contrib/libstdc++/testsuite/config/default.exp b/contrib/libstdc++/testsuite/config/default.exp new file mode 100644 index 0000000..90967cc --- /dev/null +++ b/contrib/libstdc++/testsuite/config/default.exp @@ -0,0 +1 @@ +load_lib "standard.exp" diff --git a/contrib/libstdc++/testsuite/configure.in b/contrib/libstdc++/testsuite/configure.in new file mode 100644 index 0000000..ad5f232 --- /dev/null +++ b/contrib/libstdc++/testsuite/configure.in @@ -0,0 +1,24 @@ +# This file is a shell script fragment that supplies the information +# necessary for a configure script to process the program in +# this directory. For more information, look at ../../configure. + +configdirs= +srctrigger=configure.in +srcname="tests for ANSI C++ library, dejagnu style" +package_makefile_frag=Make.pack +package_makefile_rules_frag=Make.pack.r + +# per-host: + +# per-target: + +target_makefile_frag=../target-mkfrag + +TO_TOPDIR=../../ +ALL=' ' +XCXXINCLUDES="-I${srcdir}/.. -I${srcdir}/../stl -I${TO_TOPDIR}libio -I${srcdir}/${TO_TOPDIR}libio" +TESTS="tcomplex tstring tlist tmap tvector" +MOSTLYCLEAN="*.o core ${TESTS} *.out" +(. ${srcdir}/${TO_TOPDIR}libio/config.shared) >${package_makefile_frag} 2>${package_makefile_rules_frag} + +# post-target: diff --git a/contrib/libstdc++/testsuite/lib/libstdc++.exp b/contrib/libstdc++/testsuite/lib/libstdc++.exp new file mode 100644 index 0000000..3333dda --- /dev/null +++ b/contrib/libstdc++/testsuite/lib/libstdc++.exp @@ -0,0 +1,179 @@ +# Copyright (C) 1997 Free Software Foundation, Inc. + +# 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. + +# Please email any bugs, comments, and/or additions to this file to: +# bug-lib-g++@prep.ai.mit.edu + +# This file was written by Bob Manson. (manson@cygnus.com) + +load_lib "libgloss.exp" + +global tmpdir + +if ![info exists tmpdir] { + set tmpdir "/tmp" +} + +# +# Build the status wrapper library as needed. +# +proc libstdc++_init { args } { + global wrapper_file; + global wrap_compile_flags; + set wrapper_file ""; + set wrap_compile_flags ""; + if [target_info exists needs_status_wrapper] { + set result [build_wrapper "testglue.o"]; + if { $result != "" } { + set wrapper_file [lindex $result 0]; + set wrap_compile_flags [lindex $result 1]; + } else { + warning "Status wrapper failed to build." + } + } +} +# +# Run the test specified by srcfile and resultfile. compile_args and +# exec_args are additional arguments to be passed in when compiling and +# running the testcase, respectively. +# + +proc test_libstdc++ { options srcfile compile_args inpfile resultfile exec_args } { + global base_dir + global LIBSTDCPP + global srcdir subdir objdir + global TOOL_OPTIONS + global ld_library_path + + if [info exists LIBSTDCPP] { + set libstdcpp $LIBSTDCPP; + } else { + set gp [get_multilibs]; + if { $gp != "" } { + if [file exists "$gp/libstdc++/libstdc++.a"] { + set libstdcpp "-L$gp/libstdc++ -lstdc++"; + } + } + if ![info exists libstdcpp] { + set libstdcpp [findfile $base_dir/../../libstdc++/libstdc++.a "-L$base_dir/../../libstdc++ -lstdc++" -lstdc++] + } + } + + verbose "using LIBSTDCPP = $libstdcpp" 2 + set args "" + + # Basically we want to build up a colon separated path list from + # the value of $libstdcpp. + + # First strip away any -L arguments. + regsub -all -- "-L" $libstdcpp "" ld_library_path + + # Then remove any -lstdc++ argument. + regsub -all -- " -lstdc.." $ld_library_path "" ld_library_path + + # That's enough to make things work for the normal case. + # If we wanted to handle an arbitrary value of libstdcpp, + # then we'd have to do a lot more work. + + if { $compile_args != "" } { + lappend args "additional_flags=$compile_args" + } + lappend args "incdir=.." + lappend args "incdir=$srcdir/.." + lappend args "incdir=$srcdir/../stl" + lappend args "incdir=." + if [info exists TOOL_OPTIONS] { + lappend args "additional_flags=$TOOL_OPTIONS" + } + + global wrapper_file wrap_compile_flags; + # We have to include libio, for _G_config.h. + lappend args "additional_flags=$wrap_compile_flags"; + lappend args "libs=$wrapper_file"; + lappend args "libs=$libstdcpp"; + lappend args "additional_flags=[libio_include_flags]" + lappend args debug + + regsub "^.*/(\[^/.\]+)\[.\]\[^/]*$" "$srcfile" "\\1" out + set executable "${objdir}/$out" + set errname "[file tail $srcfile]" + if { $compile_args != "" } { + set errname "$errname $compile_args" + } + + if { [target_compile $srcfile "$executable" executable $args] != "" } { + fail "$errname compilation" + setup_xfail "*-*-*" + fail "$errname execution" + setup_xfail "*-*-*" + fail "$errname output" + return; + } + pass "$errname compilation" + + set result [libstdc++_load $executable "$exec_args" "$inpfile"]; + set status [lindex $result 0]; + set output [lindex $result 1]; + $status "$errname execution" + if { $status != "pass" } { + setup_xfail "*-*-*" + fail "$errname output" + return; + } + + verbose "resultfile is $resultfile" + set id [open $resultfile r]; + set expected "" + append expected [read $id]; + regsub -all "\r" "$output" "" output; + regsub "\n*$" $expected "" expected + regsub "\n*$" $output "" output + regsub "^\n*" $expected "" expected + regsub "^\n*" $output "" output + regsub -all "\[ \t\]\[ \t\]*" $expected " " expected + regsub -all "\[ \t\]*\n\n*" $expected "\n" expected + regsub -all "\[ \t\]\[ \t\]*" $output " " output + regsub -all "\[ \t\]*\n\n*" $output "\n" output + verbose "expected is $expected" + verbose "actual is $output" + set passed 0; + if {$options == "regexp_match"} { + if [regexp $expected $output] { + set passed 1; + } + } else { + if { $expected == $output } { + set passed 1; + } + } + if { $passed == 1 } { + pass "$errname output" + } else { + clone_output "expected was $expected" + clone_output "output was $output" + fail "$errname output" + } + close $id; +} + +# +# libstdc++_version -- extract and print the version number of libstdc++p +# +proc default_libstdc++_version {} { +} + +proc default_libstdc++_start { } { +} diff --git a/contrib/libstdc++/testsuite/libstdc++.tests/test.exp b/contrib/libstdc++/testsuite/libstdc++.tests/test.exp new file mode 100644 index 0000000..7368cfb --- /dev/null +++ b/contrib/libstdc++/testsuite/libstdc++.tests/test.exp @@ -0,0 +1,34 @@ +global srcdir subdir + +catch "glob -nocomplain $srcdir/$subdir/../../tests/*.exp" srcfiles +verbose "srcfiles are $srcfiles" + +set prefix "" +foreach x $srcfiles { + regsub "\\.exp$" $x "" prefix + set bname [file tail $prefix] + set args "" + if [file exists $srcdir/$subdir/${bname}.arg] { + set id [open "$srcdir/$subdir/${bname}.arg" r]; + set args [read -nonewline $id]; + close $id; + } + if [file exists $srcdir/$subdir/${bname}.xpo] { + set resfile "$srcdir/$subdir/${bname}.xpo" + set options "regexp_match" + } else { + set resfile "${prefix}.exp" + set options "" + } + + if [file exists ${prefix}.inp] { + set inpfile ${prefix}.inp + } else { + set inpfile "" + } + + verbose "inpfile is $inpfile" + + test_libstdc++ $options "${prefix}.cc" "" $inpfile $resfile $args + test_libstdc++ $options "${prefix}.cc" "-O" $inpfile $resfile $args +} |