diff options
author | obrien <obrien@FreeBSD.org> | 1999-10-16 03:52:48 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 1999-10-16 03:52:48 +0000 |
commit | b721bc1aede3b3211302d103a1de1019c732ce74 (patch) | |
tree | 0373fc465a78f12f63d0f0e1487af637156b8a58 /contrib | |
parent | 9f01c491d0571ee2f91980be244eaeef54bef145 (diff) | |
download | FreeBSD-src-b721bc1aede3b3211302d103a1de1019c732ce74.zip FreeBSD-src-b721bc1aede3b3211302d103a1de1019c732ce74.tar.gz |
Virgin import of GCC 2.95.1's libstdc++
Diffstat (limited to 'contrib')
88 files changed, 19910 insertions, 11364 deletions
diff --git a/contrib/libstdc++/ChangeLog b/contrib/libstdc++/ChangeLog index d29a773..4462244 100644 --- a/contrib/libstdc++/ChangeLog +++ b/contrib/libstdc++/ChangeLog @@ -1,17 +1,272 @@ -Sun Mar 14 02:38:07 PST 1999 Jeff Law (law@cygnus.com) +Mon Aug 16 01:29:24 PDT 1999 Jeff Law (law@cygnus.com) - * egcs-1.1.2 Released. + * gcc-2.95.1 Released. -Thu Feb 25 02:21:22 1999 Jeffrey A Law (law@cygnus.com) +Thu Aug 5 02:00:13 1999 Loren Rittle <ljrittle@acm.org> + + * Makefile.in (MARLINK, MSHLINK): Handle library version + number components with more than one numeric digit. + +Mon Aug 2 00:40:10 1999 Jeffrey A Law (law@cygnus.com) + + 1999-07-16 Markus Gyger (mgyger@gmu.edu) + * stdexcepti.cc (__out_of_range): Use std:: qualifier for names + in std. + (__length_error): Likewise. + +Wed Jul 28 21:39:31 PDT 1999 Jeff Law (law@cygnus.com) + + * gcc-2.95 Released. + +Sun Jul 25 23:40:51 PDT 1999 Jeff Law (law@cygnus.com) + + * gcc-2.95 Released. + +Sat Jul 17 23:49:59 1999 Jeffrey A Law (law@cygnus.com) + + * Makefile.in (INTERFACE): Bump to 3. + +Fri Jul 9 01:20:23 1999 Jeffrey A Law (law@cygnus.com) + + * Makefile.in (VERSION): Bump to 2.10.0. + +Tue Jun 8 00:21:11 1999 Jeffrey A Law (law@cygnus.com) + + * configure.in (*-*-freebsd2*): Add missing '*' at end of configure + string. + +1999-06-05 Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr> + + * std/std_valarray.h: Don't #include unconditionally <alloca.h> + +1999-06-05 Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr> + + * std/std_valarray.h: New file. + * std/slice.h: New file. + * std/slice_array.h: New file. + * std/gslice.h: New file. + * std/gslice_array.h: New file. + * std/mask_array.h: New file. + * std/indirect_array.h: New file. + * std/valarray_array.h: New file. + * std/valarray_array.tcc: New file. + * std/valarray_meta.h: New file. + * valarray.cc: New file. + * valarray: New file + + * Makefile.in (OBJS): add valarray.o + (HEADERS): add valarray + (valarray.o): define dependency on valarray.cc + (install): make it possible to install valarray file. + +Wed Jun 2 00:21:54 1999 Robert Lipe <robertlipe@usa.net> + + * std/bastring.h (class basic_string:Rep): Encode xlock opcode + as .bytes instead of mnemonics. + +1999-05-20 Angela Marie Thomas <angela@cygnus.com> + + * configure.in: Test for ${compiler_name}.exe as well. + +1999-05-15 Mark Kettenis <kettenis@gnu.org> + + * configure.in: Add shared library support for the Hurd + (*-*-gnu*). + * config/gnu.ml: New file. + +1999-05-12 Jason Merrill <jason@yorick.cygnus.com> + + * configure.in (compiler_name): Don't do the skip-this-dir thing + if we're reconfiguring. + +1999-05-07 Ulrich Drepper <drepper@cygnus.com> + + * std/bastring.h (class basic_string::Rep): Make release member + function thread-safe for ix86 (x>=4) and UltraSPARC. + + * stlinst.cc: Make it possible to compile with __USE_MALLOC. + +Mon Apr 26 02:24:47 1999 "Loren J. Rittle" <rittle@supra.rsch.comm.mot.com> + + * config/freebsd.ml (LIBS): Add ARLINK. + * config/openbsd.ml (LIBS): Add ARLINK. + +Fri Apr 2 15:12:14 1999 H.J. Lu (hjl@gnu.org) + + * libstdc++/configure.in (gxx_include_dir): Handle it. + * libstdc++/Makefile.in: Likewise. + +Wed Mar 24 22:36:45 1999 Mumit Khan <khan@xraylith.wisc.edu> + + * configure.in (EXEEXT): Define. + (compiler_name): Use. + +Thu Mar 11 01:07:55 1999 Franz Sirl <Franz.Sirl-kernel@lauterbach.com> + + * configure.in: Add mh-*pic handling for alpha, arm, powerpc + +Fri Mar 5 02:16:39 1999 Doug Rabson <dfr@freebsd.org> + + * configure.in: Support shared libs on FreeBSD 3.x and 4.x + * config/freebsd.ml: A copy of config/linux.ml since they are both + ELF and both have a shared libm. + +1999-02-24 Jason Merrill <jason@yorick.cygnus.com> + + * configure.in: Fix INSTALLDIR sed pattern for Solaris sed. + +Sat Feb 20 13:17:17 1999 Jeffrey A Law (law@cygnus.com) + + * string, std/straits.h, std/bastring.h: Revert recent change. Needs + some libiberty support before it can be re-enabled. + +Thu Feb 18 19:53:17 1999 Marc Espie <espie@cvs.openbsd.org> - 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> +1999-02-04 Ulrich Drepper <drepper@cygnus.com> + + * configure.in: Recognize --enable-threads=posix for all + platforms. + * config/posix.mt: New file. + + * configure.in: Add fragments for Solaris defining macro specifying + thread library to be used. + * config/sol2pth.mt: New file + * config/sol2solth.mt: New file. + * stl/stl_alloc.h: Add support for Solaris thread library. + * stl/stl_config.h: Recognize _SOLTHREADS and define internal macros + appropriately. + +1999-01-28 Baron Roberts <baron@sgi.com> + + * string: Uncomment wstring declaration. + + * std/straits.h: Remove #if 0/#endif from around + struct string_char_traits <wchar_t>. + #include <cwchar>. + Add missing definition for wchar_t move method. + Add empty() method for trait-based empty string return. + + * std/bastring.h (c_str): Change return of "" to return of + traits::empty() call so that proper empty string is returned + based on the character type (i.e. "" or L""). + +1999-02-07 Jason Merrill <jason@yorick.cygnus.com> + + * Makefile.in (stuff2): Tweak. + +1999-02-04 Ulrich Drepper <drepper@cygnus.com> + + * configure.in: Recognize --enable-threads=posix for all + platforms. + * config/posix.mt: New file. + + * configure.in: Add fragments for Solaris defining macro specifying + thread library to be used. + * config/sol2pth.mt: New file + * config/sol2solth.mt: New file. + * stl/stl_alloc.h: Add support for Solaris thread library. + * stl/stl_config.h: Recognize _SOLTHREADS and define internal macros + appropriately. + +Sat Jan 30 08:05:46 1999 Mumit Khan <khan@xraylith.wisc.edu> + + * config/x86-interix.ml: New file. + * configure.in (i[3456]86-*-interix*): Add shared library support. + +1999-01-13 Ulrich Drepper <drepper@cygnus.com> + + * configure.in: Test for "ln -s" and set LN_S in generated Makefile. + * Makefile.in: Use $(LN_S) instead of explicitly ln -s. + +Sun Jan 03 03:16:02 1999 Robert Lipe <robertlipe@usa.net> + + * configure.in: (*-*-sysv5, *-*-*udk*): Treat like sysv4. + +Tue Dec 8 00:59:09 1998 Marc Espie <Marc.Espie@liafa.jussieu.fr> + + * Makefile.in: Be more selective about what files to install. + +1998-11-30 Ulrich Drepper <drepper@cygnus.com> + + * std/bastring.cc (operator>>): Correct cast in last patch. + (getline): Likewise. + +1998-11-27 Alexandre Oliva <oliva@dcc.unicamp.br> + + * Makefile.in (HEADERS): Install bitset. + +1998-11-26 Manfred Hollstein <manfred@s-direktnet.de> + + * configure.in (compiler_name): Add check to detect if this + language's compiler has been built. + +1998-11-23 Ulrich Drepper <drepper@cygnus.com> + + * std/bastring.cc (operator>>): Cast new character to char before + adding to string. + (getline): Likewise. + +Thu Sep 17 01:29:46 1998 H.J. Lu (hjl@gnu.org) + + * Makefile.in ($(ARLINK), $(SHLINK)): Don't rely on 'ln -f'. + + * Makefile.in (install): Don't rely on 'ln -f'. + +1998-09-09 Manfred Hollstein <manfred@s-direktnet.de> + + * Makefile.in (install): Initialize RELINSTALLDIR correctly + even for multilib and cross configurations. + + * configure.in (INSTALLDIR): Don't change INSTALLDIR's init + value if --enable-version-specific-runtime-libs has been specified. + +Wed Sep 2 21:11:15 1998 H.J. Lu (hjl@gnu.org) + + * Makefile.in (RELINSTALLDIR): New. Use it to make symlinks. + + * configure.in: Fix INSTALLDIR replacement for cross-compile. + +Sun Aug 30 22:17:41 1998 H.J. Lu (hjl@gnu.org) + + * Makefile.in (INTERFACE): New, set to 2. + (ARLIB): Set to libstdc++.a.$(VERSION) + (ARLINK, MARLINK): New macros. + (LIBS): Add $(ARLINK). + ($(ARLINK), marlink): New targets. + (install): Don't check $(libsubdir). Handle versioned libraries. + + * config/linux.ml (ARLIB, MARLINK, SHLIB, MSHLINK): New macros. + (LIBS): Add marlink $(ARLINK). + + * config/aix.ml (ARLIB): Set to libstdc++-ar.a.$(VERSION) + (ARLINK): New macros. + (BUILD_LIBS): Add $(ARLINK). + + * config/dec-osf.ml (LIBS): Add $(ARLINK). + * config/elf.ml (LIBS): Likewise. + * config/elfshlibm.ml (LIBS): Likewise. + * config/hpux.ml (LIBS): Likewise. + * config/iris5.ml (LIBS): Likewise. + * config/sol2shm.ml (LIBS): Likewise. + * config/sunos4.ml (LIBS): Likewise. + + * configure.in: Use ${topsrcdir}/config.if to put + LIBSTDCXX_INTERFACE, CXX_INTERFACE, LIBC_INTERFACE in + ${package_makefile_frag}. + +1998-08-25 Martin von Löwis <loewis@informatik.hu-berlin.de> + + * stdexcept: Remove __HONOR_STD. + +1998-08-23 Mark Mitchell <mark@markmitchell.com> - * configure.in: Append mh-ppcpic and mh-elfalphapic as appropriate. + * sinst.cc: Don't explicitly instantiation string_char_traits<char>. + * cinst.cc: Likewiwse, for complex<float>, complex<double>, + complex<long double>. 1998-08-17 Mark Mitchell <mark@markmitchell.com> @@ -262,7 +517,7 @@ Tue Sep 9 19:47:07 1997 Jason Merrill <jason@yorick.cygnus.com> Wed Aug 27 00:04:33 1997 Alexandre Oliva (oliva@dcc.unicamp.br) - * Makefile.in: create correct multiple links to + * Makefile.in: Create correct multiple links to shared libstdc++. Tue Aug 26 12:24:01 1997 H.J. Lu (hjl@gnu.ai.mit.edu) diff --git a/contrib/libstdc++/Makefile.in b/contrib/libstdc++/Makefile.in index 77e2ec9..eb9ec77 100644 --- a/contrib/libstdc++/Makefile.in +++ b/contrib/libstdc++/Makefile.in @@ -14,9 +14,12 @@ # along with 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 +VERSION = 2.10.0 +INTERFACE = 3 -OBJS = cstringi.o stdexcepti.o cstdlibi.o cmathi.o stlinst.o +gxx_include_dir=${includedir}/g++ + +OBJS = cstringi.o stdexcepti.o cstdlibi.o cmathi.o stlinst.o valarray.o SUBLIBS = $(STAMP)-string $(STAMP)-complx # C++ headers with no extension @@ -25,19 +28,21 @@ HEADERS= cassert cctype cerrno cfloat ciso646 climits clocale cmath complex \ 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 + vector fstream iomanip iostream strstream iosfwd bitset valarray -ARLIB = libstdc++.a +ARLIB = libstdc++.a.$(VERSION) +ARLINK = libstdc++.a +MARLINK = libstdc++.a.`echo $(VERSION) | sed 's/\([0-9]*[.][0-9]*\).*/\1/'` SHLIB = libstdc++.so.$(VERSION) SHARLIB = libstdc++-sh.a SHLINK = libstdc++.so -MSHLINK = libstdc++.so.`echo $(VERSION) | sed 's/\([0-9][.][0-9]\).*/\1/'` -SHFLAGS = +MSHLINK = libstdc++.so.`echo $(VERSION) | sed 's/\([0-9]*[.][0-9]*\).*/\1/'` +SHFLAGS = SHDEPS = STAMP = bigstmp -LIBS = $(ARLIB) +LIBS = $(ARLIB) $(ARLINK) #### package, host, target, and site dependent Makefile fragments come in here. ## @@ -85,6 +90,13 @@ $(ARLIB): stdlist mv t$(ARLIB) $(ARLIB) $(RANLIB) $(ARLIB) +$(ARLINK): + -rm -f $(ARLINK) + $(LN_S) $(ARLIB) $(ARLINK) || cp $(ARLIB) $(ARLINK) + +marlink: + @$(MAKE) $(MARLINK) "ARLINK=$(MARLINK)" + $(SHLIB): piclist $(CC) $(LIBCXXFLAGS) $(SHFLAGS) -shared -o $(SHLIB) `cat piclist` $(SHDEPS) @@ -95,7 +107,8 @@ $(SHARLIB): $(SHLIB) $(RANLIB) $(SHARLIB) $(SHLINK): - ln -f -s $(SHLIB) $(SHLINK) + -rm -f $(SHLINK) + $(LN_S) $(SHLIB) $(SHLINK) || cp $(ARLIB) $(ARLINK) mshlink: @$(MAKE) $(MSHLINK) "SHLINK=$(MSHLINK)" @@ -117,6 +130,7 @@ cstdlibi.o: cstdlibi.cc cmathi.o: cmathi.cc stdexcepti.o: stdexcepti.cc stlinst.o: stlinst.cc +valarray.o: valarray.cc # Later do wide strings, too. stmp-string: ${srcdir}/sinst.cc ${srcdir}/std/bastring.h \ @@ -256,7 +270,7 @@ install: fi ; \ chmod a-x $(gxx_include_dir)/$$FILE ; \ done ; \ - for FILE in *.h std/*.*; do \ + for FILE in *.h std/*.h std/*.cc std/*.tcc; do \ rm -f $(gxx_include_dir)/$$FILE ; \ $(INSTALL_DATA) $$FILE $(gxx_include_dir)/$$FILE ; \ chmod a-x $(gxx_include_dir)/$$FILE ; \ @@ -270,20 +284,68 @@ install: else true ; \ fi rootme=`pwd`/ ; export rootme ; \ - if [ x$(libsubdir) = x ] || [ x$(enable_version_specific_runtime_libs) != xyes ]; then \ + if [ x$(enable_version_specific_runtime_libs) != xyes ]; then \ INSTALLDIR=$(libdir); \ else \ INSTALLDIR=$(libsubdir); \ fi; \ - rm -f $${INSTALLDIR}$(MULTISUBDIR)/$(SHLINK) ; \ + INSTALLLINKDIR=$(libsubdir); \ + if [ $${INSTALLLINKDIR}$(MULTISUBDIR) = $${INSTALLDIR}$(MULTISUBDIR) ]; then \ + RELINSTALLDIR=; \ + elif [ x$(MULTISUBDIR) = x ]; then \ + if [ $(build_alias) = $(target_alias) ]; then \ + RELINSTALLDIR=../../../; \ + else \ + RELINSTALLDIR=../../../../$(target_alias)/lib/; \ + fi; \ + else \ + if [ $(build_alias) = $(target_alias) ]; then \ + RELINSTALLDIR=../../..`echo $(MULTISUBDIR) | sed -e 's,/[^/]*,/..,g'`$(MULTISUBDIR)/; \ + else \ + RELINSTALLDIR=../../../..`echo $(MULTISUBDIR) | sed -e 's,/[^/]*,/..,g'`/$(target_alias)/lib$(MULTISUBDIR)/; \ + fi; \ + fi; \ + if [ $(build_alias) != $(target_alias) ]; then \ + case $$RELINSTALLDIR in \ + ../../../|../../../../) \ + RELINSTALLDIR=../$${RELINSTALLDIR}$(target_alias)/lib/;; \ + esac; \ + fi; \ + rm -f $${INSTALLLINKDIR}$(MULTISUBDIR)/$(SHLINK) ; \ + rm -f $${INSTALLLINKDIR}$(MULTISUBDIR)/$(ARLINK) ; \ for FILE in $(LIBS) ; do \ rm -f $${INSTALLDIR}$(MULTISUBDIR)/$$FILE ; \ if [ $$FILE = $(SHLINK) ] ; then \ - ln -f -s $(SHLIB) $${INSTALLDIR}$(MULTISUBDIR)/$$FILE ; \ + if [ -f $${INSTALLDIR}/$(MSHLINK) ]; then \ + rm -f $${INSTALLLINKDIR}$(MULTISUBDIR)/$$FILE ; \ + $(LN_S) $${RELINSTALLDIR}$(MSHLINK) $${INSTALLLINKDIR}$(MULTISUBDIR)/$$FILE \ + || cp $${RELINSTALLDIR}$(MSHLINK) $${INSTALLLINKDIR}$(MULTISUBDIR)/$$FILE ; \ + else \ + rm -f $${INSTALLLINKDIR}$(MULTISUBDIR)/$$FILE ; \ + $(LN_S) $${RELINSTALLDIR}$(SHLIB) $${INSTALLLINKDIR}$(MULTISUBDIR)/$$FILE \ + || cp $${RELINSTALLDIR}$(SHLIB) $${INSTALLLINKDIR}$(MULTISUBDIR)/$$FILE ; \ + fi; \ + elif [ $$FILE = $(ARLINK) ] ; then \ + if [ -f $${INSTALLDIR}/$(MARLINK) ]; then \ + rm -f $${INSTALLLINKDIR}$(MULTISUBDIR)/$$FILE ; \ + $(LN_S) $${RELINSTALLDIR}$(MARLINK) $${INSTALLLINKDIR}$(MULTISUBDIR)/$$FILE \ + || cp $${RELINSTALLDIR}$(MARLINK) $${INSTALLLINKDIR}$(MULTISUBDIR)/$$FILE ; \ + else \ + rm -f $${INSTALLLINKDIR}$(MULTISUBDIR)/$$FILE ; \ + $(LN_S) $${RELINSTALLDIR}$(ARLIB) $${INSTALLLINKDIR}$(MULTISUBDIR)/$$FILE \ + || cp $${RELINSTALLDIR}$(ARLIB) $${INSTALLLINKDIR}$(MULTISUBDIR)/$$FILE ; \ + fi; \ elif [ $$FILE = mshlink ]; then \ for FILE in $(MSHLINK) ; do \ rm -f $${INSTALLDIR}$(MULTISUBDIR)/$$FILE ; \ - ln -f -s $(SHLIB) $${INSTALLDIR}$(MULTISUBDIR)/$$FILE ; \ + $(LN_S) $(SHLIB) $${INSTALLDIR}$(MULTISUBDIR)/$$FILE \ + || cp $(SHLIB) $${INSTALLDIR}$(MULTISUBDIR)/$$FILE ; \ + done; \ + elif [ $$FILE = marlink ]; then \ + for FILE in $(MARLINK) ; do \ + rm -f $${INSTALLDIR}$(MULTISUBDIR)/$$FILE ; \ + $(LN_S) $(ARLIB) $${INSTALLDIR}$(MULTISUBDIR)/$$FILE \ + || cp $(ARLIB) $${INSTALLDIR}$(MULTISUBDIR)/$$FILE ; \ done; \ elif [ $$FILE = $(SHLIB) ]; then \ $(INSTALL_PROGRAM) $$FILE $${INSTALLDIR}$(MULTISUBDIR)/$$FILE ; \ @@ -301,8 +363,7 @@ install: .PHONY: force force: -# Remove these for public releases. -MYCXXFLAGS = -g -O2 -Wpointer-arith -Wnested-externs -Woverloaded-virtual -Wbad-function-cast -Winline -Wwrite-strings +MYCXXFLAGS = -g -O2 -Wpointer-arith -Wnested-externs -Woverloaded-virtual -Wbad-function-cast -Winline -Wwrite-strings -pedantic -Wno-long-long MYCFLAGS = -g -O2 -Wpointer-arith -Wnested-externs .PHONY: stuff @@ -316,7 +377,8 @@ stuff1: touch ../../gcc/libgcc2.ready stuff2: - -$(MAKE) -C ../../gcc/ libgcc.a - -$(MAKE) check CXXFLAGS="$(MYCXXFLAGS)" CFLAGS="$(MYCFLAGS)" + $(MAKE) -C ../../gcc/ libgcc.a + $(MAKE) CXXFLAGS="$(MYCXXFLAGS)" CFLAGS="$(MYCFLAGS)" + -$(MAKE) check -$(MAKE) -C ../libio check -$(MAKE) -C ../../gcc check-g++ diff --git a/contrib/libstdc++/cinst.cc b/contrib/libstdc++/cinst.cc index 010f3ca..983e8a9 100644 --- a/contrib/libstdc++/cinst.cc +++ b/contrib/libstdc++/cinst.cc @@ -32,7 +32,6 @@ 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); diff --git a/contrib/libstdc++/config/aix.ml b/contrib/libstdc++/config/aix.ml index cd96870..dec7a90 100644 --- a/contrib/libstdc++/config/aix.ml +++ b/contrib/libstdc++/config/aix.ml @@ -1,8 +1,9 @@ # AIX has wierd shared/non-shared libraries. -ARLIB = libstdc++-ar.a +ARLIB = libstdc++-ar.a.$(VERSION) +ARLINK = libstdc++-ar.a SHLINK = libstdc++.a -LIBS = $(ARLIB) $(SHLIB) $(SHLINK) +LIBS = $(ARLIB) $(ARLINK) $(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 index 618c6c8..a11f373 100644 --- a/contrib/libstdc++/config/dec-osf.ml +++ b/contrib/libstdc++/config/dec-osf.ml @@ -1,6 +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) +LIBS = $(ARLIB) $(ARLINK) $(SHLIB) $(SHLINK) DEPLIBS = ../$(SHLIB) SHDEPS = -lm diff --git a/contrib/libstdc++/config/elf.ml b/contrib/libstdc++/config/elf.ml index 2a5f336..bd711de 100644 --- a/contrib/libstdc++/config/elf.ml +++ b/contrib/libstdc++/config/elf.ml @@ -1,7 +1,7 @@ # Elf without shared libm -- we have to link with the archive library, even # for programs that don't use complex. -LIBS = $(ARLIB) $(SHLIB) $(SHLINK) +LIBS = $(ARLIB) $(ARLINK) $(SHLIB) $(SHLINK) SHFLAGS = -h $(SHLIB) DEPLIBS = ../$(SHLIB) LDLIBS = -L.. -lstdc++ -lm diff --git a/contrib/libstdc++/config/elfshlibm.ml b/contrib/libstdc++/config/elfshlibm.ml index fe2bf3f..826f0bc 100644 --- a/contrib/libstdc++/config/elfshlibm.ml +++ b/contrib/libstdc++/config/elfshlibm.ml @@ -1,6 +1,6 @@ # Elf with shared libm, so we can link it into the shared libstdc++. -LIBS = $(ARLIB) $(SHLIB) $(SHLINK) +LIBS = $(ARLIB) $(ARLINK) $(SHLIB) $(SHLINK) SHFLAGS = -h $(SHLIB) SHDEPS = -lm DEPLIBS = ../$(SHLIB) diff --git a/contrib/libstdc++/config/freebsd.ml b/contrib/libstdc++/config/freebsd.ml new file mode 100644 index 0000000..3ee6826 --- /dev/null +++ b/contrib/libstdc++/config/freebsd.ml @@ -0,0 +1,6 @@ +# Elf with shared libm, so we can link it into the shared libstdc++. + +LIBS = $(ARLIB) $(ARLINK) $(SHLIB) $(SHLINK) mshlink +SHFLAGS = -Wl,-soname,$(MSHLINK) +SHDEPS = -lm +DEPLIBS = ../$(SHLIB) diff --git a/contrib/libstdc++/config/gnu.ml b/contrib/libstdc++/config/gnu.ml new file mode 100644 index 0000000..2a03803 --- /dev/null +++ b/contrib/libstdc++/config/gnu.ml @@ -0,0 +1,6 @@ +# Elf with shared libm, so we can link it into the shared libstdc++. + +LIBS = $(ARLIB) $(ARLINK) $(SHLIB) $(SHLINK) +SHFLAGS = -Wl,-soname,$(SHLIB) +SHDEPS = -lm +DEPLIBS = ../$(SHLIB) diff --git a/contrib/libstdc++/config/hpux.ml b/contrib/libstdc++/config/hpux.ml index 1531fe8..a39602a 100644 --- a/contrib/libstdc++/config/hpux.ml +++ b/contrib/libstdc++/config/hpux.ml @@ -1,6 +1,6 @@ # HPUX uses the .sl suffix for shared libraries. SHLIB = libstdc++.sl -LIBS = $(ARLIB) $(SHLIB) +LIBS = $(ARLIB) $(ARLINK) $(SHLIB) DEPLIBS = ../$(SHLIB) SHFLAGS = $(PICFLAG) diff --git a/contrib/libstdc++/config/irix5.ml b/contrib/libstdc++/config/irix5.ml index 6b33445..055c832 100644 --- a/contrib/libstdc++/config/irix5.ml +++ b/contrib/libstdc++/config/irix5.ml @@ -1,6 +1,6 @@ # We don't need -fpic on IRIX, so let's install both the shared and # non-shared versions. -LIBS = $(ARLIB) $(SHLIB) $(SHLINK) +LIBS = $(ARLIB) $(ARLINK) $(SHLIB) $(SHLINK) DEPLIBS = ../$(SHLIB) SHDEPS = -lm diff --git a/contrib/libstdc++/config/linux.ml b/contrib/libstdc++/config/linux.ml index 7e6eece..14dcb45 100644 --- a/contrib/libstdc++/config/linux.ml +++ b/contrib/libstdc++/config/linux.ml @@ -1,6 +1,11 @@ # Elf with shared libm, so we can link it into the shared libstdc++. -LIBS = $(ARLIB) $(SHLIB) $(SHLINK) mshlink +ARLIB = libstdc++-$(LIBSTDCXX_INTERFACE)$(LIBC_INTERFACE)$(CXX_INTERFACE)-$(VERSION).a +MARLINK = libstdc++$(LIBC_INTERFACE)$(CXX_INTERFACE).a.$(LIBSTDCXX_INTERFACE) +SHLIB = libstdc++-$(LIBSTDCXX_INTERFACE)$(LIBC_INTERFACE)$(CXX_INTERFACE)-$(VERSION).so +MSHLINK = libstdc++$(LIBC_INTERFACE)$(CXX_INTERFACE).so.$(LIBSTDCXX_INTERFACE) + +LIBS = $(ARLIB) marlink $(ARLINK) $(SHLIB) mshlink $(SHLINK) SHFLAGS = -Wl,-soname,$(MSHLINK) SHDEPS = -lm DEPLIBS = ../$(SHLIB) diff --git a/contrib/libstdc++/config/openbsd.ml b/contrib/libstdc++/config/openbsd.ml index 0d278f6..09c4023 100644 --- a/contrib/libstdc++/config/openbsd.ml +++ b/contrib/libstdc++/config/openbsd.ml @@ -1,6 +1,6 @@ # Base shared lib for OpenBSD i386 -LIBS = $(ARLIB) $(SHLIB) $(SHLINK) mshlink +LIBS = $(ARLIB) $(ARLINK) $(SHLIB) $(SHLINK) mshlink SHFLAGS = -nostdlib -Wl,-Bshareable,-Bforcearchive SHDEPS = -lm DEPLIBS = ../$(SHLIB) diff --git a/contrib/libstdc++/config/posix.mt b/contrib/libstdc++/config/posix.mt new file mode 100644 index 0000000..6afe1e5 --- /dev/null +++ b/contrib/libstdc++/config/posix.mt @@ -0,0 +1 @@ +MT_CFLAGS = -D_PTHREADS diff --git a/contrib/libstdc++/config/sol2pth.mt b/contrib/libstdc++/config/sol2pth.mt new file mode 100644 index 0000000..6afe1e5 --- /dev/null +++ b/contrib/libstdc++/config/sol2pth.mt @@ -0,0 +1 @@ +MT_CFLAGS = -D_PTHREADS diff --git a/contrib/libstdc++/config/sol2shm.ml b/contrib/libstdc++/config/sol2shm.ml index f02650c..e87f079 100644 --- a/contrib/libstdc++/config/sol2shm.ml +++ b/contrib/libstdc++/config/sol2shm.ml @@ -1,6 +1,6 @@ # Solaris2 with shared libm, so we can link it into the shared libstdc++. -LIBS = $(ARLIB) $(SHLIB) $(SHLINK) +LIBS = $(ARLIB) $(ARLINK) $(SHLIB) $(SHLINK) SHFLAGS = -h $(SHLIB) SHDEPS = -lm DEPLIBS = ../$(SHLIB) diff --git a/contrib/libstdc++/config/sol2solth.mt b/contrib/libstdc++/config/sol2solth.mt new file mode 100644 index 0000000..f809d0a --- /dev/null +++ b/contrib/libstdc++/config/sol2solth.mt @@ -0,0 +1 @@ +MT_CFLAGS = -D_SOLTHREADS diff --git a/contrib/libstdc++/config/sunos4.ml b/contrib/libstdc++/config/sunos4.ml index 0abc13c..3c5de27 100644 --- a/contrib/libstdc++/config/sunos4.ml +++ b/contrib/libstdc++/config/sunos4.ml @@ -2,7 +2,7 @@ # library, even for programs that don't use complex. # SunOS requires a version number in shared library filenames. -LIBS = $(ARLIB) $(SHLIB) +LIBS = $(ARLIB) $(ARLINK) $(SHLIB) SHFLAGS = $(PICFLAG) DEPLIBS = ../$(SHLIB) LDLIBS = -L.. -lstdc++ -lm diff --git a/contrib/libstdc++/config/x86-interix.ml b/contrib/libstdc++/config/x86-interix.ml new file mode 100644 index 0000000..8b8774e --- /dev/null +++ b/contrib/libstdc++/config/x86-interix.ml @@ -0,0 +1,9 @@ +# x86 Interix. SHLINK is defined to be .dummy to avoid running into +# the lack of symbolic links. + +SHLINK = .dummy +SHLIB = libstdc++.so +LIBS = $(ARLIB) $(SHLIB) +DEPLIBS = ../$(SHLIB) +SHFLAGS = $(PICFLAG) + diff --git a/contrib/libstdc++/configure.in b/contrib/libstdc++/configure.in index 204d4a8..bd2c9c7 100644 --- a/contrib/libstdc++/configure.in +++ b/contrib/libstdc++/configure.in @@ -2,6 +2,25 @@ # necessary for a configure script to process the program in # this directory. For more information, look at ../configure. +# If the language specific compiler does not exist, but the "gcc" directory +# does, we do not build anything. Note, $r is set by the top-level Makefile. +# Note that when we look for the compiler, we search both with and without +# extension to handle cross and canadian cross builds. +# Note that if $norecursion is set we're being called from config.status, +# so don't check for the compiler; we might be doing a make clean. +compiler_name=cc1plus +rm -f skip-this-dir +if test -n "$r" && [ -z "$norecursion" ] ; then + if test -d "$r"/gcc; then + if test -f "$r"/gcc/$compiler_name \ + || test -f "$r"/gcc/$compiler_name.exe; then + true + else + echo "rm -f multilib.out" > skip-this-dir + fi + fi +fi + if [ "${srcdir}" = "." ] ; then if [ "${with_target_subdir}" != "." ] ; then topsrcdir=${with_multisrctop}../.. @@ -39,14 +58,12 @@ esac if [ "${shared}" = "yes" ]; then case "${target}" in + alpha*-*-linux*) frags=../../config/mh-elfalphapic ;; + arm*-*-*) frags=../../config/mh-armpic ;; 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 ;; - + powerpc*-*-aix*) ;; + powerpc*-*-*) frags=../../config/mh-ppcpic ;; *-*-*) frags=../../config/mh-${target_cpu}pic ;; esac case "${target}" in @@ -54,12 +71,16 @@ if [ "${shared}" = "yes" ]; then *-*-hpux*) frags="${frags} hpux.ml" ;; *-*-irix[56]*) frags="${frags} irix5.ml" ;; *-*-linux*aout*) ;; + *-*-freebsd2*) ;; + *-*-freebsd*) frags="${frags} freebsd.ml" ;; *-*-linux*) frags="${frags} linux.ml" ;; *-*-openbsd*) frags="${frags} openbsd.ml" ;; - *-*-sysv4*) frags="${frags} elf.ml" ;; + *-*-sysv[45]*|*-*-udk*) frags="${frags} elf.ml" ;; *-*-solaris*) frags="${frags} sol2shm.ml" ;; *-*-sunos4*) frags="${frags} sunos4.ml" ;; *-*-aix*) frags="${frags} aix.ml" ;; + i[3456]86-*-interix*) frags="${frags} x86-interix.ml" ;; + *-*-gnu*) frags="${frags} gnu.ml" ;; esac fi @@ -73,6 +94,15 @@ case "${target}" in xyes|xposix) frags="${frags} openbsd.mt" ;; esac;; m68k-motorola-sysv) frags="${frags} delta.mt" ;; + *-*-solaris*) + case "x${enable_threads}" in + xposix) frags="${frags} sol2pth.mt" ;; + xsolaris) frags="${frags} sol2solth.mt" ;; + esac ;; + *) + case "x${enable_threads}" in + xposix) frags="${frags} posix.mt" ;; + esac ;; esac for frag in ${frags}; do @@ -105,15 +135,69 @@ EXTRA_DISTCLEAN='target-mkfrag' (. ${srcdir}/${TO_TOPDIR}libio/config.shared) >${package_makefile_frag} 2>${package_makefile_rules_frag} +. ${topsrcdir}/config.if +echo " +LIBSTDCXX_INTERFACE=${libstdcxx_interface} +CXX_INTERFACE=${cxx_interface} +LIBC_INTERFACE=${libc_interface} +" >> ${package_makefile_frag} + +# This duplicated the AC_PROG_LN_S macro in GNU autoconf. +rm -f conttestdata +if ln -s X conftestdata 2>/dev/null +then + rm -f conftestdata + LN_S="ln -s" +else + LN_S=ln +fi +echo " +LN_S=$LN_S +" >> ${package_makefile_frag} + # post-target: -# If cross-compiling, we install in $(tooldir). +# If cross-compiling, we install in $(tooldir)/lib or in $(libsubdir) +# depending on --enable-version-specific-runtime-libs. if [ -n "${with_cross_host}" ] ; then rm -f Makefile.tem sed \ - -e 's|\(INSTALLDIR[ ]*=[ ]*\)[^ ;]*|\1$(tooldir)/lib|' \ + -e 's|^\([ ]*INSTALLDIR[ ]*=[ ]*\)\$(libdir)|\1$(tooldir)/lib|' \ Makefile >Makefile.tem mv -f Makefile.tem Makefile fi +# enable multilib-ing by default. +if [ -z "${enable_multilib}" ]; then + enable_multilib=yes +fi + . ${topsrcdir}/config-ml.in + +gxx_include_dir= +# Specify the g++ header file directory +# Check whether --with-gxx-include-dir or --without-gxx-include-dir was given. +if test "${with_gxx_include_dir+set}" = set; then + withval="$with_gxx_include_dir" + case "${withval}" in + yes) + echo "configure.in: error: bad value ${withval} given for g++ include directory" 1>&2 + exit 1 + ;; + no) ;; + *) gxx_include_dir=$with_gxx_include_dir ;; + esac +fi + +if test x${gxx_include_dir} = x; then + if test x${enable_version_specific_runtime_libs} = xyes; then + gxx_include_dir='${libsubdir}/include/g++' + else + gxx_include_dir='${prefix}/include/g++'-${libstdcxx_interface} + fi +fi + +rm -f Makefile.tem +sed -e "s%^gxx_include_dir[ ]*=.*$%gxx_include_dir=${gxx_include_dir}%" \ + Makefile >Makefile.tem +mv -f Makefile.tem Makefile diff --git a/contrib/libstdc++/sinst.cc b/contrib/libstdc++/sinst.cc index 79c31a3..0b3617e 100644 --- a/contrib/libstdc++/sinst.cc +++ b/contrib/libstdc++/sinst.cc @@ -42,8 +42,11 @@ typedef char c; typedef wchar_t c; #endif -#ifdef TRAITS +#if defined(TRAITS) && !defined(C) template class string_char_traits <c>; +#else +/* string_char_traits<char> is already explicitly specialized in + std/straits.h. */ #endif typedef basic_string <c> s; diff --git a/contrib/libstdc++/std/bastring.cc b/contrib/libstdc++/std/bastring.cc index b5f7a0d..3093b9e 100644 --- a/contrib/libstdc++/std/bastring.cc +++ b/contrib/libstdc++/std/bastring.cc @@ -39,7 +39,7 @@ operator delete (void * ptr) { Allocator::deallocate(ptr, sizeof(Rep) + reinterpret_cast<Rep *>(ptr)->res * - sizeof (charT)); + sizeof (charT)); } template <class charT, class traits, class Allocator> @@ -450,7 +450,7 @@ operator>> (istream &is, basic_string <charT, traits, Allocator> &s) sb->sungetc (); break; } - s += ch; + s += static_cast<charT> (ch); if (--w == 1) break; } @@ -496,7 +496,7 @@ getline (istream &is, basic_string <charT, traits, Allocator>& s, charT delim) if (ch == delim) break; - s += ch; + s += static_cast<charT> (ch); if (s.length () == s.npos - 1) { diff --git a/contrib/libstdc++/std/bastring.h b/contrib/libstdc++/std/bastring.h index f188628..7089126 100644 --- a/contrib/libstdc++/std/bastring.h +++ b/contrib/libstdc++/std/bastring.h @@ -73,7 +73,41 @@ private: 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 (); } +#if defined __i486__ || defined __i586__ || defined __i686__ + void release () + { + size_t __val; + // This opcode exists as a .byte instead of as a mnemonic for the + // benefit of SCO OpenServer 5. The system assembler (which is + // essentially required on this target) can't assemble xaddl in + //COFF mode. + asm (".byte 0xf0, 0x0f, 0xc1, 0x02" // lock; xaddl %eax, (%edx) + : "=a" (__val) + : "0" (-1), "m" (ref), "d" (&ref) + : "memory"); + + if (__val == 1) + delete this; + } +#elif defined __sparcv9__ + void release () + { + size_t __newval, __oldval = ref; + do + { + __newval = __oldval - 1; + __asm__ ("cas [%4], %2, %0" + : "=r" (__oldval), "=m" (ref) + : "r" (__oldval), "m" (ref), "r"(&(ref)), "0" (__newval)); + } + while (__newval != __oldval); + + if (__oldval == 0) + delete this; + } +#else void release () { if (--ref == 0) delete this; } +#endif inline static void * operator new (size_t, size_t); inline static void operator delete (void *); diff --git a/contrib/libstdc++/std/gslice.h b/contrib/libstdc++/std/gslice.h new file mode 100644 index 0000000..4f6e854 --- /dev/null +++ b/contrib/libstdc++/std/gslice.h @@ -0,0 +1,111 @@ +// The template and inlines for the -*- C++ -*- gslice class. + +// Copyright (C) 1997-1999 Cygnus Solutions +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> + +#ifndef __GSLICE__ +#define __GSLICE__ + +extern "C++" { + +struct _Indexer { + size_t _M_count; + size_t _M_start; + valarray<size_t> _M_size; + valarray<size_t> _M_stride; + valarray<size_t> _M_index; + _Indexer(size_t, const valarray<size_t>&, const valarray<size_t>&); + void _M_increment_use() { ++_M_count; } + size_t _M_decrement_use() { return --_M_count; } +}; + + +class gslice +{ +public: + gslice (); + gslice (size_t, const valarray<size_t>&, const valarray<size_t>&); + gslice(const gslice&); + ~gslice(); + + gslice& operator= (const gslice&); + size_t start () const; + valarray<size_t> size () const; + valarray<size_t> stride () const; + +private: + _Indexer* _M_index; + + template<typename _Tp> friend class valarray; +}; + +inline size_t +gslice::start () const +{ return _M_index ? _M_index->_M_start : 0; } + +inline valarray<size_t> +gslice::size () const +{ return _M_index ? _M_index->_M_size : valarray<size_t>(); } + +inline valarray<size_t> +gslice::stride () const +{ return _M_index ? _M_index->_M_stride : valarray<size_t>(); } + +inline gslice::gslice () : _M_index(0) {} + +inline +gslice::gslice(size_t __o, const valarray<size_t>& __l, + const valarray<size_t>& __s) + : _M_index(new _Indexer(__o, __l, __s)) {} + +inline +gslice::gslice(const gslice& __g) : _M_index(__g._M_index) +{ if (_M_index) _M_index->_M_increment_use(); } + +inline +gslice::~gslice() +{ if (_M_index && _M_index->_M_decrement_use() == 0) delete _M_index; } + +inline gslice& +gslice::operator= (const gslice& __g) +{ + if (__g._M_index) __g._M_index->_M_increment_use(); + if (_M_index && _M_index->_M_decrement_use() == 0) delete _M_index; + _M_index = __g._M_index; + return *this; +} + + +} // extern "C++" + +#endif // __GSLICE__ + +// Local Variables: +// mode:c++ +// End: diff --git a/contrib/libstdc++/std/gslice_array.h b/contrib/libstdc++/std/gslice_array.h new file mode 100644 index 0000000..8a67cac --- /dev/null +++ b/contrib/libstdc++/std/gslice_array.h @@ -0,0 +1,170 @@ +// The template and inlines for the -*- C++ -*- gslice_array class. + +// Copyright (C) 1997-1999 Cygnus Solutions +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> + +#ifndef __GSLICE_ARRAY__ +#define __GSLICE_ARRAY__ + +extern "C++" { + +template<typename _Tp> class gslice_array +{ +public: + typedef _Tp value_type; + + void operator= (const valarray<_Tp>&) const; + void operator*= (const valarray<_Tp>&) const; + void operator/= (const valarray<_Tp>&) const; + void operator%= (const valarray<_Tp>&) const; + void operator+= (const valarray<_Tp>&) const; + void operator-= (const valarray<_Tp>&) const; + void operator^= (const valarray<_Tp>&) const; + void operator&= (const valarray<_Tp>&) const; + void operator|= (const valarray<_Tp>&) const; + void operator<<=(const valarray<_Tp>&) const; + void operator>>=(const valarray<_Tp>&) const; + void operator=(const _Tp&); + + template<class _Dom> + void operator= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator*= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator/= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator%= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator+= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator-= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator^= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator&= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator|= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator<<= (const _Expr<_Dom,_Tp>&) const; + template<class _Dom> + void operator>>= (const _Expr<_Dom,_Tp>&) const; + +private: + _Array<_Tp> _M_array; + const valarray<size_t>& _M_index; + + friend class valarray<_Tp>; + + gslice_array (_Array<_Tp>, const valarray<size_t>&); + + // this constructor needs to be implemented. + gslice_array (const gslice_array&); + + // not implemented + gslice_array(); + gslice_array& operator= (const gslice_array&); +}; + +template<typename _Tp> +inline +gslice_array<_Tp>::gslice_array (_Array<_Tp> __a, + const valarray<size_t>& __i) + : _M_array (__a), _M_index (__i) {} + + +template<typename _Tp> +inline +gslice_array<_Tp>::gslice_array (const gslice_array<_Tp>& __a) + : _M_array (__a._M_array), _M_index (__a._M_index) {} + + +template<typename _Tp> +inline void +gslice_array<_Tp>::operator= (const _Tp& __t) +{ + __valarray_fill (_M_array, _Array<size_t>(_M_index), + _M_index.size(), __t); +} + +template<typename _Tp> +inline void +gslice_array<_Tp>::operator= (const valarray<_Tp>& __v) const +{ + __valarray_copy (_Array<_Tp> (__v), __v.size (), + _M_array, _Array<size_t>(_M_index)); +} + +template<typename _Tp> +template<class E> +inline void +gslice_array<_Tp>::operator= (const _Expr<E, _Tp>& __e) const +{ + __valarray_copy (__e, _M_index.size(), _M_array, + _Array<size_t>(_M_index)); +} + +#undef _DEFINE_VALARRAY_OPERATOR +#define _DEFINE_VALARRAY_OPERATOR(op, name) \ +template<typename _Tp> \ +inline void \ +gslice_array<_Tp>::operator##op##= (const valarray<_Tp>& __v) const \ +{ \ + _Array_augmented_##name (_M_array, _Array<size_t>(_M_index), \ + _Array<_Tp> (__v), __v.size ()); \ +} \ + \ +template<typename _Tp> template<class E> \ +inline void \ +gslice_array<_Tp>::operator##op##= (const _Expr<E, _Tp>& __e) const \ +{ \ + _Array_augmented_##name (_M_array, _Array<size_t>(_M_index), __e, \ + _M_index.size()); \ +} + +_DEFINE_VALARRAY_OPERATOR(*, multiplies) +_DEFINE_VALARRAY_OPERATOR(/, divides) +_DEFINE_VALARRAY_OPERATOR(%, modulus) +_DEFINE_VALARRAY_OPERATOR(+, plus) +_DEFINE_VALARRAY_OPERATOR(-, minus) +_DEFINE_VALARRAY_OPERATOR(^, xor) +_DEFINE_VALARRAY_OPERATOR(&, and) +_DEFINE_VALARRAY_OPERATOR(|, or) +_DEFINE_VALARRAY_OPERATOR(<<, shift_left) +_DEFINE_VALARRAY_OPERATOR(>>, shift_right) + +#undef _DEFINE_VALARRAY_OPERATOR + +} // extern "C++" + + +#endif // __GSLICE_ARRAY__ + +// Local Variables: +// mode:c++ +// End: diff --git a/contrib/libstdc++/std/indirect_array.h b/contrib/libstdc++/std/indirect_array.h new file mode 100644 index 0000000..bb5b79f --- /dev/null +++ b/contrib/libstdc++/std/indirect_array.h @@ -0,0 +1,157 @@ +// The template and inlines for the -*- C++ -*- indirect_array class. + +// Copyright (C) 1997-1999 Cygnus Solutions +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> + +#ifndef __INDIRECT_ARRAY__ +#define __INDIRECT_ARRAY__ + +extern "C++" { + +template <class _Tp> class indirect_array +{ +public: + typedef _Tp value_type; + + void operator= (const valarray<_Tp>&) const; + void operator*= (const valarray<_Tp>&) const; + void operator/= (const valarray<_Tp>&) const; + void operator%= (const valarray<_Tp>&) const; + void operator+= (const valarray<_Tp>&) const; + void operator-= (const valarray<_Tp>&) const; + void operator^= (const valarray<_Tp>&) const; + void operator&= (const valarray<_Tp>&) const; + void operator|= (const valarray<_Tp>&) const; + void operator<<= (const valarray<_Tp>&) const; + void operator>>= (const valarray<_Tp>&) const; + void operator= (const _Tp&); + + template<class _Dom> + void operator= (const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator*= (const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator/= (const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator%= (const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator+= (const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator-= (const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator^= (const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator&= (const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator|= (const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator<<= (const _Expr<_Dom, _Tp>&) const; + template<class _Dom> + void operator>>= (const _Expr<_Dom, _Tp>&) const; + +private: + indirect_array (const indirect_array&); + indirect_array (_Array<_Tp>, size_t, _Array<size_t>); + + friend class valarray<_Tp>; + friend class gslice_array<_Tp>; + + const size_t _M_sz; + const _Array<size_t> _M_index; + const _Array<_Tp> _M_array; + + // not implemented + indirect_array (); + indirect_array& operator= (const indirect_array&); +}; + +template<typename _Tp> +inline indirect_array<_Tp>::indirect_array(const indirect_array<_Tp>& __a) + : _M_sz (__a._M_sz), _M_index (__a._M_index), + _M_array (__a._M_array) {} + +template<typename _Tp> +inline +indirect_array<_Tp>::indirect_array (_Array<_Tp> __a, size_t __s, + _Array<size_t> __i) + : _M_sz (__s), _M_index (__i), _M_array (__a) {} + + +template<typename _Tp> +inline void +indirect_array<_Tp>::operator= (const _Tp& __t) +{ __valarray_fill(_M_array, _M_index, _M_sz, __t); } + +template<typename _Tp> +inline void +indirect_array<_Tp>::operator= (const valarray<_Tp>& __v) const +{ __valarray_copy (_Array<_Tp> (__v), _M_sz, _M_array, _M_index); } + +template<typename _Tp> +template<class _Dom> +inline void +indirect_array<_Tp>::operator= (const _Expr<_Dom,_Tp>& __e) const +{ __valarray_copy (__e, _M_sz, _M_array, _M_index); } + +#undef _DEFINE_VALARRAY_OPERATOR +#define _DEFINE_VALARRAY_OPERATOR(op, name) \ +template<typename _Tp> \ +inline void \ +indirect_array<_Tp>::operator##op##= (const valarray<_Tp>& __v) const \ +{ \ + _Array_augmented_##name (_M_array, _M_index, _Array<_Tp> (__v), _M_sz); \ +} \ + \ +template<typename _Tp> template<class _Dom> \ +inline void \ +indirect_array<_Tp>::operator##op##= (const _Expr<_Dom,_Tp>& __e) const \ +{ \ + _Array_augmented_##name (_M_array, _M_index, __e, _M_sz); \ +} + +_DEFINE_VALARRAY_OPERATOR(*, multiplies) +_DEFINE_VALARRAY_OPERATOR(/, divides) +_DEFINE_VALARRAY_OPERATOR(%, modulus) +_DEFINE_VALARRAY_OPERATOR(+, plus) +_DEFINE_VALARRAY_OPERATOR(-, minus) +_DEFINE_VALARRAY_OPERATOR(^, xor) +_DEFINE_VALARRAY_OPERATOR(&, and) +_DEFINE_VALARRAY_OPERATOR(|, or) +_DEFINE_VALARRAY_OPERATOR(<<, shift_left) +_DEFINE_VALARRAY_OPERATOR(>>, shift_right) + +#undef _DEFINE_VALARRAY_OPERATOR + +} // extern "C++" + +#endif // __INDIRECT_ARRAY__ + +// Local Variables: +// mode:c++ +// End: diff --git a/contrib/libstdc++/std/mask_array.h b/contrib/libstdc++/std/mask_array.h new file mode 100644 index 0000000..d431be4 --- /dev/null +++ b/contrib/libstdc++/std/mask_array.h @@ -0,0 +1,154 @@ +// The template and inlines for the -*- C++ -*- mask_array class. + +// Copyright (C) 1997-1999 Cygnus Solutions +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> + +#ifndef __MASK_ARRAY__ +#define __MASK_ARRAY__ + +extern "C++" { + +template <class _T> class mask_array +{ +public: + typedef _T value_type; + + void operator= (const valarray<_T>&) const; + void operator*= (const valarray<_T>&) const; + void operator/= (const valarray<_T>&) const; + void operator%= (const valarray<_T>&) const; + void operator+= (const valarray<_T>&) const; + void operator-= (const valarray<_T>&) const; + void operator^= (const valarray<_T>&) const; + void operator&= (const valarray<_T>&) const; + void operator|= (const valarray<_T>&) const; + void operator<<=(const valarray<_T>&) const; + void operator>>=(const valarray<_T>&) const; + void operator= (const _T&); + + template<class _Dom> + void operator= (const _Expr<_Dom,_T>&) const; + template<class _Dom> + void operator*= (const _Expr<_Dom,_T>&) const; + template<class _Dom> + void operator/= (const _Expr<_Dom,_T>&) const; + template<class _Dom> + void operator%= (const _Expr<_Dom,_T>&) const; + template<class _Dom> + void operator+= (const _Expr<_Dom,_T>&) const; + template<class _Dom> + void operator-= (const _Expr<_Dom,_T>&) const; + template<class _Dom> + void operator^= (const _Expr<_Dom,_T>&) const; + template<class _Dom> + void operator&= (const _Expr<_Dom,_T>&) const; + template<class _Dom> + void operator|= (const _Expr<_Dom,_T>&) const; + template<class _Dom> + void operator<<=(const _Expr<_Dom,_T>&) const; + template<class _Dom> + void operator>>=(const _Expr<_Dom,_T>&) const; + +private: + mask_array (_Array<_T>, size_t, _Array<bool>); + friend class valarray<_T>; + + const size_t _M_sz; + const _Array<bool> _M_mask; + const _Array<_T> _M_array; + + mask_array (const mask_array&); + + // not implemented + mask_array (); + mask_array& operator= (const mask_array&); +}; + +template<typename _Tp> +inline mask_array<_Tp>::mask_array (const mask_array<_Tp>& a) + : _M_sz (a._M_sz), _M_mask (a._M_mask), _M_array (a._M_array) {} + +template<typename _T> +inline +mask_array<_T>::mask_array (_Array<_T> __a, size_t __s, _Array<bool> __m) + : _M_sz (__s), _M_mask (__m), _M_array (__a) {} + +template<typename _T> +inline void +mask_array<_T>::operator= (const _T& __t) +{ __valarray_fill (_M_array, _M_sz, _M_mask, __t); } + +template<typename _T> +inline void +mask_array<_T>::operator= (const valarray<_T>& __v) const +{ __valarray_copy (_Array<_T> (__v), __v.size (), _M_array, _M_mask); } + +template<typename _T> +template<class E> +inline void +mask_array<_T>::operator= (const _Expr<E, _T>& __e) const +{ __valarray_copy (__e, __e.size (), _M_array, _M_mask); } + +#undef _DEFINE_VALARRAY_OPERATOR +#define _DEFINE_VALARRAY_OPERATOR(op, name) \ +template<typename _T> \ +inline void \ +mask_array<_T>::operator##op##= (const valarray<_T>& __v) const \ +{ \ + _Array_augmented_##name (_M_array, _M_mask, \ + _Array<_T> (__v), __v.size ()); \ +} \ + \ +template<typename _T> template<class E> \ +inline void \ +mask_array<_T>::operator##op##= (const _Expr<E, _T>& __e) const \ +{ \ + _Array_augmented_##name (_M_array, _M_mask, __e, __e.size ()); \ +} + +_DEFINE_VALARRAY_OPERATOR(*, multiplies) +_DEFINE_VALARRAY_OPERATOR(/, divides) +_DEFINE_VALARRAY_OPERATOR(%, modulus) +_DEFINE_VALARRAY_OPERATOR(+, plus) +_DEFINE_VALARRAY_OPERATOR(-, minus) +_DEFINE_VALARRAY_OPERATOR(^, xor) +_DEFINE_VALARRAY_OPERATOR(&, and) +_DEFINE_VALARRAY_OPERATOR(|, or) +_DEFINE_VALARRAY_OPERATOR(<<, shift_left) +_DEFINE_VALARRAY_OPERATOR(>>, shift_right) + +#undef _DEFINE_VALARRAY_OPERATOR + +} // extern "C++" + +#endif // __MASK_ARRAY__ + +// Local Variables: +// mode:c++ +// End: diff --git a/contrib/libstdc++/std/slice.h b/contrib/libstdc++/std/slice.h new file mode 100644 index 0000000..cf2fb28 --- /dev/null +++ b/contrib/libstdc++/std/slice.h @@ -0,0 +1,76 @@ +// The template and inlines for the -*- C++ -*- slice class. + +// Copyright (C) 1997-1999 Cygnus Solutions +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> + +#ifndef __SLICE__ +#define __SLICE__ + +extern "C++" { + +class slice +{ +public: + slice (); + slice (size_t, size_t, size_t); + + size_t start () const; + size_t size () const; + size_t stride () const; + +private: + size_t _M_off; // offset + size_t _M_sz; // size + size_t _M_st; // stride unit +}; + +inline slice::slice () {} + +inline slice::slice (size_t __o, size_t __d, size_t __s) + : _M_off (__o), _M_sz (__d), _M_st (__s) {} + +inline size_t +slice::start () const + { return _M_off; } + +inline size_t +slice::size () const + { return _M_sz; } + +inline size_t +slice::stride () const + { return _M_st; } + +} // extern "C++" + +#endif // __SLICE__ + +// Local Variables: +// mode:c++ +// End: diff --git a/contrib/libstdc++/std/slice_array.h b/contrib/libstdc++/std/slice_array.h new file mode 100644 index 0000000..dc1aa34 --- /dev/null +++ b/contrib/libstdc++/std/slice_array.h @@ -0,0 +1,156 @@ +// The template and inlines for the -*- C++ -*- slice_array class. + +// Copyright (C) 1997-1999 Cygnus Solutions +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> + +#ifndef __SLICE_ARRAY__ +#define __SLICE_ARRAY__ + +extern "C++" { + +template<typename _T> +class slice_array +{ +public: + typedef _T value_type; + + void operator= (const valarray<_T>&) const; + void operator*= (const valarray<_T>&) const; + void operator/= (const valarray<_T>&) const; + void operator%= (const valarray<_T>&) const; + void operator+= (const valarray<_T>&) const; + void operator-= (const valarray<_T>&) const; + void operator^= (const valarray<_T>&) const; + void operator&= (const valarray<_T>&) const; + void operator|= (const valarray<_T>&) const; + void operator<<= (const valarray<_T>&) const; + void operator>>= (const valarray<_T>&) const; + void operator= (const _T &); + + template<class _Dom> + void operator= (const _Expr<_Dom,_T>&) const; + template<class _Dom> + void operator*= (const _Expr<_Dom,_T>&) const; + template<class _Dom> + void operator/= (const _Expr<_Dom,_T>&) const; + template<class _Dom> + void operator%= (const _Expr<_Dom,_T>&) const; + template<class _Dom> + void operator+= (const _Expr<_Dom,_T>&) const; + template<class _Dom> + void operator-= (const _Expr<_Dom,_T>&) const; + template<class _Dom> + void operator^= (const _Expr<_Dom,_T>&) const; + template<class _Dom> + void operator&= (const _Expr<_Dom,_T>&) const; + template<class _Dom> + void operator|= (const _Expr<_Dom,_T>&) const; + template<class _Dom> + void operator<<= (const _Expr<_Dom,_T>&) const; + template<class _Dom> + void operator>>= (const _Expr<_Dom,_T>&) const; + +private: + friend class valarray<_T>; + slice_array(_Array<_T>, const slice&); + + const size_t _M_sz; + const size_t _M_stride; + const _Array<_T> _M_array; + + // this constructor is implemented since we need to return a value. + slice_array (const slice_array&); + + // not implemented + slice_array (); + slice_array& operator= (const slice_array&); +}; + +template<typename _T> +inline slice_array<_T>::slice_array (_Array<_T> __a, const slice& __s) + : _M_sz (__s.size ()), _M_stride (__s.stride ()), + _M_array (__a.begin () + __s.start ()) {} + +template<typename _Tp> +inline slice_array<_Tp>::slice_array(const slice_array<_Tp>& a) + : _M_sz(a._M_sz), _M_stride(a._M_stride), _M_array(a._M_array) {} + +template<typename _T> +inline void +slice_array<_T>::operator= (const _T& __t) +{ __valarray_fill (_M_array, _M_sz, _M_stride, __t); } + +template<typename _T> +inline void +slice_array<_T>::operator= (const valarray<_T>& __v) const +{ __valarray_copy (_Array<_T> (__v), _M_array, _M_sz, _M_stride); } + +template<typename _T> +template<class _Dom> +inline void +slice_array<_T>::operator= (const _Expr<_Dom,_T>& __e) const +{ __valarray_copy (__e, _M_sz, _M_array, _M_stride); } + +#undef _DEFINE_VALARRAY_OPERATOR +#define _DEFINE_VALARRAY_OPERATOR(op, name) \ +template<typename _T> \ +inline void \ +slice_array<_T>::operator##op##= (const valarray<_T>& __v) const \ +{ \ + _Array_augmented_##name (_M_array, _M_sz, _M_stride, _Array<_T> (__v));\ +} \ + \ +template<typename _T> template<class _Dom> \ +inline void \ +slice_array<_T>::operator##op##= (const _Expr<_Dom,_T>& __e) const \ +{ \ + _Array_augmented_##name (_M_array, _M_stride, __e, _M_sz); \ +} + + +_DEFINE_VALARRAY_OPERATOR(*, multiplies) +_DEFINE_VALARRAY_OPERATOR(/, divides) +_DEFINE_VALARRAY_OPERATOR(%, modulus) +_DEFINE_VALARRAY_OPERATOR(+, plus) +_DEFINE_VALARRAY_OPERATOR(-, minus) +_DEFINE_VALARRAY_OPERATOR(^, xor) +_DEFINE_VALARRAY_OPERATOR(&, and) +_DEFINE_VALARRAY_OPERATOR(|, or) +_DEFINE_VALARRAY_OPERATOR(<<, shift_left) +_DEFINE_VALARRAY_OPERATOR(>>, shift_right) + +#undef _DEFINE_VALARRAY_OPERATOR + +} // extern "C++" + +#endif // __SLICE_ARRAY__ + +// Local Variables: +// mode:c++ +// End: diff --git a/contrib/libstdc++/std/std_valarray.h b/contrib/libstdc++/std/std_valarray.h new file mode 100644 index 0000000..b300655 --- /dev/null +++ b/contrib/libstdc++/std/std_valarray.h @@ -0,0 +1,728 @@ +// The template and inlines for the -*- C++ -*- valarray class. + +// Copyright (C) 1997-1999 Cygnus Solutions +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> + +#ifndef __STD_VALARRAY__ +#define __STD_VALARRAY__ +#define _G_NO_VALARRAY_TEMPLATE_EXPORT 1 + +#include <cstddef> +#include <cmath> +#include <cstdlib> +#include <numeric> +#include <functional> +#include <algorithm> + +#ifndef alloca +#ifdef __GNUC__ +#define alloca __builtin_alloca +#else /* not GNU C. */ +#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) +#include <alloca.h> +#else /* not sparc */ +#if defined (MSDOS) && !defined (__TURBOC__) +#include <malloc.h> +#else /* not MSDOS, or __TURBOC__ */ +#if defined(_AIX) +#include <malloc.h> + #pragma alloca +#else /* not MSDOS, __TURBOC__, or _AIX */ +#ifdef __hpux +#endif /* __hpux */ +#endif /* not _AIX */ +#endif /* not MSDOS, or __TURBOC__ */ +#endif /* not sparc. */ +#endif /* not GNU C. */ +#endif /* alloca not defined. */ + +extern "C" { + void* alloca(size_t); +} + + +extern "C++" { + +template<class _Clos, typename _Tp> class _Expr; + +template<typename _Tp1, typename _Tp2> class _ValArray; + +template<template<class> class _Oper, + template<class, class> class _Meta, class _Dom> struct _UnClos; + +template<template<class> class _Oper, + template<class, class> class _Meta1, + template<class, class> class _Meta2, + class _Dom1, class _Dom2> class _BinClos; + +template<template<class, class> class _Meta, class _Dom> class _SClos; + +template<template<class, class> class _Meta, class _Dom> class _GClos; + +template<template<class, class> class _Meta, class _Dom> class _IClos; + +template<template<class, class> class _Meta, class _Dom> class _ValFunClos; + +template<template<class, class> class _Meta, class _Dom> class _RefFunClos; + +template<class _Tp> struct _Unary_plus; +template<class _Tp> struct _Bitwise_and; +template<class _Tp> struct _Bitwise_or; +template<class _Tp> struct _Bitwise_xor; +template<class _Tp> struct _Bitwise_not; +template<class _Tp> struct _Shift_left; +template<class _Tp> struct _Shift_right; + +template<class _Tp> class valarray; // An array of type _Tp +class slice; // BLAS-like slice out of an array +template<class _Tp> class slice_array; +class gslice; // generalized slice out of an array +template<class _Tp> class gslice_array; +template<class _Tp> class mask_array; // masked array +template<class _Tp> class indirect_array; // indirected array + +} // extern "C++" + +#include <std/valarray_array.h> +#include <std/valarray_meta.h> + +extern "C++" { + +template<class _Tp> class valarray +{ +public: + typedef _Tp value_type; + + // _lib.valarray.cons_ construct/destroy: + valarray(); + explicit valarray(size_t); + valarray(const _Tp&, size_t); + valarray(const _Tp* __restrict__, size_t); + valarray(const valarray&); + valarray(const slice_array<_Tp>&); + valarray(const gslice_array<_Tp>&); + valarray(const mask_array<_Tp>&); + valarray(const indirect_array<_Tp>&); + template<class _Dom> + valarray(const _Expr<_Dom,_Tp>& __e); + ~valarray(); + + // _lib.valarray.assign_ assignment: + valarray<_Tp>& operator=(const valarray<_Tp>&); + valarray<_Tp>& operator=(const _Tp&); + valarray<_Tp>& operator=(const slice_array<_Tp>&); + valarray<_Tp>& operator=(const gslice_array<_Tp>&); + valarray<_Tp>& operator=(const mask_array<_Tp>&); + valarray<_Tp>& operator=(const indirect_array<_Tp>&); + + template<class _Dom> valarray<_Tp>& + operator= (const _Expr<_Dom,_Tp>&); + + // _lib.valarray.access_ element access: + _Tp operator[](size_t) const; + _Tp& operator[](size_t); + // _lib.valarray.sub_ subset operations: + _Expr<_SClos<_ValArray,_Tp>, _Tp> operator[](slice) const; + slice_array<_Tp> operator[](slice); + _Expr<_GClos<_ValArray,_Tp>, _Tp> operator[](const gslice&) const; + gslice_array<_Tp> operator[](const gslice&); + valarray<_Tp> operator[](const valarray<bool>&) const; + mask_array<_Tp> operator[](const valarray<bool>&); + _Expr<_IClos<_ValArray, _Tp>, _Tp> + operator[](const valarray<size_t>&) const; + indirect_array<_Tp> operator[](const valarray<size_t>&); + + // _lib.valarray.unary_ unary operators: + _Expr<_UnClos<_Unary_plus,_ValArray,_Tp>,_Tp> operator+ () const; + _Expr<_UnClos<negate,_ValArray,_Tp>,_Tp> operator- () const; + _Expr<_UnClos<_Bitwise_not,_ValArray,_Tp>,_Tp> operator~ () const; + _Expr<_UnClos<logical_not,_ValArray,_Tp>,bool> operator! () const; + + // _lib.valarray.cassign_ computed assignment: + valarray<_Tp>& operator*= (const _Tp&); + valarray<_Tp>& operator/= (const _Tp&); + valarray<_Tp>& operator%= (const _Tp&); + valarray<_Tp>& operator+= (const _Tp&); + valarray<_Tp>& operator-= (const _Tp&); + valarray<_Tp>& operator^= (const _Tp&); + valarray<_Tp>& operator&= (const _Tp&); + valarray<_Tp>& operator|= (const _Tp&); + valarray<_Tp>& operator<<=(const _Tp&); + valarray<_Tp>& operator>>=(const _Tp&); + valarray<_Tp>& operator*= (const valarray<_Tp>&); + valarray<_Tp>& operator/= (const valarray<_Tp>&); + valarray<_Tp>& operator%= (const valarray<_Tp>&); + valarray<_Tp>& operator+= (const valarray<_Tp>&); + valarray<_Tp>& operator-= (const valarray<_Tp>&); + valarray<_Tp>& operator^= (const valarray<_Tp>&); + valarray<_Tp>& operator|= (const valarray<_Tp>&); + valarray<_Tp>& operator&= (const valarray<_Tp>&); + valarray<_Tp>& operator<<=(const valarray<_Tp>&); + valarray<_Tp>& operator>>=(const valarray<_Tp>&); + + template<class _Dom> + valarray<_Tp>& operator*= (const _Expr<_Dom,_Tp>&); + template<class _Dom> + valarray<_Tp>& operator/= (const _Expr<_Dom,_Tp>&); + template<class _Dom> + valarray<_Tp>& operator%= (const _Expr<_Dom,_Tp>&); + template<class _Dom> + valarray<_Tp>& operator+= (const _Expr<_Dom,_Tp>&); + template<class _Dom> + valarray<_Tp>& operator-= (const _Expr<_Dom,_Tp>&); + template<class _Dom> + valarray<_Tp>& operator^= (const _Expr<_Dom,_Tp>&); + template<class _Dom> + valarray<_Tp>& operator|= (const _Expr<_Dom,_Tp>&); + template<class _Dom> + valarray<_Tp>& operator&= (const _Expr<_Dom,_Tp>&); + template<class _Dom> + valarray<_Tp>& operator<<=(const _Expr<_Dom,_Tp>&); + template<class _Dom> + valarray<_Tp>& operator>>=(const _Expr<_Dom,_Tp>&); + + + // _lib.valarray.members_ member functions: + size_t size() const; + _Tp sum() const; + _Tp min() const; + _Tp max() const; + + // FIXME: Extension + _Tp product () const; + + valarray<_Tp> shift (int) const; + valarray<_Tp> cshift(int) const; + _Expr<_ValFunClos<_ValArray,_Tp>,_Tp> apply(_Tp func(_Tp)) const; + _Expr<_RefFunClos<_ValArray,_Tp>,_Tp> apply(_Tp func(const _Tp&)) const; + void resize(size_t __size, _Tp __c = _Tp()); + +private: + size_t _M_size; + _Tp* __restrict__ _M_data; + + friend class _Array<_Tp>; +}; + + +template<typename _Tp> struct _Unary_plus : unary_function<_Tp,_Tp> { + _Tp operator() (const _Tp& __t) const { return __t; } +}; + +template<typename _Tp> struct _Bitwise_and : binary_function<_Tp,_Tp,_Tp> { + _Tp operator() (_Tp __x, _Tp __y) const { return __x & __y; } +}; + +template<typename _Tp> struct _Bitwise_or : binary_function<_Tp,_Tp,_Tp> { + _Tp operator() (_Tp __x, _Tp __y) const { return __x | __y; } +}; + +template<typename _Tp> struct _Bitwise_xor : binary_function<_Tp,_Tp,_Tp> { + _Tp operator() (_Tp __x, _Tp __y) const { return __x ^ __y; } +}; + +template<typename _Tp> struct _Bitwise_not : unary_function<_Tp,_Tp> { + _Tp operator() (_Tp __t) const { return ~__t; } +}; + +template<typename _Tp> struct _Shift_left : unary_function<_Tp,_Tp> { + _Tp operator() (_Tp __x, _Tp __y) const { return __x << __y; } +}; + +template<typename _Tp> struct _Shift_right : unary_function<_Tp,_Tp> { + _Tp operator() (_Tp __x, _Tp __y) const { return __x >> __y; } +}; + + +template<typename _Tp> +inline _Tp +valarray<_Tp>::operator[] (size_t __i) const +{ return _M_data[__i]; } + +template<typename _Tp> +inline _Tp& +valarray<_Tp>::operator[] (size_t __i) +{ return _M_data[__i]; } + +} // extern "C++" + +#include <std/slice.h> +#include <std/slice_array.h> +#include <std/gslice.h> +#include <std/gslice_array.h> +#include <std/mask_array.h> +#include <std/indirect_array.h> + +extern "C++" { + +template<typename _Tp> +inline valarray<_Tp>::valarray () : _M_size (0), _M_data (0) {} + +template<typename _Tp> +inline valarray<_Tp>::valarray (size_t __n) + : _M_size (__n), _M_data (new _Tp[__n]) {} + +template<typename _Tp> +inline valarray<_Tp>::valarray (const _Tp& __t, size_t __n) + : _M_size (__n), _M_data (new _Tp[__n]) +{ __valarray_fill (_M_data, _M_size, __t); } + +template<typename _Tp> +inline valarray<_Tp>::valarray (const _Tp* __restrict__ __pT, size_t __n) + : _M_size (__n), _M_data (new _Tp[__n]) +{ __valarray_copy (__pT, __n, _M_data); } + +template<typename _Tp> +inline valarray<_Tp>::valarray (const valarray<_Tp>& __v) + : _M_size (__v._M_size), _M_data (new _Tp[__v._M_size]) +{ __valarray_copy (__v._M_data, _M_size, _M_data); } + +template<typename _Tp> +inline valarray<_Tp>::valarray (const slice_array<_Tp>& __sa) + : _M_size (__sa._M_sz), _M_data (new _Tp[__sa._M_sz]) +{ __valarray_copy (__sa._M_array, __sa._M_sz, __sa._M_stride, + _Array<_Tp>(_M_data)); } + +template<typename _Tp> +inline valarray<_Tp>::valarray (const gslice_array<_Tp>& __ga) + : _M_size (__ga._M_index.size()), _M_data (new _Tp[_M_size]) +{ __valarray_copy (__ga._M_array, _Array<size_t>(__ga._M_index), + _Array<_Tp>(_M_data), _M_size); } + +template<typename _Tp> +inline valarray<_Tp>::valarray (const mask_array<_Tp>& __ma) + : _M_size (__ma._M_sz), _M_data (new _Tp[__ma._M_sz]) +{ __valarray_copy (__ma._M_array, __ma._M_mask, + _Array<_Tp>(_M_data), _M_size); } + +template<typename _Tp> +inline valarray<_Tp>::valarray (const indirect_array<_Tp>& __ia) + : _M_size (__ia._M_sz), _M_data (new _Tp[__ia._M_sz]) +{ __valarray_copy (__ia._M_array, __ia._M_index, + _Array<_Tp>(_M_data), _M_size); } + +template<typename _Tp> template<class _Dom> +inline valarray<_Tp>::valarray (const _Expr<_Dom, _Tp>& __e) + : _M_size (__e.size ()), _M_data (new _Tp[_M_size]) +{ __valarray_copy (__e, _M_size, _Array<_Tp>(_M_data)); } + +template<typename _Tp> +inline valarray<_Tp>::~valarray () { delete[] _M_data; } + +template<typename _Tp> +inline valarray<_Tp>& +valarray<_Tp>::operator= (const valarray<_Tp>& __v) +{ + __valarray_copy(__v._M_data, _M_size, _M_data); + return *this; +} + +template<typename _Tp> +inline valarray<_Tp>& +valarray<_Tp>::operator= (const _Tp& __t) +{ + __valarray_fill (_M_data, _M_size, __t); + return *this; +} + +template<typename _Tp> +inline valarray<_Tp>& +valarray<_Tp>::operator= (const slice_array<_Tp>& __sa) +{ + __valarray_copy (__sa._M_array, __sa._M_sz, + __sa._M_stride, _Array<_Tp>(_M_data)); + return *this; +} + +template<typename _Tp> +inline valarray<_Tp>& +valarray<_Tp>::operator= (const gslice_array<_Tp>& __ga) +{ + __valarray_copy (__ga._M_array, _Array<size_t>(__ga._M_index), + _Array<_Tp>(_M_data), _M_size); + return *this; +} + +template<typename _Tp> +inline valarray<_Tp>& +valarray<_Tp>::operator= (const mask_array<_Tp>& __ma) +{ + __valarray_copy (__ma._M_array, __ma._M_mask, + _Array<_Tp>(_M_data), _M_size); + return *this; +} + +template<typename _Tp> +inline valarray<_Tp>& +valarray<_Tp>::operator= (const indirect_array<_Tp>& __ia) +{ + __valarray_copy (__ia._M_array, __ia._M_index, + _Array<_Tp>(_M_data), _M_size); + return *this; +} + +template<typename _Tp> template<class _Dom> +inline valarray<_Tp>& +valarray<_Tp>::operator= (const _Expr<_Dom, _Tp>& __e) +{ + __valarray_copy (__e, _M_size, _Array<_Tp>(_M_data)); + return *this; +} + +template<typename _Tp> +inline _Expr<_SClos<_ValArray,_Tp>, _Tp> +valarray<_Tp>::operator[] (slice __s) const +{ + typedef _SClos<_ValArray,_Tp> _Closure; + return _Expr<_Closure, _Tp> (_Closure (_Array<_Tp>(_M_data), __s)); +} + +template<typename _Tp> +inline slice_array<_Tp> +valarray<_Tp>::operator[] (slice __s) +{ + return slice_array<_Tp> (_Array<_Tp>(_M_data), __s); +} + +template<typename _Tp> +inline _Expr<_GClos<_ValArray,_Tp>, _Tp> +valarray<_Tp>::operator[] (const gslice& __gs) const +{ + typedef _GClos<_ValArray,_Tp> _Closure; + return _Expr<_Closure, _Tp> + (_Closure (_Array<_Tp>(_M_data), __gs._M_index->_M_index)); +} + +template<typename _Tp> +inline gslice_array<_Tp> +valarray<_Tp>::operator[] (const gslice& __gs) +{ + return gslice_array<_Tp> + (_Array<_Tp>(_M_data), __gs._M_index->_M_index); +} + +template<typename _Tp> +inline valarray<_Tp> +valarray<_Tp>::operator[] (const valarray<bool>& __m) const +{ + size_t __s (0); + size_t __e (__m.size ()); + for (size_t __i=0; __i<__e; ++__i) + if (__m[__i]) ++__s; + return valarray<_Tp> (mask_array<_Tp> (_Array<_Tp>(_M_data), __s, + _Array<bool> (__m))); +} + +template<typename _Tp> +inline mask_array<_Tp> +valarray<_Tp>::operator[] (const valarray<bool>& __m) +{ + size_t __s (0); + size_t __e (__m.size ()); + for (size_t __i=0; __i<__e; ++__i) + if (__m[__i]) ++__s; + return mask_array<_Tp> (_Array<_Tp>(_M_data), __s, _Array<bool> (__m)); +} + +template<typename _Tp> +inline _Expr<_IClos<_ValArray,_Tp>, _Tp> +valarray<_Tp>::operator[] (const valarray<size_t>& __i) const +{ + typedef _IClos<_ValArray,_Tp> _Closure; + return _Expr<_Closure, _Tp> (_Closure (*this, __i)); +} + +template<typename _Tp> +inline indirect_array<_Tp> +valarray<_Tp>::operator[] (const valarray<size_t>& __i) +{ + return indirect_array<_Tp> (_Array<_Tp>(_M_data), __i.size(), + _Array<size_t> (__i)); +} + +template<class _Tp> +inline size_t valarray<_Tp>::size () const { return _M_size; } + +template<class _Tp> +inline _Tp +valarray<_Tp>::sum () const +{ + return accumulate (_M_data, _M_data + _M_size, _Tp ()); +} + +template<typename _Tp> +inline _Tp +valarray<_Tp>::product () const +{ + return accumulate (_M_data, _M_data+_M_size, _Tp(1), multiplies<_Tp> ()); +} + +template <class _Tp> +inline valarray<_Tp> +valarray<_Tp>::shift (int __n) const +{ + _Tp* const __a = static_cast<_Tp*> (alloca (sizeof(_Tp) * _M_size)); + if (! __n) // __n == 0: no shift + __valarray_copy (_M_data, _M_size, __a); + else if (__n > 0) { // __n > 0: shift left + if (__n > _M_size) + __valarray_fill(__a, __n, _Tp()); + else { + __valarray_copy (_M_data+__n, _M_size-__n, __a); + __valarray_fill (__a+_M_size-__n, __n, _Tp()); + } + } + else { // __n < 0: shift right + __valarray_copy (_M_data, _M_size+__n, __a-__n); + __valarray_fill(__a, -__n, _Tp()); + } + return valarray<_Tp> (__a, _M_size); +} + +template <class _Tp> +inline valarray<_Tp> +valarray<_Tp>::cshift (int __n) const +{ + _Tp* const __a = static_cast<_Tp*> (alloca (sizeof(_Tp) * _M_size)); + if (! __n) // __n == 0: no cshift + __valarray_copy(_M_data, _M_size, __a); + else if (__n > 0) { // __n > 0: cshift left + __valarray_copy (_M_data, __n, __a + _M_size-__n); + __valarray_copy (_M_data + __n, _M_size-__n, __a); + } + else { // __n < 0: cshift right + __valarray_copy (_M_data + _M_size + __n, -__n, __a); + __valarray_copy (_M_data, _M_size + __n, __a - __n); + } + return valarray<_Tp> (__a, _M_size); +} + +template <class _Tp> +inline void +valarray<_Tp>::resize (size_t __n, _Tp __c) +{ + if (_M_size != __n) { + delete[] _M_data; + _M_size = __n; + _M_data = new _Tp[_M_size]; + } + __valarray_fill (_M_data, _M_size, __c); +} + +template<typename _Tp> +inline _Tp +valarray<_Tp>::min() const +{ + return *min_element (_M_data, _M_data+_M_size); +} + +template<typename _Tp> +inline _Tp +valarray<_Tp>::max() const +{ + return *max_element (_M_data, _M_data+_M_size); +} + +template<class _Tp> +inline _Expr<_ValFunClos<_ValArray,_Tp>,_Tp> +valarray<_Tp>::apply (_Tp func (_Tp)) const +{ + typedef _ValFunClos<_ValArray,_Tp> _Closure; + return _Expr<_Closure,_Tp> (_Closure (*this, func)); +} + +template<class _Tp> +inline _Expr<_RefFunClos<_ValArray,_Tp>,_Tp> +valarray<_Tp>::apply (_Tp func (const _Tp &)) const +{ + typedef _RefFunClos<_ValArray,_Tp> _Closure; + return _Expr<_Closure,_Tp> (_Closure (*this, func)); +} + +#define _DEFINE_VALARRAY_UNARY_OPERATOR(_Op, _Name) \ + template<typename _Tp> \ + inline _Expr<_UnClos<_Name,_ValArray,_Tp>, _Tp> \ + valarray<_Tp>::operator##_Op() const \ + { \ + typedef _UnClos<_Name,_ValArray,_Tp> _Closure; \ + return _Expr<_Closure, _Tp> (_Closure (*this)); \ + } + + _DEFINE_VALARRAY_UNARY_OPERATOR(+, _Unary_plus) + _DEFINE_VALARRAY_UNARY_OPERATOR(-, negate) + _DEFINE_VALARRAY_UNARY_OPERATOR(~, _Bitwise_not) + +#undef _DEFINE_VALARRAY_UNARY_OPERATOR + + template<typename _Tp> + inline _Expr<_UnClos<logical_not,_ValArray,_Tp>, bool> + valarray<_Tp>::operator!() const + { + typedef _UnClos<logical_not,_ValArray,_Tp> _Closure; + return _Expr<_Closure, bool> (_Closure (*this)); + } + +#define _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(_Op, _Name) \ + template<class _Tp> \ + inline valarray<_Tp> & \ + valarray<_Tp>::operator##_Op##= (const _Tp &__t) \ + { \ + _Array_augmented_##_Name (_Array<_Tp>(_M_data), _M_size, __t); \ + return *this; \ + } \ + \ + template<class _Tp> \ + inline valarray<_Tp> & \ + valarray<_Tp>::operator##_Op##= (const valarray<_Tp> &__v) \ + { \ + _Array_augmented_##_Name (_Array<_Tp>(_M_data), _M_size, \ + _Array<_Tp>(__v._M_data)); \ + return *this; \ + } + +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(+, plus) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(-, minus) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(*, multiplies) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(/, divides) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(%, modulus) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(^, xor) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(&, and) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(|, or) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(<<, shift_left) +_DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(>>, shift_right) + +#undef _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT + + +#define _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(_Op, _Name) \ + template<class _Tp> template<class _Dom> \ + inline valarray<_Tp> & \ + valarray<_Tp>::operator##_Op##= (const _Expr<_Dom,_Tp> &__e) \ + { \ + _Array_augmented_##_Name (_Array<_Tp>(_M_data), __e, _M_size); \ + return *this; \ + } + +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(+, plus) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(-, minus) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(*, multiplies) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(/, divides) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(%, modulus) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(^, xor) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(&, and) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(|, or) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(<<, shift_left) +_DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(>>, shift_right) + +#undef _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT + + +#define _DEFINE_BINARY_OPERATOR(_Op, _Name) \ + template<typename _Tp> \ + inline _Expr<_BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp>, _Tp> \ + operator##_Op (const valarray<_Tp> &__v, const valarray<_Tp> &__w) \ + { \ + typedef _BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp> _Closure; \ + return _Expr<_Closure, _Tp> (_Closure (__v, __w)); \ + } \ + \ + template<typename _Tp> \ + inline _Expr<_BinClos<_Name,_ValArray,_Constant,_Tp,_Tp>,_Tp> \ + operator##_Op (const valarray<_Tp> &__v, const _Tp &__t) \ + { \ + typedef _BinClos<_Name,_ValArray,_Constant,_Tp,_Tp> _Closure; \ + return _Expr<_Closure, _Tp> (_Closure (__v, __t)); \ + } \ + \ + template<typename _Tp> \ + inline _Expr<_BinClos<_Name,_Constant,_ValArray,_Tp,_Tp>,_Tp> \ + operator##_Op (const _Tp &__t, const valarray<_Tp> &__v) \ + { \ + typedef _BinClos<_Name,_Constant,_ValArray,_Tp,_Tp> _Closure; \ + return _Expr<_Closure, _Tp> (_Closure (__t, __v)); \ + } + +_DEFINE_BINARY_OPERATOR(+, plus) +_DEFINE_BINARY_OPERATOR(-, minus) +_DEFINE_BINARY_OPERATOR(*, multiplies) +_DEFINE_BINARY_OPERATOR(/, divides) +_DEFINE_BINARY_OPERATOR(%, modulus) +_DEFINE_BINARY_OPERATOR(^, _Bitwise_xor) +_DEFINE_BINARY_OPERATOR(&, _Bitwise_and) +_DEFINE_BINARY_OPERATOR(|, _Bitwise_or) +_DEFINE_BINARY_OPERATOR(<<, _Shift_left) +_DEFINE_BINARY_OPERATOR(>>, _Shift_right) + +#undef _DEFINE_BINARY_OPERATOR + +#define _DEFINE_LOGICAL_OPERATOR(_Op, _Name) \ + template<typename _Tp> \ + inline _Expr<_BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp>,bool> \ + operator##_Op (const valarray<_Tp> &__v, const valarray<_Tp> &__w) \ + { \ + typedef _BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp> _Closure; \ + return _Expr<_Closure, bool> (_Closure (__v, __w)); \ + } \ + \ + template<class _Tp> \ + inline _Expr<_BinClos<_Name,_ValArray,_Constant,_Tp,_Tp>,bool> \ + operator##_Op (const valarray<_Tp> &__v, const _Tp &__t) \ + { \ + typedef _BinClos<_Name,_ValArray,_Constant,_Tp,_Tp> _Closure; \ + return _Expr<_Closure, bool> (_Closure (__v, __t)); \ + } \ + \ + template<class _Tp> \ + inline _Expr<_BinClos<_Name,_Constant,_ValArray,_Tp,_Tp>,bool> \ + operator##_Op (const _Tp &__t, const valarray<_Tp> &__v) \ + { \ + typedef _BinClos<_Name,_Constant,_ValArray,_Tp,_Tp> _Closure; \ + return _Expr<_Closure, bool> (_Closure (__t, __v)); \ + } + +_DEFINE_LOGICAL_OPERATOR(&&, logical_and) +_DEFINE_LOGICAL_OPERATOR(||, logical_or) +_DEFINE_LOGICAL_OPERATOR(==, equal_to) +_DEFINE_LOGICAL_OPERATOR(!=, not_equal_to) +_DEFINE_LOGICAL_OPERATOR(<, less) +_DEFINE_LOGICAL_OPERATOR(>, greater) +_DEFINE_LOGICAL_OPERATOR(<=, less_equal) +_DEFINE_LOGICAL_OPERATOR(>=, greater_equal) + +#undef _DEFINE_VALARRAY_OPERATOR + +#undef _G_NO_VALARRAY_TEMPLATE_EXPORT + +} // extern "C++" + +#endif // __STD_VALARRAY__ + +// Local Variables: +// mode:c++ +// End: diff --git a/contrib/libstdc++/std/valarray_array.h b/contrib/libstdc++/std/valarray_array.h new file mode 100644 index 0000000..f711e52 --- /dev/null +++ b/contrib/libstdc++/std/valarray_array.h @@ -0,0 +1,346 @@ +// The template and inlines for the -*- C++ -*- internal _Array helper class. + +// Copyright (C) 1997-1999 Cygnus Solutions +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> + +#ifndef __VALARRAY_ARRAY__ +#define __VALARRAY_ARRAY__ + +#include <cstdlib> +#include <cstring> + +extern "C++" { + +// +// Helper functions on raw pointers +// + +// fill plain array __a[<__n>] with __t +template<typename _Tp> +inline void +__valarray_fill (_Tp* __restrict__ __a, size_t __n, const _Tp& __t) +{ while (__n--) *__a++ = __t; } + +// fill strided array __a[<__n-1 : __s>] with __t +template<typename _Tp> +inline void +__valarray_fill (_Tp* __restrict__ __a, size_t __n, + size_t __s, const _Tp& __t) +{ for (size_t __i=0; __i<__n; ++__i, __a+=__s) *__a = __t; } + +// fill indirect array __a[__i[<__n>]] with __i +template<typename _Tp> +inline void +__valarray_fill(_Tp* __restrict__ __a, const size_t* __restrict__ __i, + size_t __n, const _Tp& __t) +{ for (size_t __j=0; __j<__n; ++__j, ++__i) __a[*__i] = __t; } + +// copy plain array __a[<__n>] in __b[<__n>] +template<typename _Tp> +inline void +__valarray_copy (const _Tp* __restrict__ __a, size_t __n, + _Tp* __restrict__ __b) +{ memcpy (__b, __a, __n * sizeof(_Tp)); } + +// copy strided array __a[<__n : __s>] in plain __b[<__n>] +template<typename _Tp> +inline void +__valarray_copy (const _Tp* __restrict__ __a, size_t __n, size_t __s, + _Tp* __restrict__ __b) +{ for (size_t __i=0; __i<__n; ++__i, ++__b, __a += __s) *__b += *__a; } + +// copy plain __a[<__n>] in strided __b[<__n : __s>] +template<typename _Tp> +inline void +__valarray_copy (const _Tp* __restrict__ __a, _Tp* __restrict__ __b, + size_t __n, size_t __s) +{ for (size_t __i=0; __i<__n; ++__i, ++__a, __b+=__s) *__b = *__a; } + +// copy indexed __a[__i[<__n>]] in plain __b[<__n>] +template<typename _Tp> +inline void +__valarray_copy (const _Tp* __restrict__ __a, + const size_t* __restrict__ __i, + _Tp* __restrict__ __b, size_t __n) +{ for (size_t __j=0; __j<__n; ++__j, ++__b, ++__i) *__b = __a[*__i]; } + +// copy plain __a[<__n>] in indexed __b[__i[<__n>]] +template<typename _Tp> +inline void +__valarray_copy (const _Tp* __restrict__ __a, size_t __n, + _Tp* __restrict__ __b, const size_t* __restrict__ __i) +{ for (size_t __j=0; __j<__n; ++__j, ++__a, ++__i) __b[*__i] = *__a; } + +// +// Helper class _Array, first layer of valarray abstraction. +// All operations on valarray should be forwarded to this class +// whenever possible. -- gdr +// + +template<typename _Tp> struct _Array { + + explicit _Array (size_t); + explicit _Array (_Tp* const __restrict__); + explicit _Array (const valarray<_Tp>&); + _Array (const _Tp* __restrict__, size_t); + + void free_data() const; + _Tp* begin () const; + + _Tp* const __restrict__ _M_data; +}; + +template<typename _Tp> +inline void +__valarray_fill (_Array<_Tp> __a, size_t __n, const _Tp& __t) +{ __valarray_fill (__a._M_data, __n, __t); } + +template<typename _Tp> +inline void +__valarray_fill (_Array<_Tp> __a, size_t __n, size_t __s, const _Tp& __t) +{ __valarray_fill (__a._M_data, __n, __s, __t); } + +template<typename _Tp> +inline void +__valarray_fill (_Array<_Tp> __a, _Array<size_t> __i, + size_t __n, const _Tp& __t) +{ __valarray_fill (__a._M_data, __i._M_data, __n, __t); } + +template<typename _Tp> +inline void +__valarray_copy (_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) +{ __valarray_copy (__a._M_data, __n, __b._M_data); } + +template<typename _Tp> +inline void +__valarray_copy (_Array<_Tp> __a, size_t __n, size_t __s, _Array<_Tp> __b) +{ __valarray_copy(__a._M_data, __n, __s, __b._M_data); } + +template<typename _Tp> +inline void +__valarray_copy (_Array<_Tp> __a, _Array<_Tp> __b, size_t __n, size_t __s) +{ __valarray_copy (__a._M_data, __b._M_data, __n, __s); } + +template<typename _Tp> +inline void +__valarray_copy (_Array<_Tp> __a, _Array<size_t> __i, + _Array<_Tp> __b, size_t __n) +{ __valarray_copy (__a._M_data, __i._M_data, __b._M_data, __n); } + +template<typename _Tp> +inline void +__valarray_copy (_Array<_Tp> __a, size_t __n, _Array<_Tp> __b, + _Array<size_t> __i) +{ __valarray_copy (__a._M_data, __n, __b._M_data, __i._M_data); } + +template<typename _Tp> +inline +_Array<_Tp>::_Array (size_t __n) : _M_data (new _Tp[__n]) {} + +template<typename _Tp> +inline +_Array<_Tp>::_Array (_Tp* const __restrict__ __p) : _M_data (__p) {} + +template<typename _Tp> +inline _Array<_Tp>::_Array (const valarray<_Tp>& __v) + : _M_data (__v._M_data) {} + +template<typename _Tp> +inline +_Array<_Tp>::_Array (const _Tp* __restrict__ __b, size_t __s) + : _M_data (new _Tp[__s]) { __valarray_copy (__b, __s, _M_data); } + +template<typename _Tp> +inline void +_Array<_Tp>::free_data() const { delete[] _M_data; } + +template<typename _Tp> +inline _Tp* +_Array<_Tp>::begin () const +{ return _M_data; } + +#define _DEFINE_ARRAY_FUNCTION(_Op, _Name) \ +template<typename _Tp> \ +inline void \ +_Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, const _Tp& __t) \ +{ \ + for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p) \ + *__p _Op##= __t; \ +} \ + \ +template<typename _Tp> \ +inline void \ +_Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) \ +{ \ + _Tp* __p (__a._M_data); \ + for (_Tp* __q=__b._M_data; __q<__b._M_data+__n; ++__p, ++__q) \ + *__p _Op##= *__q; \ +} \ + \ +template<typename _Tp, class _Dom> \ +void \ +_Array_augmented_##_Name (_Array<_Tp> __a, \ + const _Expr<_Dom,_Tp>& __e, size_t __n) \ +{ \ + _Tp* __p (__a._M_data); \ + for (size_t __i=0; __i<__n; ++__i, ++__p) *__p _Op##= __e[__i]; \ +} \ + \ +template<typename _Tp> \ +inline void \ +_Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, size_t __s, \ + _Array<_Tp> __b) \ +{ \ + _Tp* __q (__b._M_data); \ + for (_Tp* __p=__a._M_data; __p<__a._M_data+__s*__n; __p+=__s, ++__q) \ + *__p _Op##= *__q; \ +} \ + \ +template<typename _Tp> \ +inline void \ +_Array_augmented_##_Name (_Array<_Tp> __a, _Array<_Tp> __b, \ + size_t __n, size_t __s) \ +{ \ + _Tp* __q (__b._M_data); \ + for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p, __q+=__s) \ + *__p _Op##= *__q; \ +} \ + \ +template<typename _Tp, class _Dom> \ +void \ +_Array_augmented_##_Name (_Array<_Tp> __a, size_t __s, \ + const _Expr<_Dom,_Tp>& __e, size_t __n) \ +{ \ + _Tp* __p (__a._M_data); \ + for (size_t __i=0; __i<__n; ++__i, __p+=__s) *__p _Op##= __e[__i]; \ +} \ + \ +template<typename _Tp> \ +inline void \ +_Array_augmented_##_Name (_Array<_Tp> __a, _Array<size_t> __i, \ + _Array<_Tp> __b, size_t __n) \ +{ \ + _Tp* __q (__b._M_data); \ + for (size_t* __j=__i._M_data; __j<__i._M_data+__n; ++__j, ++__q) \ + __a._M_data[*__j] _Op##= *__q; \ +} \ + \ +template<typename _Tp> \ +inline void \ +_Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, \ + _Array<_Tp> __b, _Array<size_t> __i) \ +{ \ + _Tp* __p (__a._M_data); \ + for (size_t* __j=__i._M_data; __j<__i._M_data+__n; ++__j, ++__p) \ + *__p _Op##= __b._M_data[*__j]; \ +} \ + \ +template<typename _Tp, class _Dom> \ +void \ +_Array_augmented_##_Name (_Array<_Tp> __a, _Array<size_t> __i, \ + const _Expr<_Dom, _Tp>& __e, size_t __n) \ +{ \ + size_t* __j (__i._M_data); \ + for (size_t __k=0; __k<__n; ++__k, ++__j) \ + __a._M_data[*__j] _Op##= __e[__k]; \ +} \ + \ +template<typename _Tp> \ +void \ +_Array_augmented_##_Name (_Array<_Tp> __a, _Array<bool> __m, \ + _Array<_Tp> __b, size_t __n) \ +{ \ + bool* ok (__m._M_data); \ + _Tp* __p (__a._M_data); \ + for (_Tp* __q=__b._M_data; __q<__b._M_data+__n; ++__q, ++ok, ++__p) { \ + while (! *ok) { \ + ++ok; \ + ++__p; \ + } \ + *__p _Op##= *__q; \ + } \ +} \ + \ +template<typename _Tp> \ +void \ +_Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, \ + _Array<_Tp> __b, _Array<bool> __m) \ +{ \ + bool* ok (__m._M_data); \ + _Tp* __q (__b._M_data); \ + for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p, ++ok, ++__q) { \ + while (! *ok) { \ + ++ok; \ + ++__q; \ + } \ + *__p _Op##= *__q; \ + } \ +} \ + \ +template<typename _Tp, class _Dom> \ +void \ +_Array_augmented_##_Name (_Array<_Tp> __a, _Array<bool> __m, \ + const _Expr<_Dom, _Tp>& __e, size_t __n) \ +{ \ + bool* ok(__m._M_data); \ + _Tp* __p (__a._M_data); \ + for (size_t __i=0; __i<__n; ++__i, ++ok, ++__p) { \ + while (! *ok) { \ + ++ok; \ + ++__p; \ + } \ + *__p _Op##= __e[__i]; \ + } \ +} + +_DEFINE_ARRAY_FUNCTION(+, plus) +_DEFINE_ARRAY_FUNCTION(-, minus) +_DEFINE_ARRAY_FUNCTION(*, multiplies) +_DEFINE_ARRAY_FUNCTION(/, divides) +_DEFINE_ARRAY_FUNCTION(%, modulus) +_DEFINE_ARRAY_FUNCTION(^, xor) +_DEFINE_ARRAY_FUNCTION(|, or) +_DEFINE_ARRAY_FUNCTION(&, and) +_DEFINE_ARRAY_FUNCTION(<<, shift_left) +_DEFINE_ARRAY_FUNCTION(>>, shift_right) + +#undef _DEFINE_ARRAY_FUNCTION + +} // extern "C++" + +#ifdef _G_NO_VALARRAY_TEMPLATE_EXPORT +# define export +# include <std/valarray_array.tcc> +#endif + +#endif // __VALARRAY_ARRAY__ + +// Local Variables: +// mode:c++ +// End: diff --git a/contrib/libstdc++/std/valarray_array.tcc b/contrib/libstdc++/std/valarray_array.tcc new file mode 100644 index 0000000..bd66925 --- /dev/null +++ b/contrib/libstdc++/std/valarray_array.tcc @@ -0,0 +1,130 @@ +// The template and inlines for the -*- C++ -*- internal _Array helper class. + +// Copyright (C) 1997-1999 Cygnus Solutions +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> + +#ifndef __VALARRAY_ARRAY_TCC__ +#define __VALARRAY_ARRAY_TCC__ + +extern "C++" { + +export template<typename _Tp> +void +__valarray_fill (_Array<_Tp> __a, size_t __n, _Array<bool> __m, const _Tp& __t) +{ + _Tp* __p = __a._M_data; + bool* __ok (__m._M_data); + for (size_t __i=0; __i<__n; ++__i, ++__ok, ++__p) { + while (! *__ok) { + ++__ok; + ++__p; + } + *__p = __t; + } +} + +export template<typename _Tp> +void +__valarray_copy (_Array<_Tp> __a, _Array<bool> __m, _Array<_Tp> __b, size_t __n) +{ + _Tp* __p (__a._M_data); + bool* __ok (__m._M_data); + for (_Tp* __q=__b._M_data; __q<__b._M_data+__n; ++__q, ++__ok, ++__p) { + while (! *__ok) { + ++__ok; + ++__p; + } + *__q = *__p; + } +} + +export template<typename _Tp> +void +__valarray_copy (_Array<_Tp> __a, size_t __n, _Array<_Tp> __b, _Array<bool> __m) +{ + _Tp* __q (__b._M_data); + bool* __ok (__m._M_data); + for (_Tp* __p=__a._M_data; __p<__a._M_data+__n; ++__p, ++__ok, ++__q) { + while (! *__ok) { + ++__ok; + ++__q; + } + *__q = *__p; + } +} + +export template<typename _Tp, class _Dom> +void +__valarray_copy (const _Expr<_Dom, _Tp>& __e, size_t __n, _Array<_Tp> __a) +{ + _Tp* __p (__a._M_data); + for (size_t __i=0; __i<__n; ++__i, ++__p) *__p = __e[__i]; +} + +export template<typename _Tp, class _Dom> +void +__valarray_copy (const _Expr<_Dom, _Tp>& __e, size_t __n, + _Array<_Tp> __a, size_t __s) +{ + _Tp* __p (__a._M_data); + for (size_t __i=0; __i<__n; ++__i, __p+=__s) *__p = __e[__i]; +} + +export template<typename _Tp, class _Dom> +void +__valarray_copy (const _Expr<_Dom, _Tp>& __e, size_t __n, + _Array<_Tp> __a, _Array<size_t> __i) +{ + size_t* __j (__i._M_data); + for (size_t __k=0; __k<__n; ++__k, ++__j) __a._M_data[*__j] = __e[__k]; +} + +export template<typename _Tp, class _Dom> +void +__valarray_copy (const _Expr<_Dom, _Tp>& __e, size_t __n, + _Array<_Tp> __a, _Array<bool> __m) +{ + bool* __ok (__m._M_data); + _Tp* __p (__a._M_data); + for (size_t __i=0; __i<__n; ++__i, ++__ok, ++__p) { + while (! *__ok) { + ++__ok; + ++__p; + } + *__p = __e[__i]; + } +} + +} // extern "C++" + +#endif // __VALARRAY_ARRAY_TCC__ + +// Local Variables: +// mode:c++ +// End: diff --git a/contrib/libstdc++/std/valarray_meta.h b/contrib/libstdc++/std/valarray_meta.h new file mode 100644 index 0000000..f799111 --- /dev/null +++ b/contrib/libstdc++/std/valarray_meta.h @@ -0,0 +1,1045 @@ +// The template and inlines for the -*- C++ -*- internal _Meta class. + +// Copyright (C) 1997-1999 Cygnus Solutions +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@cmla.ens-cachan.fr> + +#ifndef _CPP_VALARRAY_META_H +#define _CPP_VALARRAY_META_H 1 + +// +// Implementing a loosened valarray return value is tricky. +// First we need to meet 26.3.1/3: we should not add more than +// two levels of template nesting. Therefore we resort to template +// template to "flatten" loosened return value types. +// At some point we use partial specialization to remove one level +// template nesting due to _Expr<> +// + + +// This class is NOT defined. It doesn't need to. +template<typename _Tp1, typename _Tp2> class _Constant; + +// +// Unary function application closure. +// +template<class _Dom> class _UnFunBase { +public: + typedef typename _Dom::value_type value_type; + typedef value_type _Vt; + + _UnFunBase (const _Dom& __e, _Vt __f(_Vt)) + : _M_expr(__e), _M_func(__f) {} + + _Vt operator[] (size_t __i) const { return _M_func(_M_expr[__i]); } + size_t size () const { return _M_expr.size(); } + +private: + const _Dom& _M_expr; + _Vt (*_M_func)(_Vt); +}; + +template<template<class, class> class _Meta, class _Dom> class _UnFunClos; + +template<class _Dom> +struct _UnFunClos<_Expr,_Dom> : _UnFunBase<_Dom> { + typedef _UnFunBase<_Dom> _Base; + typedef typename _Base::value_type value_type; + + _UnFunClos (const _Dom& __e, value_type __f(value_type)) + : _Base (__e, __f) {} +}; + +template<typename _Tp> +struct _UnFunClos<_ValArray,_Tp> : _UnFunBase<valarray<_Tp> > { + typedef _UnFunBase<valarray<_Tp> > _Base; + typedef typename _Base::value_type value_type; + + _UnFunClos (const valarray<_Tp>& __v, _Tp __f(_Tp)) + : _Base (__v, __f) {} +}; + +// +// Binary function application closure. +// +template<template<class, class> class _Meta1, + template<class, class> class Meta2, + class _Dom1, class _Dom2> class _BinFunClos; + +template<class _Dom1, class _Dom2> class _BinFunBase { +public: + typedef typename _Dom1::value_type value_type; + typedef value_type _Vt; + + _BinFunBase (const _Dom1& __e1, const _Dom2& __e2, + _Vt __f (_Vt, _Vt)) + : _M_expr1 (__e1), _M_expr2 (__e2), _M_func (__f) {} + + value_type operator[] (size_t __i) const + { return _M_func (_M_expr1[__i], _M_expr2[__i]); } + size_t size () const { return _M_expr1.size (); } + +private: + const _Dom1& _M_expr1; + const _Dom2& _M_expr2; + _Vt (*_M_func)(_Vt, _Vt); +}; + +template<class _Dom> class _BinFunBase1 { +public: + typedef typename _Dom::value_type value_type ; + typedef value_type _Vt; + + _BinFunBase1 (const _Vt& __c, const _Dom& __e, _Vt __f(_Vt, _Vt)) + : _M_expr1 (__c), _M_expr2 (__e), _M_func (__f) {} + + value_type operator[] (size_t __i) const + { return _M_func (_M_expr1, _M_expr2[__i]); } + size_t size () const { return _M_expr2.size (); } + +private: + const _Vt& _M_expr1; + const _Dom& _M_expr2; + _Vt (*_M_func)(_Vt, _Vt); +}; + +template<class _Dom> class _BinFunBase2 { +public: + typedef typename _Dom::value_type value_type; + typedef value_type _Vt; + + _BinFunBase2 (const _Dom& __e, const _Vt& __c, _Vt __f(_Vt, _Vt)) + : _M_expr1 (__e), _M_expr2 (__c), _M_func (__f) {} + + value_type operator[] (size_t __i) const + { return _M_func (_M_expr1[__i], _M_expr2); } + size_t size () const { return _M_expr1.size (); } + +private: + const _Dom& _M_expr1; + const _Vt& _M_expr2; + _Vt (*_M_func)(_Vt, _Vt); +}; + +template<class _Dom1, class _Dom2> +struct _BinFunClos<_Expr,_Expr,_Dom1,_Dom2> : _BinFunBase<_Dom1,_Dom2> { + typedef _BinFunBase<_Dom1,_Dom2> _Base; + typedef typename _Base::value_type value_type; + typedef value_type _Tp; + + _BinFunClos (const _Dom1& __e1, const _Dom2& __e2, + _Tp __f(_Tp, _Tp)) + : _Base (__e1, __e2, __f) {} +}; + +template<typename _Tp> +struct _BinFunClos<_ValArray,_ValArray,_Tp,_Tp> + : _BinFunBase<valarray<_Tp>, valarray<_Tp> > { + typedef _BinFunBase<valarray<_Tp>, valarray<_Tp> > _Base; + typedef _Tp value_type; + + _BinFunClos (const valarray<_Tp>& __v, const valarray<_Tp>& __w, + _Tp __f(_Tp, _Tp)) + : _Base (__v, __w, __f) {} +}; + +template<class _Dom> +struct _BinFunClos<_Expr,_ValArray,_Dom,typename _Dom::value_type> + : _BinFunBase<_Dom,valarray<typename _Dom::value_type> > { + typedef typename _Dom::value_type _Tp; + typedef _BinFunBase<_Dom,valarray<_Tp> > _Base; + typedef _Tp value_type; + + _BinFunClos (const _Dom& __e, const valarray<_Tp>& __v, + _Tp __f(_Tp, _Tp)) + : _Base (__e, __v, __f) {} +}; + +template<class _Dom> +struct _BinFunClos<_ValArray,_Expr,typename _Dom::value_type,_Dom> + : _BinFunBase<valarray<typename _Dom::value_type>,_Dom> { + typedef typename _Dom::value_type _Tp; + typedef _BinFunBase<_Dom,valarray<_Tp> > _Base; + typedef _Tp value_type; + + _BinFunClos (const valarray<_Tp>& __v, const _Dom& __e, + _Tp __f(_Tp, _Tp)) + : _Base (__v, __e, __f) {} +}; + +template<class _Dom> +struct _BinFunClos<_Expr,_Constant,_Dom,typename _Dom::value_type> + : _BinFunBase2<_Dom> { + typedef typename _Dom::value_type _Tp; + typedef _Tp value_type; + typedef _BinFunBase2<_Dom> _Base; + + _BinFunClos (const _Dom& __e, const _Tp& __t, _Tp __f (_Tp, _Tp)) + : _Base (__e, __t, __f) {} +}; + +template<class _Dom> +struct _BinFunClos<_Constant,_Expr,_Dom,typename _Dom::value_type> + : _BinFunBase1<_Dom> { + typedef typename _Dom::value_type _Tp; + typedef _Tp value_type; + typedef _BinFunBase1<_Dom> _Base; + + _BinFunClos (const _Tp& __t, const _Dom& __e, _Tp __f (_Tp, _Tp)) + : _Base (__t, __e, __f) {} +}; + +template<typename _Tp> +struct _BinFunClos<_ValArray,_Constant,_Tp,_Tp> + : _BinFunBase2<valarray<_Tp> > { + typedef _BinFunBase2<valarray<_Tp> > _Base; + typedef _Tp value_type; + + _BinFunClos (const valarray<_Tp>& __v, const _Tp& __t, + _Tp __f(_Tp, _Tp)) + : _Base (__v, __t, __f) {} +}; + +template<typename _Tp> +struct _BinFunClos<_Constant,_ValArray,_Tp,_Tp> + : _BinFunBase1<valarray<_Tp> > { + typedef _BinFunBase1<valarray<_Tp> > _Base; + typedef _Tp value_type; + + _BinFunClos (const _Tp& __t, const valarray<_Tp>& __v, + _Tp __f (_Tp, _Tp)) + : _Base (__t, __v, __f) {} +}; + +// +// Apply function taking a value/const reference closure +// + +template<typename _Dom, typename _Arg> class _FunBase { +public: + typedef typename _Dom::value_type value_type; + + _FunBase (const _Dom& __e, value_type __f(_Arg)) + : _M_expr (__e), _M_func (__f) {} + + value_type operator[] (size_t __i) const + { return _M_func (_M_expr[__i]); } + size_t size() const { return _M_expr.size ();} + +private: + const _Dom& _M_expr; + value_type (*_M_func)(_Arg); +}; + +template<class _Dom> +struct _ValFunClos<_Expr,_Dom> + : _FunBase<_Dom, typename _Dom::value_type> { + typedef _FunBase<_Dom, typename _Dom::value_type> _Base; + typedef typename _Base::value_type value_type; + typedef value_type _Tp; + + _ValFunClos (const _Dom& __e, _Tp __f (_Tp)) : _Base (__e, __f) {} +}; + +template<typename _Tp> +struct _ValFunClos<_ValArray,_Tp> + : _FunBase<valarray<_Tp>, _Tp> { + typedef _FunBase<valarray<_Tp>, _Tp> _Base; + typedef _Tp value_type; + + _ValFunClos (const valarray<_Tp>& __v, _Tp __f(_Tp)) + : _Base (__v, __f) {} +}; + +template<class _Dom> +struct _RefFunClos<_Expr,_Dom> : + _FunBase<_Dom, const typename _Dom::value_type&> { + typedef _FunBase<_Dom, const typename _Dom::value_type&> _Base; + typedef typename _Base::value_type value_type; + typedef value_type _Tp; + + _RefFunClos (const _Dom& __e, _Tp __f (const _Tp&)) + : _Base (__e, __f) {} +}; + +template<typename _Tp> +struct _RefFunClos<_ValArray,_Tp> + : _FunBase<valarray<_Tp>, const _Tp&> { + typedef _FunBase<valarray<_Tp>, const _Tp&> _Base; + typedef _Tp value_type; + + _RefFunClos (const valarray<_Tp>& __v, _Tp __f(const _Tp&)) + : _Base (__v, __f) {} +}; + +// +// Unary expression closure. +// + +template<template<class> class _Oper, typename _Arg> +class _UnBase { +public: + typedef _Oper<typename _Arg::value_type> _Op; + typedef typename _Op::result_type value_type; + + _UnBase (const _Arg& __e) : _M_expr(__e) {} + value_type operator[] (size_t) const; + size_t size () const { return _M_expr.size (); } + +private: + const _Arg& _M_expr; +}; + +template<template<class> class _Oper, typename _Arg> +inline typename _UnBase<_Oper, _Arg>::value_type +_UnBase<_Oper, _Arg>::operator[] (size_t __i) const +{ return _Op() (_M_expr[__i]); } + +template<template<class> class _Oper, class _Dom> +struct _UnClos<_Oper, _Expr, _Dom> : _UnBase<_Oper, _Dom> { + typedef _Dom _Arg; + typedef _UnBase<_Oper, _Dom> _Base; + typedef typename _Base::value_type value_type; + + _UnClos (const _Arg& __e) : _Base(__e) {} +}; + +template<template<class> class _Oper, typename _Tp> +struct _UnClos<_Oper, _ValArray, _Tp> : _UnBase<_Oper, valarray<_Tp> > { + typedef valarray<_Tp> _Arg; + typedef _UnBase<_Oper, valarray<_Tp> > _Base; + typedef typename _Base::value_type value_type; + + _UnClos (const _Arg& __e) : _Base(__e) {} +}; + + +// +// Binary expression closure. +// + +template<template<class> class _Oper, typename _FirstArg, typename _SecondArg> +class _BinBase { +public: + typedef _Oper<typename _FirstArg::value_type> _Op; + typedef typename _Op::result_type value_type; + + _BinBase (const _FirstArg& __e1, const _SecondArg& __e2) + : _M_expr1 (__e1), _M_expr2 (__e2) {} + value_type operator[] (size_t) const; + size_t size () const { return _M_expr1.size (); } + +private: + const _FirstArg& _M_expr1; + const _SecondArg& _M_expr2; +}; + +template<template<class> class _Oper, typename _FirstArg, typename _SecondArg> +inline typename _BinBase<_Oper,_FirstArg,_SecondArg>::value_type +_BinBase<_Oper,_FirstArg,_SecondArg>::operator[] (size_t __i) const +{ return _Op() (_M_expr1[__i], _M_expr2[__i]); } + + +template<template<class> class _Oper, class _Clos> +class _BinBase2 { +public: + typedef typename _Clos::value_type _Vt; + typedef _Oper<_Vt> _Op; + typedef typename _Op::result_type value_type; + + _BinBase2 (const _Clos& __e, const _Vt& __t) + : _M_expr1 (__e), _M_expr2 (__t) {} + value_type operator[] (size_t) const; + size_t size () const { return _M_expr1.size (); } + +private: + const _Clos& _M_expr1; + const _Vt& _M_expr2; +}; + +template<template<class> class _Oper, class _Clos> +inline typename _BinBase2<_Oper,_Clos>::value_type +_BinBase2<_Oper,_Clos>::operator[] (size_t __i) const +{ return _Op() (_M_expr1[__i], _M_expr2); } + + +template<template<class> class _Oper, class _Clos> +class _BinBase1 { +public: + typedef typename _Clos::value_type _Vt; + typedef _Oper<_Vt> _Op; + typedef typename _Op::result_type value_type; + + _BinBase1 (const _Vt& __t, const _Clos& __e) + : _M_expr1 (__t), _M_expr2 (__e) {} + value_type operator[] (size_t) const; + size_t size () const { return _M_expr2.size (); } + +private: + const _Vt& _M_expr1; + const _Clos& _M_expr2; +}; + +template<template<class> class _Oper, class _Clos> +inline typename +_BinBase1<_Oper,_Clos>::value_type +_BinBase1<_Oper,_Clos>:: operator[] (size_t __i) const +{ return _Op() (_M_expr1, _M_expr2[__i]); } + + +template<template<class> class _Oper, class _Dom1, class _Dom2> +struct _BinClos<_Oper, _Expr, _Expr, _Dom1, _Dom2> + : _BinBase<_Oper,_Dom1,_Dom2> { + typedef _BinBase<_Oper,_Dom1,_Dom2> _Base; + typedef typename _Base::value_type value_type; + + _BinClos(const _Dom1& __e1, const _Dom2& __e2) : _Base(__e1, __e2) {} +}; + +template<template<class> class _Oper, typename _Tp> +struct _BinClos<_Oper,_ValArray,_ValArray,_Tp,_Tp> + : _BinBase<_Oper,valarray<_Tp>,valarray<_Tp> > { + typedef _BinBase<_Oper,valarray<_Tp>,valarray<_Tp> > _Base; + typedef _Tp value_type; + + _BinClos (const valarray<_Tp>& __v, const valarray<_Tp>& __w) + : _Base (__v, __w) {} +}; + +template<template<class> class _Oper, class _Dom> +struct _BinClos<_Oper,_Expr,_ValArray,_Dom,typename _Dom::value_type> + : _BinBase<_Oper,_Dom,valarray<typename _Dom::value_type> > { + typedef typename _Dom::value_type _Tp; + typedef _BinBase<_Oper,_Dom,valarray<_Tp> > _Base; + typedef typename _Base::value_type value_type; + + _BinClos(const _Dom& __e1, const valarray<_Tp>& __e2) + : _Base (__e1, __e2) {} +}; + +template<template<class> class _Oper, class _Dom> +struct _BinClos<_Oper,_ValArray,_Expr,typename _Dom::value_type,_Dom> + : _BinBase<_Oper,valarray<typename _Dom::value_type>,_Dom> { + typedef typename _Dom::value_type _Tp; + typedef _BinBase<_Oper,valarray<_Tp>,_Dom> _Base; + typedef typename _Base::value_type value_type; + + _BinClos (const valarray<_Tp> __e1, const _Dom& __e2) + : _Base (__e1, __e2) {} +}; + +template<template<class> class _Oper, class _Dom> +struct _BinClos<_Oper,_Expr,_Constant,_Dom,typename _Dom::value_type> + : _BinBase2<_Oper,_Dom> { + typedef typename _Dom::value_type _Tp; + typedef _BinBase2<_Oper,_Dom> _Base; + typedef typename _Base::value_type value_type; + + _BinClos (const _Dom& __e1, const _Tp& __e2) : _Base (__e1, __e2) {} +}; + +template<template<class> class _Oper, class _Dom> +struct _BinClos<_Oper,_Constant,_Expr,typename _Dom::value_type,_Dom> + : _BinBase1<_Oper,_Dom> { + typedef typename _Dom::value_type _Tp; + typedef _BinBase1<_Oper,_Dom> _Base; + typedef typename _Base::value_type value_type; + + _BinClos (const _Tp& __e1, const _Dom& __e2) : _Base (__e1, __e2) {} +}; + +template<template<class> class _Oper, typename _Tp> +struct _BinClos<_Oper,_ValArray,_Constant,_Tp,_Tp> + : _BinBase2<_Oper,valarray<_Tp> > { + typedef _BinBase2<_Oper,valarray<_Tp> > _Base; + typedef typename _Base::value_type value_type; + + _BinClos (const valarray<_Tp>& __v, const _Tp& __t) + : _Base (__v, __t) {} +}; + +template<template<class> class _Oper, typename _Tp> +struct _BinClos<_Oper,_Constant,_ValArray,_Tp,_Tp> + : _BinBase1<_Oper,valarray<_Tp> > { + typedef _BinBase1<_Oper,valarray<_Tp> > _Base; + typedef typename _Base::value_type value_type; + + _BinClos (const _Tp& __t, const valarray<_Tp>& __v) + : _Base (__t, __v) {} +}; + + +// +// slice_array closure. +// +template<typename _Dom> class _SBase { +public: + typedef typename _Dom::value_type value_type; + + _SBase (const _Dom& __e, const slice& __s) + : _M_expr (__e), _M_slice (__s) {} + value_type operator[] (size_t __i) const + { return _M_expr[_M_slice.start () + __i * _M_slice.stride ()]; } + size_t size() const { return _M_slice.size (); } + +private: + const _Dom& _M_expr; + const slice& _M_slice; +}; + +template<typename _Tp> class _SBase<_Array<_Tp> > { +public: + typedef _Tp value_type; + + _SBase (_Array<_Tp> __a, const slice& __s) + : _M_array (__a._M_data+__s.start()), _M_size (__s.size()), + _M_stride (__s.stride()) {} + value_type operator[] (size_t __i) const + { return _M_array._M_data[__i * _M_stride]; } + size_t size() const { return _M_size; } + +private: + const _Array<_Tp> _M_array; + const size_t _M_size; + const size_t _M_stride; +}; + +template<class _Dom> struct _SClos<_Expr,_Dom> : _SBase<_Dom> { + typedef _SBase<_Dom> _Base; + typedef typename _Base::value_type value_type; + + _SClos (const _Dom& __e, const slice& __s) : _Base (__e, __s) {} +}; + +template<typename _Tp> +struct _SClos<_ValArray,_Tp> : _SBase<_Array<_Tp> > { + typedef _SBase<_Array<_Tp> > _Base; + typedef _Tp value_type; + + _SClos (_Array<_Tp> __a, const slice& __s) : _Base (__a, __s) {} +}; + +// +// gslice_array closure. +// +template<class _Dom> class _GBase { +public: + typedef typename _Dom::value_type value_type; + + _GBase (const _Dom& __e, const valarray<size_t>& __i) + : _M_expr (__e), _M_index(__i) {} + value_type operator[] (size_t __i) const + { return _M_expr[_M_index[__i]]; } + size_t size () const { return _M_index.size(); } + +private: + const _Dom& _M_expr; + const valarray<size_t>& _M_index; +}; + +template<typename _Tp> class _GBase<_Array<_Tp> > { +public: + typedef _Tp value_type; + + _GBase (_Array<_Tp> __a, const valarray<size_t>& __i) + : _M_array (__a), _M_index(__i) {} + value_type operator[] (size_t __i) const + { return _M_array._M_data[_M_index[__i]]; } + size_t size () const { return _M_index.size(); } + +private: + const _Array<_Tp> _M_array; + const valarray<size_t>& _M_index; +}; + +template<class _Dom> struct _GClos<_Expr,_Dom> : _GBase<_Dom> { + typedef _GBase<_Dom> _Base; + typedef typename _Base::value_type value_type; + + _GClos (const _Dom& __e, const valarray<size_t>& __i) + : _Base (__e, __i) {} +}; + +template<typename _Tp> +struct _GClos<_ValArray,_Tp> : _GBase<_Array<_Tp> > { + typedef _GBase<_Array<_Tp> > _Base; + typedef typename _Base::value_type value_type; + + _GClos (_Array<_Tp> __a, const valarray<size_t>& __i) + : _Base (__a, __i) {} +}; + +// +// indirect_array closure +// + +template<class _Dom> class _IBase { +public: + typedef typename _Dom::value_type value_type; + + _IBase (const _Dom& __e, const valarray<size_t>& __i) + : _M_expr (__e), _M_index (__i) {} + value_type operator[] (size_t __i) const + { return _M_expr[_M_index[__i]]; } + size_t size() const { return _M_index.size(); } + +private: + const _Dom& _M_expr; + const valarray<size_t>& _M_index; +}; + +template<class _Dom> struct _IClos<_Expr,_Dom> : _IBase<_Dom> { + typedef _IBase<_Dom> _Base; + typedef typename _Base::value_type value_type; + + _IClos (const _Dom& __e, const valarray<size_t>& __i) + : _Base (__e, __i) {} +}; + +template<typename _Tp> +struct _IClos<_ValArray,_Tp> : _IBase<valarray<_Tp> > { + typedef _IBase<valarray<_Tp> > _Base; + typedef _Tp value_type; + + _IClos (const valarray<_Tp>& __a, const valarray<size_t>& __i) + : _Base (__a, __i) {} +}; + +// +// class _Expr +// +template<class _Clos, typename _Tp> class _Expr { +public: + typedef _Tp value_type; + + _Expr (const _Clos&); + + const _Clos& operator() () const; + + value_type operator[] (size_t) const; + valarray<value_type> operator[] (slice) const; + valarray<value_type> operator[] (const gslice&) const; + valarray<value_type> operator[] (const valarray<bool>&) const; + valarray<value_type> operator[] (const valarray<size_t>&) const; + + _Expr<_UnClos<_Unary_plus,_Expr,_Clos>, value_type> + operator+ () const; + + _Expr<_UnClos<negate,_Expr,_Clos>, value_type> + operator- () const; + + _Expr<_UnClos<_Bitwise_not,_Expr,_Clos>, value_type> + operator~ () const; + + _Expr<_UnClos<logical_not,_Expr,_Clos>, bool> + operator! () const; + + size_t size () const; + value_type sum () const; + + valarray<value_type> shift (int) const; + valarray<value_type> cshift (int) const; +// _Meta<_ApplyFunctionWithValue<_Expr>, value_type> +// apply (value_type _M_func (value_type)) const; +// _Meta<_ApplyFunctionWithConstRef<_Expr>, value_type> +// apply (value_type _M_func (const value_type&)) const; + +private: + const _Clos _M_closure; +}; + +template<class _Clos, typename _Tp> +inline +_Expr<_Clos,_Tp>::_Expr (const _Clos& __c) : _M_closure(__c) {} + +template<class _Clos, typename _Tp> +inline const _Clos& +_Expr<_Clos,_Tp>::operator() () const +{ return _M_closure; } + +template<class _Clos, typename _Tp> +inline _Tp +_Expr<_Clos,_Tp>::operator[] (size_t __i) const +{ return _M_closure[__i]; } + +template<class _Clos, typename _Tp> +inline valarray<_Tp> +_Expr<_Clos,_Tp>::operator[] (slice __s) const +{ return _M_closure[__s]; } + +template<class _Clos, typename _Tp> +inline valarray<_Tp> +_Expr<_Clos,_Tp>::operator[] (const gslice& __gs) const +{ return _M_closure[__gs]; } + +template<class _Clos, typename _Tp> +inline valarray<_Tp> +_Expr<_Clos,_Tp>::operator[] (const valarray<bool>& __m) const +{ return _M_closure[__m]; } + +template<class _Clos, typename _Tp> +inline valarray<_Tp> +_Expr<_Clos,_Tp>::operator[] (const valarray<size_t>& __i) const +{ return _M_closure[__i]; } + +template<class _Clos, typename _Tp> +inline size_t +_Expr<_Clos,_Tp>::size () const { return _M_closure.size (); } + +// XXX: replace this with a more robust summation algorithm. +template<class _Clos, typename _Tp> +inline _Tp +_Expr<_Clos,_Tp>::sum () const +{ + _Tp __s(_Tp()); + size_t __n (_M_closure.size ()); + for (size_t __i=0; __i<__n; ++__i) __s += _M_closure[__i]; + return __s; +} + +template<class _Dom, typename _Tp> +inline _Tp +min (const _Expr<_Dom,_Tp>& __e) +{ + size_t __s (__e.size ()); + _Tp __m (__e[0]); + for (size_t __i=1; __i<__s; ++__i) + if (__m > __e[__i]) __m = __e[__i]; + return __m; +} + +template<class _Dom, typename _Tp> +inline _Tp +max (const _Expr<_Dom,_Tp>& __e) +{ + size_t __s (__e.size()); + _Tp __m (__e[0]); + for (size_t __i=1; __i<__s; ++__i) + if (__m < __e[__i]) __m = __e[__i]; + return __m; +} + +template<class _Dom, typename _Tp> +inline _Expr<_UnClos<logical_not,_Expr,_Dom>, bool> +_Expr<_Dom,_Tp>::operator! () const +{ + typedef _UnClos<logical_not,_Expr,_Dom> _Closure; + return _Expr<_Closure,_Tp> (_Closure(this->_M_closure)); +} + +#define _DEFINE_EXPR_UNARY_OPERATOR(_Op, _Name) \ +template<class _Dom, typename _Tp> \ +inline _Expr<_UnClos<_Name,_Expr,_Dom>,_Tp> \ +_Expr<_Dom,_Tp>::operator##_Op () const \ +{ \ + typedef _UnClos<_Name,_Expr,_Dom> _Closure; \ + return _Expr<_Closure,_Tp> (_Closure (this->_M_closure)); \ +} + + _DEFINE_EXPR_UNARY_OPERATOR(+, _Unary_plus) + _DEFINE_EXPR_UNARY_OPERATOR(-, negate) + _DEFINE_EXPR_UNARY_OPERATOR(~, _Bitwise_not) + +#undef _DEFINE_EXPR_UNARY_OPERATOR + + +#define _DEFINE_EXPR_BINARY_OPERATOR(_Op, _Name) \ +template<class _Dom1, class _Dom2> \ +inline _Expr<_BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2>, \ + typename _Name<typename _Dom1::value_type>::result_type> \ +operator##_Op (const _Expr<_Dom1,typename _Dom1::value_type>& __v, \ + const _Expr<_Dom2,typename _Dom2::value_type>& __w) \ +{ \ + typedef typename _Dom1::value_type _Arg; \ + typedef typename _Name<_Arg>::result_type _Value; \ + typedef _BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2> _Closure; \ + return _Expr<_Closure,_Value> (_Closure (__v (), __w ())); \ +} \ + \ +template<class _Dom> \ +inline _Expr<_BinClos<_Name,_Expr,_Constant,_Dom,typename _Dom::value_type>, \ + typename _Name<typename _Dom::value_type>::result_type> \ +operator##_Op (const _Expr<_Dom,typename _Dom::value_type>& __v, \ + const typename _Dom::value_type& __t) \ +{ \ + typedef typename _Dom::value_type _Arg; \ + typedef typename _Name<_Arg>::result_type _Value; \ + typedef _BinClos<_Name,_Expr,_Constant,_Dom,_Arg> _Closure; \ + return _Expr<_Closure,_Value> (_Closure (__v (), __t)); \ +} \ + \ +template<class _Dom> \ +inline _Expr<_BinClos<_Name,_Constant,_Expr,typename _Dom::value_type,_Dom>, \ + typename _Name<typename _Dom::value_type>::result_type> \ +operator##_Op (const typename _Dom::value_type& __t, \ + const _Expr<_Dom,typename _Dom::value_type>& __v) \ +{ \ + typedef typename _Dom::value_type _Arg; \ + typedef typename _Name<_Arg>::result_type _Value; \ + typedef _BinClos<_Name,_Constant,_Expr,_Arg,_Dom> _Closure; \ + return _Expr<_Closure,_Value> (_Closure (__t, __v ())); \ +} \ + \ +template<class _Dom> \ +inline _Expr<_BinClos<_Name,_Expr,_ValArray,_Dom,typename _Dom::value_type>, \ + typename _Name<typename _Dom::value_type>::result_type> \ +operator##_Op (const _Expr<_Dom,typename _Dom::value_type>& __e, \ + const valarray<typename _Dom::value_type>& __v) \ +{ \ + typedef typename _Dom::value_type _Arg; \ + typedef typename _Name<_Arg>::result_type _Value; \ + typedef _BinClos<_Name,_Expr,_ValArray,_Dom,_Arg> _Closure; \ + return _Expr<_Closure,_Value> (_Closure (__e (), __v)); \ +} \ + \ +template<class _Dom> \ +inline _Expr<_BinClos<_Name,_ValArray,_Expr,typename _Dom::value_type,_Dom>, \ + typename _Name<typename _Dom::value_type>::result_type> \ +operator##_Op (const valarray<typename _Dom::value_type>& __v, \ + const _Expr<_Dom,typename _Dom::value_type>& __e) \ +{ \ + typedef typename _Dom::value_type _Tp; \ + typedef typename _Name<_Tp>::result_type _Value; \ + typedef _BinClos<_Name,_ValArray,_Expr,_Tp,_Dom> _Closure; \ + return _Expr<_Closure,_Value> (_Closure (__v, __e ())); \ +} + + _DEFINE_EXPR_BINARY_OPERATOR(+, plus) + _DEFINE_EXPR_BINARY_OPERATOR(-, minus) + _DEFINE_EXPR_BINARY_OPERATOR(*, multiplies) + _DEFINE_EXPR_BINARY_OPERATOR(/, divides) + _DEFINE_EXPR_BINARY_OPERATOR(%, modulus) + _DEFINE_EXPR_BINARY_OPERATOR(^, _Bitwise_xor) + _DEFINE_EXPR_BINARY_OPERATOR(&, _Bitwise_and) + _DEFINE_EXPR_BINARY_OPERATOR(|, _Bitwise_or) + _DEFINE_EXPR_BINARY_OPERATOR(<<, _Shift_left) + _DEFINE_EXPR_BINARY_OPERATOR(>>, _Shift_right) + +#undef _DEFINE_EXPR_BINARY_OPERATOR + +#define _DEFINE_EXPR_RELATIONAL_OPERATOR(_Op, _Name) \ +template<class _Dom1, class _Dom2> \ +inline _Expr<_BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2>, bool> \ +operator##_Op (const _Expr<_Dom1,typename _Dom1::value_type>& __v, \ + const _Expr<_Dom2,typename _Dom2::value_type>& __w) \ +{ \ + typedef typename _Dom1::value_type _Arg; \ + typedef _BinClos<_Name,_Expr,_Expr,_Dom1,_Dom2> _Closure; \ + return _Expr<_Closure,bool> (_Closure (__v (), __w ())); \ +} \ + \ +template<class _Dom> \ +inline _Expr<_BinClos<_Name,_Expr,_Constant,_Dom,typename _Dom::value_type>, \ + bool> \ +operator##_Op (const _Expr<_Dom,typename _Dom::value_type>& __v, \ + const typename _Dom::value_type& __t) \ +{ \ + typedef typename _Dom::value_type _Arg; \ + typedef _BinClos<_Name,_Expr,_Constant,_Dom,_Arg> _Closure; \ + return _Expr<_Closure,bool> (_Closure (__v (), __t)); \ +} \ + \ +template<class _Dom> \ +inline _Expr<_BinClos<_Name,_Constant,_Expr,typename _Dom::value_type,_Dom>, \ + bool> \ +operator##_Op (const typename _Dom::value_type& __t, \ + const _Expr<_Dom,typename _Dom::value_type>& __v) \ +{ \ + typedef typename _Dom::value_type _Arg; \ + typedef _BinClos<_Name,_Constant,_Expr,_Arg,_Dom> _Closure; \ + return _Expr<_Closure,bool> (_Closure (__t, __v ())); \ +} \ + \ +template<class _Dom> \ +inline _Expr<_BinClos<_Name,_Expr,_ValArray,_Dom,typename _Dom::value_type>, \ + bool> \ +operator##_Op (const _Expr<_Dom,typename _Dom::value_type>& __e, \ + const valarray<typename _Dom::value_type>& __v) \ +{ \ + typedef typename _Dom::value_type _Tp; \ + typedef _BinClos<_Name,_Expr,_ValArray,_Dom,_Tp> _Closure; \ + return _Expr<_Closure,bool> (_Closure (__e (), __v)); \ +} \ + \ +template<class _Dom> \ +inline _Expr<_BinClos<_Name,_ValArray,_Expr,typename _Dom::value_type,_Dom>, \ + bool> \ +operator##_Op (const valarray<typename _Dom::value_type>& __v, \ + const _Expr<_Dom,typename _Dom::value_type>& __e) \ +{ \ + typedef typename _Dom::value_type _Tp; \ + typedef _BinClos<_Name,_ValArray,_Expr,_Tp,_Dom> _Closure; \ + return _Expr<_Closure,bool> (_Closure (__v, __e ())); \ +} + + _DEFINE_EXPR_RELATIONAL_OPERATOR(&&, logical_and) + _DEFINE_EXPR_RELATIONAL_OPERATOR(||, logical_or) + _DEFINE_EXPR_RELATIONAL_OPERATOR(==, equal_to) + _DEFINE_EXPR_RELATIONAL_OPERATOR(!=, not_equal_to) + _DEFINE_EXPR_RELATIONAL_OPERATOR(<, less) + _DEFINE_EXPR_RELATIONAL_OPERATOR(>, greater) + _DEFINE_EXPR_RELATIONAL_OPERATOR(<=, less_equal) + _DEFINE_EXPR_RELATIONAL_OPERATOR(>=, greater_equal) + +#undef _DEFINE_EXPR_RELATIONAL_OPERATOR + + + +#define _DEFINE_EXPR_UNARY_FUNCTION(_Name) \ +template<class _Dom> \ +inline _Expr<_UnFunClos<_Expr,_Dom>,typename _Dom::value_type> \ +_Name(const _Expr<_Dom,typename _Dom::value_type>& __e) \ +{ \ + typedef typename _Dom::value_type _Tp; \ + typedef _UnFunClos<_Expr,_Dom> _Closure; \ + return _Expr<_Closure,_Tp> (_Closure (__e, (_Tp(*)(_Tp))(&_Name))); \ +} \ + \ +template<typename _Tp> \ +inline _Expr<_UnFunClos<_ValArray,_Tp>,_Tp> \ +_Name(const valarray<_Tp>& __v) \ +{ \ + typedef _UnFunClos<_ValArray,_Tp> _Closure; \ + return _Expr<_Closure,_Tp> (_Closure (__v, (_Tp(*)(_Tp))(&_Name))); \ +} + + + _DEFINE_EXPR_UNARY_FUNCTION(abs) + _DEFINE_EXPR_UNARY_FUNCTION(cos) + _DEFINE_EXPR_UNARY_FUNCTION(acos) + _DEFINE_EXPR_UNARY_FUNCTION(cosh) + _DEFINE_EXPR_UNARY_FUNCTION(sin) + _DEFINE_EXPR_UNARY_FUNCTION(asin) + _DEFINE_EXPR_UNARY_FUNCTION(sinh) + _DEFINE_EXPR_UNARY_FUNCTION(tan) + _DEFINE_EXPR_UNARY_FUNCTION(atan) + _DEFINE_EXPR_UNARY_FUNCTION(exp) + _DEFINE_EXPR_UNARY_FUNCTION(log) + _DEFINE_EXPR_UNARY_FUNCTION(log10) + _DEFINE_EXPR_UNARY_FUNCTION(sqrt) + +#undef _DEFINE_EXPR_UNARY_FUNCTION + + +#define _DEFINE_EXPR_BINARY_FUNCTION(_Name) \ +template<class _Dom1, class _Dom2> \ +inline _Expr<_BinFunClos<_Expr,_Expr,_Dom1,_Dom2>,typename _Dom1::value_type>\ +_Name (const _Expr<_Dom1,typename _Dom1::value_type>& __e1, \ + const _Expr<_Dom2,typename _Dom2::value_type>& __e2) \ +{ \ + typedef typename _Dom1::value_type _Tp; \ + typedef _BinFunClos<_Expr,_Expr,_Dom1,_Dom2> _Closure; \ + return _Expr<_Closure,_Tp> \ + (_Closure (__e1 (), __e2 (), (_Tp(*)(_Tp, _Tp))(&_Name))); \ +} \ + \ +template<class _Dom> \ +inline _Expr<_BinFunClos<_Expr,_ValArray,_Dom,typename _Dom::value_type>, \ + typename _Dom::value_type> \ +_Name (const _Expr<_Dom,typename _Dom::value_type>& __e, \ + const valarray<typename _Dom::value_type>& __v) \ +{ \ + typedef typename _Dom::value_type _Tp; \ + typedef _BinFunClos<_Expr,_ValArray,_Dom,_Tp> _Closure; \ + return _Expr<_Closure,_Tp> \ + (_Closure (__e (), __v, (_Tp(*)(_Tp, _Tp))(&_Name))); \ +} \ + \ +template<class _Dom> \ +inline _Expr<_BinFunClos<_ValArray,_Expr,typename _Dom::value_type,_Dom>, \ + typename _Dom::value_type> \ +_Name (const valarray<typename _Dom::valarray>& __v, \ + const _Expr<_Dom,typename _Dom::value_type>& __e) \ +{ \ + typedef typename _Dom::value_type _Tp; \ + typedef _BinFunClos<_ValArray,_Expr,_Tp,_Dom> _Closure; \ + return _Expr<_Closure,_Tp> \ + (_Closure (__v, __e (), (_Tp(*)(_Tp, _Tp))(&_Name))); \ +} \ + \ +template<class _Dom> \ +inline _Expr<_BinFunClos<_Expr,_Constant,_Dom,typename _Dom::value_type>, \ + typename _Dom::value_type> \ +_Name (const _Expr<_Dom, typename _Dom::value_type>& __e, \ + const typename _Dom::value_type& __t) \ +{ \ + typedef typename _Dom::value_type _Tp; \ + typedef _BinFunClos<_Expr,_Constant,_Dom,_Tp> _Closure; \ + return _Expr<_Closure,_Tp> \ + (_Closure (__e (), __t, (_Tp(*)(_Tp, _Tp))(&_Name))); \ +} \ + \ +template<class _Dom> \ +inline _Expr<_BinFunClos<_Constant,_Expr,typename _Dom::value_type,_Dom>, \ + typename _Dom::value_type> \ +_Name (const typename _Dom::value_type& __t, \ + const _Expr<_Dom,typename _Dom::value_type>& __e) \ +{ \ + typedef typename _Dom::value_type _Tp; \ + typedef _BinFunClos<_Constant,_Expr,_Tp,_Dom> _Closure; \ + return _Expr<_Closure,_Tp> \ + (_Closure (__t, __e (), (_Tp(*)(_Tp, _Tp))(&_Name))); \ +} \ + \ +template<typename _Tp> \ +inline _Expr<_BinFunClos<_ValArray,_ValArray,_Tp,_Tp>, _Tp> \ +_Name (const valarray<_Tp>& __v, const valarray<_Tp>& __w) \ +{ \ + typedef _BinFunClos<_ValArray,_ValArray,_Tp,_Tp> _Closure; \ + return _Expr<_Closure,_Tp> \ + (_Closure (__v, __w, (_Tp(*)(_Tp,_Tp))(&_Name))); \ +} \ + \ +template<typename _Tp> \ +inline _Expr<_BinFunClos<_ValArray,_Constant,_Tp,_Tp>,_Tp> \ +_Name (const valarray<_Tp>& __v, const _Tp& __t) \ +{ \ + typedef _BinFunClos<_ValArray,_Constant,_Tp,_Tp> _Closure; \ + return _Expr<_Closure,_Tp> \ + (_Closure (__v, __t, (_Tp(*)(_Tp,_Tp))(&_Name))); \ +} \ + \ +template<typename _Tp> \ +inline _Expr<_BinFunClos<_Constant,_ValArray,_Tp,_Tp>,_Tp> \ +_Name (const _Tp& __t, const valarray<_Tp>& __v) \ +{ \ + typedef _BinFunClos<_Constant,_ValArray,_Tp,_Tp> _Closure; \ + return _Expr<_Closure,_Tp> \ + (_Closure (__t, __v, (_Tp(*)(_Tp,_Tp))(&_Name))); \ +} + +_DEFINE_EXPR_BINARY_FUNCTION(atan2) +_DEFINE_EXPR_BINARY_FUNCTION(pow) + +#undef _DEFINE_EXPR_BINARY_FUNCTION + +#endif // _CPP_VALARRAY_META_H + +// Local Variables: +// mode:c++ +// End: diff --git a/contrib/libstdc++/stdexcept b/contrib/libstdc++/stdexcept index c0ac87f..69e9627 100644 --- a/contrib/libstdc++/stdexcept +++ b/contrib/libstdc++/stdexcept @@ -37,9 +37,7 @@ extern "C++" { -#ifdef __HONOR_STD namespace std { -#endif class logic_error : public exception { string _what; @@ -92,9 +90,7 @@ public: underflow_error (const string& what_arg): runtime_error (what_arg) { } }; -#ifdef __HONOR_STD } // namespace std -#endif } // extern "C++" diff --git a/contrib/libstdc++/stdexcepti.cc b/contrib/libstdc++/stdexcepti.cc index 3b03acd..9c02c71 100644 --- a/contrib/libstdc++/stdexcepti.cc +++ b/contrib/libstdc++/stdexcepti.cc @@ -12,10 +12,10 @@ void __out_of_range (const char *s) { - throw out_of_range (s); + throw std::out_of_range (s); } void __length_error (const char *s) { - throw length_error (s); + throw std::length_error (s); } diff --git a/contrib/libstdc++/stl/ChangeLog b/contrib/libstdc++/stl/ChangeLog index 4655380..22d31b0 100644 --- a/contrib/libstdc++/stl/ChangeLog +++ b/contrib/libstdc++/stl/ChangeLog @@ -1,6 +1,103 @@ -Sun Mar 14 02:38:07 PST 1999 Jeff Law (law@cygnus.com) +Mon Aug 16 01:29:24 PDT 1999 Jeff Law (law@cygnus.com) - * egcs-1.1.2 Released. + * gcc-2.95.1 Released. + +Sun Aug 8 21:06:16 1999 Alexandre Oliva <oliva@dcc.unicamp.br> + + * pthread_alloc: Solaris' ctype.h defines _U to 01; use _Up as + template parameter instead. + +Wed Jul 28 21:39:31 PDT 1999 Jeff Law (law@cygnus.com) + + * gcc-2.95 Released. + +Sun Jul 25 23:40:51 PDT 1999 Jeff Law (law@cygnus.com) + + * gcc-2.95 Released. + +1999-07-11 Martin v. Löwis (loewis@informatik.hu-berlin.de) + + * stl_function.h (bind1st, bind2nd): Rename __opr to __oper, + as __opr is used internally by egcs. + * stl_numeric.h (__power, power): Likewise. + +1999-06-18 Martin von Löwis <loewis@informatik.hu-berlin.de> + + * stl_queue.h: Rename _M_c to c, and _M_comp to comp. + +1999-06-17 Alexandre Oliva <oliva@dcc.unicamp.br> + + * stl_algo.h (transform): Rename __opr to __oper, as __opr is used + internally by egcs. + Reported by Harri Porten <porten@tu-harburg.de> + +1999-05-17 Mark Kettenis <kettenis@gnu.org> + + * stl_config.h: Only define __STL_PTHREADS with GLIBC >= 2 for + Linux. + +Mon May 17 03:33:47 1999 Mumit Khan <khan@xraylith.wisc.edu> + + * stl_config.h (__CYGWIN__): Cygwin newlib RTL lacks drand48. + +1999-05-07 Ulrich Drepper <drepper@cygnus.com> + + * stl_alloc.h: Make it possible to compile with __USE_MALLOC. + +Tue Apr 13 00:32:57 1999 Mumit Khan <khan@xraylith.wisc.edu> + + * stl_config.h (__MINGW32__): Mingw32 RTL lacks drand48. + +Sun Apr 11 23:48:30 1999 Jeffrey A Law (law@cygnus.com) + + * bitset: Re-install Alexandre's lost patch from 1998-11-27. + +1999-01-20 Ulrich Drepper <drepper@cygnus.com> + + * stl_construct.h (__destroy_aux): Use != instead of < for + ForwardIterator comparison. + Patch by jmaurer@menuett.rhein-main.de (Jens Maurer). + +1999-01-20 Mark Mitchell <mark@markmitchell.com> + + * stl_config.h (__STL_USE_NAMESPACES): Define. + +1998-11-27 Alexandre Oliva <oliva@dcc.unicamp.br> + + * bitset: Explicitly convert basic_string<...>::npos to size_t in + default argument to constructor, to avoid parse error at `>'. + (__STL_EXPLICIT_FUNCTION_TMPL_ARGS): Replace #if with #ifdef. + +1998-11-01 Mark Mitchell <mark@markmitchell.com> + + * stl_alloc.h (default_alloc_template::_S_free_list): Don't + qualify _NFREELISTS. + +1998-10-11 Mark Mitchell <mark@markmitchell.com> + + * stl_config.h (__SGI_STL_USE_AUTO_PTR_CONVERSIONS): Define. + * memory (auto_ptr::operator auto_ptr_ref<_Tp1>): Fix typo. + (auto_ptr::operator auto_ptr<_Tp1>): Add missing + semicolon. + +1998-09-03 Jason Merrill <jason@yorick.cygnus.com> + + * stl_config.h: Define __STL_HAS_WCHAR_T, + __STL_MEMBER_TEMPLATE_CLASSES, __STL_HAS_NAMESPACES, + __STL_NO_NAMESPACES and __STL_LONG_LONG. + +1998-09-02 Jason Merrill <jason@yorick.cygnus.com> + + * algorithm alloc.h defalloc.h hash_map.h hash_set.h iterator + memory pthread_alloc pthread_alloc.h rope ropeimpl.h stl_algo.h + stl_algobase.h stl_alloc.h stl_bvector.h stl_config.h + stl_construct.h stl_deque.h stl_function.h stl_hash_fun.h + stl_hash_map.h stl_hash_set.h stl_hashtable.h stl_heap.h + stl_iterator.h stl_list.h stl_map.h stl_multimap.h stl_multiset.h + stl_numeric.h stl_pair.h stl_queue.h stl_raw_storage_iter.h + stl_relops.h stl_rope.h stl_set.h stl_slist.h stl_stack.h + stl_tempbuf.h stl_tree.h stl_uninitialized.h stl_vector.h + tempbuf.h type_traits.h: Update to SGI STL 3.11. Fri Jul 10 15:20:09 1998 Klaus-Georg Adams <Klaus-Georg.Adams@chemie.uni-karlsruhe.de> @@ -93,7 +190,7 @@ 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. @@ -131,7 +228,7 @@ Mon Sep 30 17:56:43 1996 Jason Merrill <jason@yorick.cygnus.com> Fri Sep 27 19:03:06 1996 Jason Merrill <jason@yorick.cygnus.com> - * alloc.h (__default_alloc_template): lock is a friend. + * alloc.h (__default_alloc_template): lock is a friend. Thu Sep 19 20:10:37 1996 Jason Merrill <jason@yorick.cygnus.com> @@ -269,5 +366,3 @@ Fri Dec 30 16:29:39 1994 Mike Stump <mrs@cygnus.com> 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 index 81bc7cf..c319c08 100644 --- a/contrib/libstdc++/stl/README +++ b/contrib/libstdc++/stl/README @@ -1,16 +1,13 @@ This directory contains an SGI release of the C++ Standard Template -Library, slightly modified to work with g++ (version 2.8.0 or newer). +Library, slightly modified to work with g++. 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. +For examples of 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/algorithm b/contrib/libstdc++/stl/algorithm index 515e9bd..1ba584f 100644 --- a/contrib/libstdc++/stl/algorithm +++ b/contrib/libstdc++/stl/algorithm @@ -29,6 +29,7 @@ #include <stl_algobase.h> #include <stl_construct.h> +#include <stl_uninitialized.h> #include <stl_tempbuf.h> #include <stl_algo.h> diff --git a/contrib/libstdc++/stl/alloc.h b/contrib/libstdc++/stl/alloc.h index 7cc9610..f99a862 100644 --- a/contrib/libstdc++/stl/alloc.h +++ b/contrib/libstdc++/stl/alloc.h @@ -33,7 +33,9 @@ using __STD::single_client_alloc; #ifdef __STL_STATIC_TEMPLATE_MEMBER_BUG using __STD::__malloc_alloc_oom_handler; #endif /* __STL_STATIC_TEMPLATE_MEMBER_BUG */ - +#ifdef __STL_USE_STD_ALLOCATORS +using __STD::allocator; +#endif /* __STL_USE_STD_ALLOCATORS */ #endif /* __STL_USE_NAMESPACES */ diff --git a/contrib/libstdc++/stl/bitset b/contrib/libstdc++/stl/bitset new file mode 100644 index 0000000..e26845e --- /dev/null +++ b/contrib/libstdc++/stl/bitset @@ -0,0 +1,1063 @@ +/* + * Copyright (c) 1998 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef __SGI_STL_BITSET +#define __SGI_STL_BITSET + +// This implementation of bitset<> has a second template parameter, +// _WordT, which defaults to unsigned long. *YOU SHOULD NOT USE +// THIS FEATURE*. It is experimental, and it may be removed in +// future releases. + +// A bitset of size N, using words of type _WordT, will have +// N % (sizeof(_WordT) * CHAR_BIT) unused bits. (They are the high- +// order bits in the highest word.) It is a class invariant +// of class bitset<> that those unused bits are always zero. + +// Most of the actual code isn't contained in bitset<> itself, but in the +// base class _Base_bitset. The base class works with whole words, not with +// individual bits. This allows us to specialize _Base_bitset for the +// important special case where the bitset is only a single word. + +// The C++ standard does not define the precise semantics of operator[]. +// In this implementation the const version of operator[] is equivalent +// to test(), except that it does no range checking. The non-const version +// returns a reference to a bit, again without doing any range checking. + + +#include <stddef.h> // for size_t +#include <string> +#include <stdexcept> // for invalid_argument, out_of_range, overflow_error +#include <iostream.h> // for istream, ostream + +#define __BITS_PER_WORDT(__wt) (CHAR_BIT*sizeof(__wt)) +#define __BITSET_WORDS(__n,__wt) \ + ((__n) < 1 ? 1 : ((__n) + __BITS_PER_WORDT(__wt) - 1)/__BITS_PER_WORDT(__wt)) + +__STL_BEGIN_NAMESPACE + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1209 +#endif + +// structure to aid in counting bits +template<bool __dummy> +struct _Bit_count { + static unsigned char _S_bit_count[256]; +}; + +// Mapping from 8 bit unsigned integers to the index of the first one +// bit: +template<bool __dummy> +struct _First_one { + static unsigned char _S_first_one[256]; +}; + +// +// Base class: general case. +// + +template<size_t _Nw, class _WordT> +struct _Base_bitset { + _WordT _M_w[_Nw]; // 0 is the least significant word. + + _Base_bitset( void ) { _M_do_reset(); } + + _Base_bitset(unsigned long __val); + + static size_t _S_whichword( size_t __pos ) { + return __pos / __BITS_PER_WORDT(_WordT); + } + static size_t _S_whichbyte( size_t __pos ) { + return (__pos % __BITS_PER_WORDT(_WordT)) / CHAR_BIT; + } + static size_t _S_whichbit( size_t __pos ) { + return __pos % __BITS_PER_WORDT(_WordT); + } + static _WordT _S_maskbit( size_t __pos ) { + return (static_cast<_WordT>(1)) << _S_whichbit(__pos); + } + + _WordT& _M_getword(size_t __pos) { return _M_w[_S_whichword(__pos)]; } + _WordT _M_getword(size_t __pos) const { return _M_w[_S_whichword(__pos)]; } + + _WordT& _M_hiword() { return _M_w[_Nw - 1]; } + _WordT _M_hiword() const { return _M_w[_Nw - 1]; } + + void _M_do_and(const _Base_bitset<_Nw,_WordT>& __x) { + for ( size_t __i = 0; __i < _Nw; __i++ ) { + _M_w[__i] &= __x._M_w[__i]; + } + } + + void _M_do_or(const _Base_bitset<_Nw,_WordT>& __x) { + for ( size_t __i = 0; __i < _Nw; __i++ ) { + _M_w[__i] |= __x._M_w[__i]; + } + } + + void _M_do_xor(const _Base_bitset<_Nw,_WordT>& __x) { + for ( size_t __i = 0; __i < _Nw; __i++ ) { + _M_w[__i] ^= __x._M_w[__i]; + } + } + + void _M_do_left_shift(size_t __shift); + + void _M_do_right_shift(size_t __shift); + + void _M_do_flip() { + for ( size_t __i = 0; __i < _Nw; __i++ ) { + _M_w[__i] = ~_M_w[__i]; + } + } + + void _M_do_set() { + for ( size_t __i = 0; __i < _Nw; __i++ ) { + _M_w[__i] = ~static_cast<_WordT>(0); + } + } + + void _M_do_reset() { + for ( size_t __i = 0; __i < _Nw; __i++ ) { + _M_w[__i] = 0; + } + } + + bool _M_is_equal(const _Base_bitset<_Nw,_WordT>& __x) const { + for (size_t __i = 0; __i < _Nw; ++__i) { + if (_M_w[__i] != __x._M_w[__i]) + return false; + } + return true; + } + + bool _M_is_any() const { + for ( size_t __i = 0; __i < __BITSET_WORDS(_Nw,_WordT); __i++ ) { + if ( _M_w[__i] != static_cast<_WordT>(0) ) + return true; + } + return false; + } + + size_t _M_do_count() const { + size_t __result = 0; + const unsigned char* __byte_ptr = (const unsigned char*)_M_w; + const unsigned char* __end_ptr = (const unsigned char*)(_M_w+_Nw); + + while ( __byte_ptr < __end_ptr ) { + __result += _Bit_count<true>::_S_bit_count[*__byte_ptr]; + __byte_ptr++; + } + return __result; + } + + unsigned long _M_do_to_ulong() const; + + // find first "on" bit + size_t _M_do_find_first(size_t __not_found) const; + + // find the next "on" bit that follows "prev" + size_t _M_do_find_next(size_t __prev, size_t __not_found) const; +}; + +// +// Definitions of non-inline functions from _Base_bitset. +// + +template<size_t _Nw, class _WordT> +_Base_bitset<_Nw, _WordT>::_Base_bitset(unsigned long __val) +{ + _M_do_reset(); + const size_t __n = min(sizeof(unsigned long)*CHAR_BIT, + __BITS_PER_WORDT(_WordT)*_Nw); + for(size_t __i = 0; __i < __n; ++__i, __val >>= 1) + if ( __val & 0x1 ) + _M_getword(__i) |= _S_maskbit(__i); +} + +template<size_t _Nw, class _WordT> +void _Base_bitset<_Nw, _WordT>::_M_do_left_shift(size_t __shift) +{ + if (__shift != 0) { + const size_t __wshift = __shift / __BITS_PER_WORDT(_WordT); + const size_t __offset = __shift % __BITS_PER_WORDT(_WordT); + const size_t __sub_offset = __BITS_PER_WORDT(_WordT) - __offset; + size_t __n = _Nw - 1; + for ( ; __n > __wshift; --__n) + _M_w[__n] = (_M_w[__n - __wshift] << __offset) | + (_M_w[__n - __wshift - 1] >> __sub_offset); + if (__n == __wshift) + _M_w[__n] = _M_w[0] << __offset; + for (size_t __n1 = 0; __n1 < __n; ++__n1) + _M_w[__n1] = static_cast<_WordT>(0); + } +} + +template<size_t _Nw, class _WordT> +void _Base_bitset<_Nw, _WordT>::_M_do_right_shift(size_t __shift) +{ + if (__shift != 0) { + const size_t __wshift = __shift / __BITS_PER_WORDT(_WordT); + const size_t __offset = __shift % __BITS_PER_WORDT(_WordT); + const size_t __sub_offset = __BITS_PER_WORDT(_WordT) - __offset; + const size_t __limit = _Nw - __wshift - 1; + size_t __n = 0; + for ( ; __n < __limit; ++__n) + _M_w[__n] = (_M_w[__n + __wshift] >> __offset) | + (_M_w[__n + __wshift + 1] << __sub_offset); + _M_w[__limit] = _M_w[_Nw-1] >> __offset; + for (size_t __n1 = __limit + 1; __n1 < _Nw; ++__n1) + _M_w[__n1] = static_cast<_WordT>(0); + } +} + +template<size_t _Nw, class _WordT> +unsigned long _Base_bitset<_Nw, _WordT>::_M_do_to_ulong() const +{ + const overflow_error __overflow("bitset"); + + if (sizeof(_WordT) >= sizeof(unsigned long)) { + for (size_t __i = 1; __i < _Nw; ++__i) + if (_M_w[__i]) + __STL_THROW(__overflow); + + const _WordT __mask = static_cast<_WordT>(static_cast<unsigned long>(-1)); + if (_M_w[0] & ~__mask) + __STL_THROW(__overflow); + + return static_cast<unsigned long>(_M_w[0] & __mask); + } + else { // sizeof(_WordT) < sizeof(unsigned long). + const size_t __nwords = + (sizeof(unsigned long) + sizeof(_WordT) - 1) / sizeof(_WordT); + + size_t __min_nwords = __nwords; + if (_Nw > __nwords) { + for (size_t __i = __nwords; __i < _Nw; ++__i) + if (_M_w[__i]) + __STL_THROW(__overflow); + } + else + __min_nwords = _Nw; + + // If unsigned long is 8 bytes and _WordT is 6 bytes, then an unsigned + // long consists of all of one word plus 2 bytes from another word. + const size_t __part = sizeof(unsigned long) % sizeof(_WordT); + + if (__part != 0 && __nwords <= _Nw && + (_M_w[__min_nwords - 1] >> ((sizeof(_WordT) - __part) * CHAR_BIT)) != 0) + __STL_THROW(__overflow); + + unsigned long __result = 0; + for (size_t __i = 0; __i < __min_nwords; ++__i) { + __result |= static_cast<unsigned long>( + _M_w[__i]) << (__i * sizeof(_WordT) * CHAR_BIT); + } + return __result; + } +} // End _M_do_to_ulong + +template<size_t _Nw, class _WordT> +size_t _Base_bitset<_Nw, _WordT>::_M_do_find_first(size_t __not_found) const +{ + for ( size_t __i = 0; __i < _Nw; __i++ ) { + _WordT __thisword = _M_w[__i]; + if ( __thisword != static_cast<_WordT>(0) ) { + // find byte within word + for ( size_t __j = 0; __j < sizeof(_WordT); __j++ ) { + unsigned char __this_byte + = static_cast<unsigned char>(__thisword & (~(unsigned char)0)); + if ( __this_byte ) + return __i*__BITS_PER_WORDT(_WordT) + __j*CHAR_BIT + + _First_one<true>::_S_first_one[__this_byte]; + + __thisword >>= CHAR_BIT; + } + } + } + // not found, so return an indication of failure. + return __not_found; +} + +template<size_t _Nw, class _WordT> +size_t +_Base_bitset<_Nw, _WordT>::_M_do_find_next(size_t __prev, + size_t __not_found) const +{ + // make bound inclusive + ++__prev; + + // check out of bounds + if ( __prev >= _Nw * __BITS_PER_WORDT(_WordT) ) + return __not_found; + + // search first word + size_t __i = _S_whichword(__prev); + _WordT __thisword = _M_w[__i]; + + // mask off bits below bound + __thisword &= (~static_cast<_WordT>(0)) << _S_whichbit(__prev); + + if ( __thisword != static_cast<_WordT>(0) ) { + // find byte within word + // get first byte into place + __thisword >>= _S_whichbyte(__prev) * CHAR_BIT; + for ( size_t __j = _S_whichbyte(__prev); __j < sizeof(_WordT); __j++ ) { + unsigned char __this_byte + = static_cast<unsigned char>(__thisword & (~(unsigned char)0)); + if ( __this_byte ) + return __i*__BITS_PER_WORDT(_WordT) + __j*CHAR_BIT + + _First_one<true>::_S_first_one[__this_byte]; + + __thisword >>= CHAR_BIT; + } + } + + // check subsequent words + __i++; + for ( ; __i < _Nw; __i++ ) { + _WordT __thisword = _M_w[__i]; + if ( __thisword != static_cast<_WordT>(0) ) { + // find byte within word + for ( size_t __j = 0; __j < sizeof(_WordT); __j++ ) { + unsigned char __this_byte + = static_cast<unsigned char>(__thisword & (~(unsigned char)0)); + if ( __this_byte ) + return __i*__BITS_PER_WORDT(_WordT) + __j*CHAR_BIT + + _First_one<true>::_S_first_one[__this_byte]; + + __thisword >>= CHAR_BIT; + } + } + } + + // not found, so return an indication of failure. + return __not_found; +} // end _M_do_find_next + + +// ------------------------------------------------------------ + +// +// Base class: specialization for a single word. +// + +template<class _WordT> +struct _Base_bitset<1, _WordT> { + _WordT _M_w; + + _Base_bitset( void ) { _M_do_reset(); } + + _Base_bitset(unsigned long __val); + + static size_t _S_whichword( size_t __pos ) { + return __pos / __BITS_PER_WORDT(_WordT); + } + static size_t _S_whichbyte( size_t __pos ) { + return (__pos % __BITS_PER_WORDT(_WordT)) / CHAR_BIT; + } + static size_t _S_whichbit( size_t __pos ) { + return __pos % __BITS_PER_WORDT(_WordT); + } + static _WordT _S_maskbit( size_t __pos ) { + return (static_cast<_WordT>(1)) << _S_whichbit(__pos); + } + + _WordT& _M_getword(size_t) { return _M_w; } + _WordT _M_getword(size_t) const { return _M_w; } + + _WordT& _M_hiword() { return _M_w; } + _WordT _M_hiword() const { return _M_w; } + + void _M_do_and(const _Base_bitset<1,_WordT>& __x) { _M_w &= __x._M_w; } + void _M_do_or(const _Base_bitset<1,_WordT>& __x) { _M_w |= __x._M_w; } + void _M_do_xor(const _Base_bitset<1,_WordT>& __x) { _M_w ^= __x._M_w; } + void _M_do_left_shift(size_t __shift) { _M_w <<= __shift; } + void _M_do_right_shift(size_t __shift) { _M_w >>= __shift; } + void _M_do_flip() { _M_w = ~_M_w; } + void _M_do_set() { _M_w = ~static_cast<_WordT>(0); } + void _M_do_reset() { _M_w = 0; } + + bool _M_is_equal(const _Base_bitset<1,_WordT>& __x) const { + return _M_w == __x._M_w; + } + bool _M_is_any() const { + return _M_w != 0; + } + + size_t _M_do_count() const { + size_t __result = 0; + const unsigned char* __byte_ptr = (const unsigned char*)&_M_w; + const unsigned char* __end_ptr = ((const unsigned char*)&_M_w)+sizeof(_M_w); + while ( __byte_ptr < __end_ptr ) { + __result += _Bit_count<true>::_S_bit_count[*__byte_ptr]; + __byte_ptr++; + } + return __result; + } + + unsigned long _M_do_to_ulong() const { + if (sizeof(_WordT) <= sizeof(unsigned long)) + return static_cast<unsigned long>(_M_w); + else { + const _WordT __mask = static_cast<_WordT>(static_cast<unsigned long>(-1)); + if (_M_w & ~__mask) + __STL_THROW(overflow_error("bitset")); + return static_cast<unsigned long>(_M_w); + } + } + + size_t _M_do_find_first(size_t __not_found) const; + + // find the next "on" bit that follows "prev" + size_t _M_do_find_next(size_t __prev, size_t __not_found) const; + +}; + +// +// Definitions of non-inline functions from the single-word version of +// _Base_bitset. +// + +template <class _WordT> +_Base_bitset<1, _WordT>::_Base_bitset(unsigned long __val) +{ + _M_do_reset(); + const size_t __n = min(sizeof(unsigned long)*CHAR_BIT, + __BITS_PER_WORDT(_WordT)*_Nw); + for(size_t __i = 0; __i < __n; ++__i, __val >>= 1) + if ( __val & 0x1 ) + _M_w |= _S_maskbit(__i); +} + +template <class _WordT> +size_t _Base_bitset<1, _WordT>::_M_do_find_first(size_t __not_found) const +{ + _WordT __thisword = _M_w; + + if ( __thisword != static_cast<_WordT>(0) ) { + // find byte within word + for ( size_t __j = 0; __j < sizeof(_WordT); __j++ ) { + unsigned char __this_byte + = static_cast<unsigned char>(__thisword & (~(unsigned char)0)); + if ( __this_byte ) + return __j*CHAR_BIT + _First_one<true>::_S_first_one[__this_byte]; + + __thisword >>= CHAR_BIT; + } + } + // not found, so return a value that indicates failure. + return __not_found; +} + +template <class _WordT> +size_t +_Base_bitset<1, _WordT>::_M_do_find_next(size_t __prev, + size_t __not_found ) const +{ + // make bound inclusive + ++__prev; + + // check out of bounds + if ( __prev >= __BITS_PER_WORDT(_WordT) ) + return __not_found; + + // search first (and only) word + _WordT __thisword = _M_w; + + // mask off bits below bound + __thisword &= (~static_cast<_WordT>(0)) << _S_whichbit(__prev); + + if ( __thisword != static_cast<_WordT>(0) ) { + // find byte within word + // get first byte into place + __thisword >>= _S_whichbyte(__prev) * CHAR_BIT; + for ( size_t __j = _S_whichbyte(__prev); __j < sizeof(_WordT); __j++ ) { + unsigned char __this_byte + = static_cast<unsigned char>(__thisword & (~(unsigned char)0)); + if ( __this_byte ) + return __j*CHAR_BIT + _First_one<true>::_S_first_one[__this_byte]; + + __thisword >>= CHAR_BIT; + } + } + + // not found, so return a value that indicates failure. + return __not_found; +} // end _M_do_find_next + +// +// One last specialization: _M_do_to_ulong() and the constructor from +// unsigned long are very simple if the bitset consists of a single +// word of type unsigned long. +// + +template<> +inline unsigned long +_Base_bitset<1, unsigned long>::_M_do_to_ulong() const { return _M_w; } + +template<> +inline _Base_bitset<1, unsigned long>::_Base_bitset(unsigned long __val) { + _M_w = __val; +} + + +// ------------------------------------------------------------ +// Helper class to zero out the unused high-order bits in the highest word. + +template <class _WordT, size_t _Extrabits> struct _Sanitize { + static void _M_do_sanitize(_WordT& __val) + { __val &= ~((~static_cast<_WordT>(0)) << _Extrabits); } +}; + +template <class _WordT> struct _Sanitize<_WordT, 0> { + static void _M_do_sanitize(_WordT) {} +}; + +// ------------------------------------------------------------ +// Class bitset. +// _Nb may be any nonzero number of type size_t. +// Type _WordT may be any unsigned integral type. + +template<size_t _Nb, class _WordT = unsigned long> +class bitset : private _Base_bitset<__BITSET_WORDS(_Nb,_WordT), _WordT> +{ +private: + typedef _Base_bitset<__BITSET_WORDS(_Nb,_WordT), _WordT> _Base; + + // Import base's protected interface. Necessary because of new template + // name resolution rules. + using _Base::_S_whichword; + using _Base::_S_whichbyte; + using _Base::_S_whichbit; + using _Base::_S_maskbit; + using _Base::_M_getword; + using _Base::_M_hiword; + using _Base::_M_do_and; + using _Base::_M_do_or; + using _Base::_M_do_xor; + using _Base::_M_do_left_shift; + using _Base::_M_do_right_shift; + using _Base::_M_do_flip; + using _Base::_M_do_set; + using _Base::_M_do_reset; + using _Base::_M_is_equal; + using _Base::_M_is_any; + using _Base::_M_do_count; + using _Base::_M_do_to_ulong; + using _Base::_M_do_find_first; + using _Base::_M_do_find_next; + +private: + void _M_do_sanitize() { + _Sanitize<_WordT,_Nb%__BITS_PER_WORDT(_WordT) > + ::_M_do_sanitize(_M_hiword()); + } + +public: + + // bit reference: + class reference { + friend class bitset; + + _WordT *_M_wp; + size_t _M_bpos; + + // left undefined + reference(); + + reference( bitset& __b, size_t __pos ) { + _M_wp = &__b._M_getword(__pos); + _M_bpos = _S_whichbit(__pos); + } + + public: + ~reference() {} + + // for b[i] = __x; + reference& operator=(bool __x) { + if ( __x ) + *_M_wp |= _S_maskbit(_M_bpos); + else + *_M_wp &= ~_S_maskbit(_M_bpos); + + return *this; + } + + // for b[i] = b[__j]; + reference& operator=(const reference& __j) { + if ( (*(__j._M_wp) & _S_maskbit(__j._M_bpos)) ) + *_M_wp |= _S_maskbit(_M_bpos); + else + *_M_wp &= ~_S_maskbit(_M_bpos); + + return *this; + } + + // flips the bit + bool operator~() const { return (*(_M_wp) & _S_maskbit(_M_bpos)) == 0; } + + // for __x = b[i]; + operator bool() const { return (*(_M_wp) & _S_maskbit(_M_bpos)) != 0; } + + // for b[i].flip(); + reference& flip() { + *_M_wp ^= _S_maskbit(_M_bpos); + return *this; + } + }; + + // 23.3.5.1 constructors: + bitset() {} + bitset(unsigned long __val) : + _Base_bitset<__BITSET_WORDS(_Nb,_WordT), _WordT>(__val) {} + + template<class _CharT, class _Traits, class _Alloc> + explicit bitset(const basic_string<_CharT,_Traits,_Alloc>& __s, + size_t __pos = 0, + size_t __n = size_t(basic_string<_CharT,_Traits,_Alloc>::npos)) + : _Base() + { + if (__pos > __s.size()) + __STL_THROW(out_of_range("bitset")); + _M_copy_from_string(__s, __pos, __n); + } + + // 23.3.5.2 bitset operations: + bitset<_Nb,_WordT>& operator&=(const bitset<_Nb,_WordT>& __rhs) { + _M_do_and(__rhs); + return *this; + } + + bitset<_Nb,_WordT>& operator|=(const bitset<_Nb,_WordT>& __rhs) { + _M_do_or(__rhs); + return *this; + } + + bitset<_Nb,_WordT>& operator^=(const bitset<_Nb,_WordT>& __rhs) { + _M_do_xor(__rhs); + return *this; + } + + bitset<_Nb,_WordT>& operator<<=(size_t __pos) { + _M_do_left_shift(__pos); + _M_do_sanitize(); + return *this; + } + + bitset<_Nb,_WordT>& operator>>=(size_t __pos) { + _M_do_right_shift(__pos); + _M_do_sanitize(); + return *this; + } + + // + // Extension: + // Versions of single-bit set, reset, flip, test with no range checking. + // + + bitset<_Nb,_WordT>& _Unchecked_set(size_t __pos) { + _M_getword(__pos) |= _S_maskbit(__pos); + return *this; + } + + bitset<_Nb,_WordT>& _Unchecked_set(size_t __pos, int __val) { + if (__val) + _M_getword(__pos) |= _S_maskbit(__pos); + else + _M_getword(__pos) &= ~_S_maskbit(__pos); + + return *this; + } + + bitset<_Nb,_WordT>& _Unchecked_reset(size_t __pos) { + _M_getword(__pos) &= ~_S_maskbit(__pos); + return *this; + } + + bitset<_Nb,_WordT>& _Unchecked_flip(size_t __pos) { + _M_getword(__pos) ^= _S_maskbit(__pos); + return *this; + } + + bool _Unchecked_test(size_t __pos) const { + return (_M_getword(__pos) & _S_maskbit(__pos)) != static_cast<_WordT>(0); + } + + // Set, reset, and flip. + + bitset<_Nb,_WordT>& set() { + _M_do_set(); + _M_do_sanitize(); + return *this; + } + + bitset<_Nb,_WordT>& set(size_t __pos) { + if (__pos >= _Nb) + __STL_THROW(out_of_range("bitset")); + + return _Unchecked_set(__pos); + } + + bitset<_Nb,_WordT>& set(size_t __pos, int __val) { + if (__pos >= _Nb) + __STL_THROW(out_of_range("bitset")); + + return _Unchecked_set(__pos, __val); + } + + bitset<_Nb,_WordT>& reset() { + _M_do_reset(); + return *this; + } + + bitset<_Nb,_WordT>& reset(size_t __pos) { + if (__pos >= _Nb) + __STL_THROW(out_of_range("bitset")); + + return _Unchecked_reset(__pos); + } + + bitset<_Nb,_WordT>& flip() { + _M_do_flip(); + _M_do_sanitize(); + return *this; + } + + bitset<_Nb,_WordT>& flip(size_t __pos) { + if (__pos >= _Nb) + __STL_THROW(out_of_range("bitset")); + + return _Unchecked_flip(__pos); + } + + bitset<_Nb,_WordT> operator~() const { + return bitset<_Nb,_WordT>(*this).flip(); + } + + // element access: + //for b[i]; + reference operator[](size_t __pos) { return reference(*this,__pos); } + bool operator[](size_t __pos) const { return _Unchecked_test(__pos); } + + unsigned long to_ulong() const { return _M_do_to_ulong(); } + +#ifdef __STL_EXPLICIT_FUNCTION_TMPL_ARGS + template <class _CharT, class _Traits, class _Alloc> + basic_string<_CharT, _Traits, _Alloc> to_string() const { + basic_string<_CharT, _Traits, _Alloc> __result; + _M_copy_to_string(__result); + return __result; + } +#endif /* __STL_EXPLICIT_FUNCTION_TMPL_ARGS */ + + // Helper functions for string operations. + template<class _CharT, class _Traits, class _Alloc> + void _M_copy_from_string(const basic_string<_CharT,_Traits,_Alloc>& __s, + size_t, + size_t); + + // Helper functions for string operations. + template<class _CharT, class _Traits, class _Alloc> + void _M_copy_to_string(basic_string<_CharT,_Traits,_Alloc>&) const; + + size_t count() const { return _M_do_count(); } + + size_t size() const { return _Nb; } + + bool operator==(const bitset<_Nb,_WordT>& __rhs) const { + return _M_is_equal(__rhs); + } + bool operator!=(const bitset<_Nb,_WordT>& __rhs) const { + return !_M_is_equal(__rhs); + } + + bool test(size_t __pos) const { + if (__pos > _Nb) + __STL_THROW(out_of_range("bitset")); + + return _Unchecked_test(__pos); + } + + bool any() const { return _M_is_any(); } + bool none() const { return !_M_is_any(); } + + bitset<_Nb,_WordT> operator<<(size_t __pos) const + { return bitset<_Nb,_WordT>(*this) <<= __pos; } + bitset<_Nb,_WordT> operator>>(size_t __pos) const + { return bitset<_Nb,_WordT>(*this) >>= __pos; } + + // + // EXTENSIONS: bit-find operations. These operations are + // experimental, and are subject to change or removal in future + // versions. + // + + // find the index of the first "on" bit + size_t _Find_first() const + { return _M_do_find_first(_Nb); } + + // find the index of the next "on" bit after prev + size_t _Find_next( size_t __prev ) const + { return _M_do_find_next(__prev, _Nb); } + +}; + +// +// Definitions of non-inline member functions. +// + +template <size_t _Nb, class _WordT> +template<class _CharT, class _Traits, class _Alloc> +void bitset<_Nb, _WordT> + ::_M_copy_from_string(const basic_string<_CharT,_Traits,_Alloc>& __s, + size_t __pos, + size_t __n) +{ + reset(); + const size_t __nbits = min(_Nb, min(__n, __s.size() - __pos)); + for (size_t __i = 0; __i < __nbits; ++__i) { + switch(__s[__pos + __nbits - __i - 1]) { + case '0': + break; + case '1': + set(__i); + break; + default: + __STL_THROW(invalid_argument("bitset")); + } + } +} + +template <size_t _Nb, class _WordT> +template <class _CharT, class _Traits, class _Alloc> +void bitset<_Nb, _WordT> + ::_M_copy_to_string(basic_string<_CharT, _Traits, _Alloc>& __s) const +{ + __s.assign(_Nb, '0'); + + for (size_t __i = 0; __i < _Nb; ++__i) + if (_Unchecked_test(__i)) + __s[_Nb - 1 - __i] = '1'; +} + +// ------------------------------------------------------------ + +// +// 23.3.5.3 bitset operations: +// + +template <size_t _Nb, class _WordT> +inline bitset<_Nb,_WordT> operator&(const bitset<_Nb,_WordT>& __x, + const bitset<_Nb,_WordT>& __y) { + bitset<_Nb,_WordT> __result(__x); + __result &= __y; + return __result; +} + + +template <size_t _Nb, class _WordT> +inline bitset<_Nb,_WordT> operator|(const bitset<_Nb,_WordT>& __x, + const bitset<_Nb,_WordT>& __y) { + bitset<_Nb,_WordT> __result(__x); + __result |= __y; + return __result; +} + +template <size_t _Nb, class _WordT> +inline bitset<_Nb,_WordT> operator^(const bitset<_Nb,_WordT>& __x, + const bitset<_Nb,_WordT>& __y) { + bitset<_Nb,_WordT> __result(__x); + __result ^= __y; + return __result; +} + +// NOTE: these must be rewritten once we have templatized iostreams. + +template <size_t _Nb, class _WordT> +istream& +operator>>(istream& __is, bitset<_Nb,_WordT>& __x) { + string __tmp; + __tmp.reserve(_Nb); + + // In new templatized iostreams, use istream::sentry + if (__is.flags() & ios::skipws) { + char __c; + do + __is.get(__c); + while (__is && isspace(__c)); + if (__is) + __is.putback(__c); + } + + for (size_t __i = 0; __i < _Nb; ++__i) { + char __c; + __is.get(__c); + + if (!__is) + break; + else if (__c != '0' && __c != '1') { + __is.putback(__c); + break; + } + else + __tmp.push_back(__c); + } + + if (__tmp.empty()) + __is.clear(__is.rdstate() | ios::failbit); + else + __x._M_copy_from_string(__tmp, static_cast<size_t>(0), _Nb); + + return __is; +} + +template <size_t _Nb, class _WordT> +ostream& operator<<(ostream& __os, const bitset<_Nb,_WordT>& __x) { + string __tmp; + __x._M_copy_to_string(__tmp); + return __os << __tmp; +} + +// ------------------------------------------------------------ +// Lookup tables for find and count operations. + +template<bool __dummy> +unsigned char _Bit_count<__dummy>::_S_bit_count[] = { + 0, /* 0 */ 1, /* 1 */ 1, /* 2 */ 2, /* 3 */ 1, /* 4 */ + 2, /* 5 */ 2, /* 6 */ 3, /* 7 */ 1, /* 8 */ 2, /* 9 */ + 2, /* 10 */ 3, /* 11 */ 2, /* 12 */ 3, /* 13 */ 3, /* 14 */ + 4, /* 15 */ 1, /* 16 */ 2, /* 17 */ 2, /* 18 */ 3, /* 19 */ + 2, /* 20 */ 3, /* 21 */ 3, /* 22 */ 4, /* 23 */ 2, /* 24 */ + 3, /* 25 */ 3, /* 26 */ 4, /* 27 */ 3, /* 28 */ 4, /* 29 */ + 4, /* 30 */ 5, /* 31 */ 1, /* 32 */ 2, /* 33 */ 2, /* 34 */ + 3, /* 35 */ 2, /* 36 */ 3, /* 37 */ 3, /* 38 */ 4, /* 39 */ + 2, /* 40 */ 3, /* 41 */ 3, /* 42 */ 4, /* 43 */ 3, /* 44 */ + 4, /* 45 */ 4, /* 46 */ 5, /* 47 */ 2, /* 48 */ 3, /* 49 */ + 3, /* 50 */ 4, /* 51 */ 3, /* 52 */ 4, /* 53 */ 4, /* 54 */ + 5, /* 55 */ 3, /* 56 */ 4, /* 57 */ 4, /* 58 */ 5, /* 59 */ + 4, /* 60 */ 5, /* 61 */ 5, /* 62 */ 6, /* 63 */ 1, /* 64 */ + 2, /* 65 */ 2, /* 66 */ 3, /* 67 */ 2, /* 68 */ 3, /* 69 */ + 3, /* 70 */ 4, /* 71 */ 2, /* 72 */ 3, /* 73 */ 3, /* 74 */ + 4, /* 75 */ 3, /* 76 */ 4, /* 77 */ 4, /* 78 */ 5, /* 79 */ + 2, /* 80 */ 3, /* 81 */ 3, /* 82 */ 4, /* 83 */ 3, /* 84 */ + 4, /* 85 */ 4, /* 86 */ 5, /* 87 */ 3, /* 88 */ 4, /* 89 */ + 4, /* 90 */ 5, /* 91 */ 4, /* 92 */ 5, /* 93 */ 5, /* 94 */ + 6, /* 95 */ 2, /* 96 */ 3, /* 97 */ 3, /* 98 */ 4, /* 99 */ + 3, /* 100 */ 4, /* 101 */ 4, /* 102 */ 5, /* 103 */ 3, /* 104 */ + 4, /* 105 */ 4, /* 106 */ 5, /* 107 */ 4, /* 108 */ 5, /* 109 */ + 5, /* 110 */ 6, /* 111 */ 3, /* 112 */ 4, /* 113 */ 4, /* 114 */ + 5, /* 115 */ 4, /* 116 */ 5, /* 117 */ 5, /* 118 */ 6, /* 119 */ + 4, /* 120 */ 5, /* 121 */ 5, /* 122 */ 6, /* 123 */ 5, /* 124 */ + 6, /* 125 */ 6, /* 126 */ 7, /* 127 */ 1, /* 128 */ 2, /* 129 */ + 2, /* 130 */ 3, /* 131 */ 2, /* 132 */ 3, /* 133 */ 3, /* 134 */ + 4, /* 135 */ 2, /* 136 */ 3, /* 137 */ 3, /* 138 */ 4, /* 139 */ + 3, /* 140 */ 4, /* 141 */ 4, /* 142 */ 5, /* 143 */ 2, /* 144 */ + 3, /* 145 */ 3, /* 146 */ 4, /* 147 */ 3, /* 148 */ 4, /* 149 */ + 4, /* 150 */ 5, /* 151 */ 3, /* 152 */ 4, /* 153 */ 4, /* 154 */ + 5, /* 155 */ 4, /* 156 */ 5, /* 157 */ 5, /* 158 */ 6, /* 159 */ + 2, /* 160 */ 3, /* 161 */ 3, /* 162 */ 4, /* 163 */ 3, /* 164 */ + 4, /* 165 */ 4, /* 166 */ 5, /* 167 */ 3, /* 168 */ 4, /* 169 */ + 4, /* 170 */ 5, /* 171 */ 4, /* 172 */ 5, /* 173 */ 5, /* 174 */ + 6, /* 175 */ 3, /* 176 */ 4, /* 177 */ 4, /* 178 */ 5, /* 179 */ + 4, /* 180 */ 5, /* 181 */ 5, /* 182 */ 6, /* 183 */ 4, /* 184 */ + 5, /* 185 */ 5, /* 186 */ 6, /* 187 */ 5, /* 188 */ 6, /* 189 */ + 6, /* 190 */ 7, /* 191 */ 2, /* 192 */ 3, /* 193 */ 3, /* 194 */ + 4, /* 195 */ 3, /* 196 */ 4, /* 197 */ 4, /* 198 */ 5, /* 199 */ + 3, /* 200 */ 4, /* 201 */ 4, /* 202 */ 5, /* 203 */ 4, /* 204 */ + 5, /* 205 */ 5, /* 206 */ 6, /* 207 */ 3, /* 208 */ 4, /* 209 */ + 4, /* 210 */ 5, /* 211 */ 4, /* 212 */ 5, /* 213 */ 5, /* 214 */ + 6, /* 215 */ 4, /* 216 */ 5, /* 217 */ 5, /* 218 */ 6, /* 219 */ + 5, /* 220 */ 6, /* 221 */ 6, /* 222 */ 7, /* 223 */ 3, /* 224 */ + 4, /* 225 */ 4, /* 226 */ 5, /* 227 */ 4, /* 228 */ 5, /* 229 */ + 5, /* 230 */ 6, /* 231 */ 4, /* 232 */ 5, /* 233 */ 5, /* 234 */ + 6, /* 235 */ 5, /* 236 */ 6, /* 237 */ 6, /* 238 */ 7, /* 239 */ + 4, /* 240 */ 5, /* 241 */ 5, /* 242 */ 6, /* 243 */ 5, /* 244 */ + 6, /* 245 */ 6, /* 246 */ 7, /* 247 */ 5, /* 248 */ 6, /* 249 */ + 6, /* 250 */ 7, /* 251 */ 6, /* 252 */ 7, /* 253 */ 7, /* 254 */ + 8 /* 255 */ +}; // end _Bit_count + +template<bool __dummy> +unsigned char _First_one<__dummy>::_S_first_one[] = { + 0, /* 0 */ 0, /* 1 */ 1, /* 2 */ 0, /* 3 */ 2, /* 4 */ + 0, /* 5 */ 1, /* 6 */ 0, /* 7 */ 3, /* 8 */ 0, /* 9 */ + 1, /* 10 */ 0, /* 11 */ 2, /* 12 */ 0, /* 13 */ 1, /* 14 */ + 0, /* 15 */ 4, /* 16 */ 0, /* 17 */ 1, /* 18 */ 0, /* 19 */ + 2, /* 20 */ 0, /* 21 */ 1, /* 22 */ 0, /* 23 */ 3, /* 24 */ + 0, /* 25 */ 1, /* 26 */ 0, /* 27 */ 2, /* 28 */ 0, /* 29 */ + 1, /* 30 */ 0, /* 31 */ 5, /* 32 */ 0, /* 33 */ 1, /* 34 */ + 0, /* 35 */ 2, /* 36 */ 0, /* 37 */ 1, /* 38 */ 0, /* 39 */ + 3, /* 40 */ 0, /* 41 */ 1, /* 42 */ 0, /* 43 */ 2, /* 44 */ + 0, /* 45 */ 1, /* 46 */ 0, /* 47 */ 4, /* 48 */ 0, /* 49 */ + 1, /* 50 */ 0, /* 51 */ 2, /* 52 */ 0, /* 53 */ 1, /* 54 */ + 0, /* 55 */ 3, /* 56 */ 0, /* 57 */ 1, /* 58 */ 0, /* 59 */ + 2, /* 60 */ 0, /* 61 */ 1, /* 62 */ 0, /* 63 */ 6, /* 64 */ + 0, /* 65 */ 1, /* 66 */ 0, /* 67 */ 2, /* 68 */ 0, /* 69 */ + 1, /* 70 */ 0, /* 71 */ 3, /* 72 */ 0, /* 73 */ 1, /* 74 */ + 0, /* 75 */ 2, /* 76 */ 0, /* 77 */ 1, /* 78 */ 0, /* 79 */ + 4, /* 80 */ 0, /* 81 */ 1, /* 82 */ 0, /* 83 */ 2, /* 84 */ + 0, /* 85 */ 1, /* 86 */ 0, /* 87 */ 3, /* 88 */ 0, /* 89 */ + 1, /* 90 */ 0, /* 91 */ 2, /* 92 */ 0, /* 93 */ 1, /* 94 */ + 0, /* 95 */ 5, /* 96 */ 0, /* 97 */ 1, /* 98 */ 0, /* 99 */ + 2, /* 100 */ 0, /* 101 */ 1, /* 102 */ 0, /* 103 */ 3, /* 104 */ + 0, /* 105 */ 1, /* 106 */ 0, /* 107 */ 2, /* 108 */ 0, /* 109 */ + 1, /* 110 */ 0, /* 111 */ 4, /* 112 */ 0, /* 113 */ 1, /* 114 */ + 0, /* 115 */ 2, /* 116 */ 0, /* 117 */ 1, /* 118 */ 0, /* 119 */ + 3, /* 120 */ 0, /* 121 */ 1, /* 122 */ 0, /* 123 */ 2, /* 124 */ + 0, /* 125 */ 1, /* 126 */ 0, /* 127 */ 7, /* 128 */ 0, /* 129 */ + 1, /* 130 */ 0, /* 131 */ 2, /* 132 */ 0, /* 133 */ 1, /* 134 */ + 0, /* 135 */ 3, /* 136 */ 0, /* 137 */ 1, /* 138 */ 0, /* 139 */ + 2, /* 140 */ 0, /* 141 */ 1, /* 142 */ 0, /* 143 */ 4, /* 144 */ + 0, /* 145 */ 1, /* 146 */ 0, /* 147 */ 2, /* 148 */ 0, /* 149 */ + 1, /* 150 */ 0, /* 151 */ 3, /* 152 */ 0, /* 153 */ 1, /* 154 */ + 0, /* 155 */ 2, /* 156 */ 0, /* 157 */ 1, /* 158 */ 0, /* 159 */ + 5, /* 160 */ 0, /* 161 */ 1, /* 162 */ 0, /* 163 */ 2, /* 164 */ + 0, /* 165 */ 1, /* 166 */ 0, /* 167 */ 3, /* 168 */ 0, /* 169 */ + 1, /* 170 */ 0, /* 171 */ 2, /* 172 */ 0, /* 173 */ 1, /* 174 */ + 0, /* 175 */ 4, /* 176 */ 0, /* 177 */ 1, /* 178 */ 0, /* 179 */ + 2, /* 180 */ 0, /* 181 */ 1, /* 182 */ 0, /* 183 */ 3, /* 184 */ + 0, /* 185 */ 1, /* 186 */ 0, /* 187 */ 2, /* 188 */ 0, /* 189 */ + 1, /* 190 */ 0, /* 191 */ 6, /* 192 */ 0, /* 193 */ 1, /* 194 */ + 0, /* 195 */ 2, /* 196 */ 0, /* 197 */ 1, /* 198 */ 0, /* 199 */ + 3, /* 200 */ 0, /* 201 */ 1, /* 202 */ 0, /* 203 */ 2, /* 204 */ + 0, /* 205 */ 1, /* 206 */ 0, /* 207 */ 4, /* 208 */ 0, /* 209 */ + 1, /* 210 */ 0, /* 211 */ 2, /* 212 */ 0, /* 213 */ 1, /* 214 */ + 0, /* 215 */ 3, /* 216 */ 0, /* 217 */ 1, /* 218 */ 0, /* 219 */ + 2, /* 220 */ 0, /* 221 */ 1, /* 222 */ 0, /* 223 */ 5, /* 224 */ + 0, /* 225 */ 1, /* 226 */ 0, /* 227 */ 2, /* 228 */ 0, /* 229 */ + 1, /* 230 */ 0, /* 231 */ 3, /* 232 */ 0, /* 233 */ 1, /* 234 */ + 0, /* 235 */ 2, /* 236 */ 0, /* 237 */ 1, /* 238 */ 0, /* 239 */ + 4, /* 240 */ 0, /* 241 */ 1, /* 242 */ 0, /* 243 */ 2, /* 244 */ + 0, /* 245 */ 1, /* 246 */ 0, /* 247 */ 3, /* 248 */ 0, /* 249 */ + 1, /* 250 */ 0, /* 251 */ 2, /* 252 */ 0, /* 253 */ 1, /* 254 */ + 0, /* 255 */ +}; // end _First_one + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1209 +#endif + +__STL_END_NAMESPACE + + +#undef __BITS_PER_WORDT +#undef __BITSET_WORDS + +#endif /* __SGI_STL_BITSET */ + + +// Local Variables: +// mode:C++ +// End: diff --git a/contrib/libstdc++/stl/defalloc.h b/contrib/libstdc++/stl/defalloc.h index 49690f8..0bfcc2c 100644 --- a/contrib/libstdc++/stl/defalloc.h +++ b/contrib/libstdc++/stl/defalloc.h @@ -15,12 +15,13 @@ // Inclusion of this file is DEPRECATED. This is the original HP // default allocator. It is provided only for backward compatibility. -// +// This file WILL BE REMOVED in a future release. +// // DO NOT USE THIS FILE unless you have an old container implementation -// that requires an allocator with the HP-style interface. SGI STL -// uses a different allocator interface. SGI-style allocators are not -// parametrized with respect to the object type; they traffic in void * -// pointers. This file is not included by any other SGI STL header. +// that requires an allocator with the HP-style interface. +// +// Standard-conforming allocators have a very different interface. The +// standard default allocator is declared in the header <memory>. #ifndef DEFALLOC_H #define DEFALLOC_H diff --git a/contrib/libstdc++/stl/hash_map.h b/contrib/libstdc++/stl/hash_map.h index 81cb578..f347162 100644 --- a/contrib/libstdc++/stl/hash_map.h +++ b/contrib/libstdc++/stl/hash_map.h @@ -31,6 +31,7 @@ #include <stl_hashtable.h> #endif +#include <algobase.h> #include <stl_hash_map.h> #ifdef __STL_USE_NAMESPACES diff --git a/contrib/libstdc++/stl/hash_set.h b/contrib/libstdc++/stl/hash_set.h index c938ccc..d3e93c0 100644 --- a/contrib/libstdc++/stl/hash_set.h +++ b/contrib/libstdc++/stl/hash_set.h @@ -31,6 +31,7 @@ #include <stl_hashtable.h> #endif +#include <algobase.h> #include <stl_hash_set.h> #ifdef __STL_USE_NAMESPACES diff --git a/contrib/libstdc++/stl/iterator b/contrib/libstdc++/stl/iterator index 90e6c9c..4ddd208 100644 --- a/contrib/libstdc++/stl/iterator +++ b/contrib/libstdc++/stl/iterator @@ -29,8 +29,12 @@ #include <stl_config.h> #include <stl_relops.h> -#include <stddef.h> +#include <stddef.h> /* XXX should use <cstddef> */ +#if 0 /* XXX define a flag for this */ +#include <iostream> +#else #include <iostream.h> +#endif #include <stl_iterator.h> #endif /* __SGI_STL_ITERATOR */ diff --git a/contrib/libstdc++/stl/memory b/contrib/libstdc++/stl/memory index a806588..64338dd 100644 --- a/contrib/libstdc++/stl/memory +++ b/contrib/libstdc++/stl/memory @@ -22,64 +22,83 @@ #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) +#if defined(__STL_MEMBER_TEMPLATES) __STL_BEGIN_NAMESPACE -template <class X> class auto_ptr { +template <class _Tp> class auto_ptr { private: - X* ptr; - mutable bool owns; + _Tp* _M_ptr; + public: - typedef X element_type; - explicit auto_ptr(X* p = 0) __STL_NOTHROW : ptr(p), owns(p) {} - auto_ptr(const auto_ptr& a) __STL_NOTHROW : ptr(a.ptr), owns(a.owns) { - a.owns = 0; + typedef _Tp element_type; + explicit auto_ptr(_Tp* __p = 0) __STL_NOTHROW : _M_ptr(__p) {} + auto_ptr(auto_ptr& __a) __STL_NOTHROW : _M_ptr(__a.release()) {} + template <class _Tp1> auto_ptr(auto_ptr<_Tp1>& __a) __STL_NOTHROW + : _M_ptr(__a.release()) {} + auto_ptr& operator=(auto_ptr& __a) __STL_NOTHROW { + if (&__a != this) { + delete _M_ptr; + _M_ptr = __a.release(); + } + return *this; } - template <class T> auto_ptr(const auto_ptr<T>& a) __STL_NOTHROW - : ptr(a.ptr), owns(a.owns) { - a.owns = 0; + template <class _Tp1> + auto_ptr& operator=(auto_ptr<_Tp1>& __a) __STL_NOTHROW { + if (__a.get() != this->get()) { + delete _M_ptr; + _M_ptr = __a.release(); + } + return *this; } + ~auto_ptr() __STL_NOTHROW { delete _M_ptr; } - auto_ptr& operator=(const auto_ptr& a) __STL_NOTHROW { - if (&a != this) { - if (owns) - delete ptr; - owns = a.owns; - ptr = a.ptr; - a.owns = 0; - } + _Tp& operator*() const __STL_NOTHROW { + return *_M_ptr; } - template <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; - } + _Tp* operator->() const __STL_NOTHROW { + return _M_ptr; + } + _Tp* get() const __STL_NOTHROW { + return _M_ptr; + } + _Tp* release() __STL_NOTHROW { + _Tp* __tmp = _M_ptr; + _M_ptr = 0; + return __tmp; } - ~auto_ptr() { - if (owns) - delete ptr; + void reset(_Tp* __p = 0) __STL_NOTHROW { + delete _M_ptr; + _M_ptr = __p; } - X& operator*() const __STL_NOTHROW { return *ptr; } - X* operator->() const __STL_NOTHROW { return ptr; } - X* get() const __STL_NOTHROW { return ptr; } - X* release const __STL_NOTHROW { owns = false; return ptr } + // According to the C++ standard, these conversions are required. Most + // present-day compilers, however, do not enforce that requirement---and, + // in fact, most present-day compilers do not support the language + // features that these conversions rely on. + +#ifdef __SGI_STL_USE_AUTO_PTR_CONVERSIONS + +private: + template<class _Tp1> struct auto_ptr_ref { + _Tp1* _M_ptr; + auto_ptr_ref(_Tp1* __p) : _M_ptr(__p) {} + }; + +public: + auto_ptr(auto_ptr_ref<_Tp> __ref) __STL_NOTHROW + : _M_ptr(__ref._M_ptr) {} + template <class _Tp1> operator auto_ptr_ref<_Tp1>() __STL_NOTHROW + { return auto_ptr_ref<_Tp>(this->release()); } + template <class _Tp1> operator auto_ptr<_Tp1>() __STL_NOTHROW + { return auto_ptr<_Tp1>(this->release()); } + +#endif /* __SGI_STL_USE_AUTO_PTR_CONVERSIONS */ }; __STL_END_NAMESPACE -#endif /* mutable && explicit && member templates */ -#endif /* 0 */ - +#endif /* member templates */ #endif /* __SGI_STL_MEMORY */ diff --git a/contrib/libstdc++/stl/pthread_alloc b/contrib/libstdc++/stl/pthread_alloc index 4ca9d9e..1852908 100644 --- a/contrib/libstdc++/stl/pthread_alloc +++ b/contrib/libstdc++/stl/pthread_alloc @@ -20,7 +20,7 @@ // This should be reasonably fast even in the presence of threads. // The down side is that storage may not be well-utilized. // It is not an error to allocate memory in thread A and deallocate -// it n thread B. But this effectively transfers ownership of the memory, +// it in thread B. But this effectively transfers ownership of the memory, // so that it can only be reallocated by thread B. Thus this can effectively // result in a storage leak if it's done on a regular basis. // It can also result in frequent sharing of @@ -35,308 +35,440 @@ __STL_BEGIN_NAMESPACE -// Note that this class has nonstatic members. We instantiate it once -// per thread. -template <bool dummy> -class __pthread_alloc_template { - -private: - enum {ALIGN = 8}; - enum {MAX_BYTES = 128}; // power of 2 - enum {NFREELISTS = MAX_BYTES/ALIGN}; +#define __STL_DATA_ALIGNMENT 8 + +union _Pthread_alloc_obj { + union _Pthread_alloc_obj * __free_list_link; + char __client_data[__STL_DATA_ALIGNMENT]; /* The client sees this. */ +}; + +// Pthread allocators don't appear to the client to have meaningful +// instances. We do in fact need to associate some state with each +// thread. That state is represented by +// _Pthread_alloc_per_thread_state<_Max_size>. + +template<size_t _Max_size> +struct _Pthread_alloc_per_thread_state { + typedef _Pthread_alloc_obj __obj; + enum { _S_NFREELISTS = _Max_size/__STL_DATA_ALIGNMENT }; + _Pthread_alloc_obj* volatile __free_list[_S_NFREELISTS]; + _Pthread_alloc_per_thread_state<_Max_size> * __next; + // Free list link for list of available per thread structures. + // When one of these becomes available for reuse due to thread + // termination, any objects in its free list remain associated + // with it. The whole structure may then be used by a newly + // created thread. + _Pthread_alloc_per_thread_state() : __next(0) + { + memset((void *)__free_list, 0, _S_NFREELISTS * sizeof(__obj *)); + } + // Returns an object of size __n, and possibly adds to size n free list. + void *_M_refill(size_t __n); +}; - union obj { - union obj * free_list_link; - char client_data[ALIGN]; /* The client sees this. */ - }; +// Pthread-specific allocator. +// The argument specifies the largest object size allocated from per-thread +// free lists. Larger objects are allocated using malloc_alloc. +// Max_size must be a power of 2. +template <size_t _Max_size = 128> +class _Pthread_alloc_template { - // Per instance state - obj* volatile free_list[NFREELISTS]; - __pthread_alloc_template<dummy>* next; // Free list link +public: // but only for internal use: - static size_t ROUND_UP(size_t bytes) { - return (((bytes) + ALIGN-1) & ~(ALIGN - 1)); - } - static size_t FREELIST_INDEX(size_t bytes) { - return (((bytes) + ALIGN-1)/ALIGN - 1); - } + typedef _Pthread_alloc_obj __obj; - // Returns an object of size n, and optionally adds to size n free list. - void *refill(size_t n); // Allocates a chunk for nobjs of size "size". nobjs may be reduced // if it is inconvenient to allocate the requested number. - static char *chunk_alloc(size_t size, int &nobjs); + static char *_S_chunk_alloc(size_t __size, int &__nobjs); + + enum {_S_ALIGN = __STL_DATA_ALIGNMENT}; + + static size_t _S_round_up(size_t __bytes) { + return (((__bytes) + _S_ALIGN-1) & ~(_S_ALIGN - 1)); + } + static size_t _S_freelist_index(size_t __bytes) { + return (((__bytes) + _S_ALIGN-1)/_S_ALIGN - 1); + } +private: // Chunk allocation state. And other shared state. - // Protected by chunk_allocator_lock. - static pthread_mutex_t chunk_allocator_lock; - static char *start_free; - static char *end_free; - static size_t heap_size; - static __pthread_alloc_template<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 { + // Protected by _S_chunk_allocator_lock. + static pthread_mutex_t _S_chunk_allocator_lock; + static char *_S_start_free; + static char *_S_end_free; + static size_t _S_heap_size; + static _Pthread_alloc_per_thread_state<_Max_size>* _S_free_per_thread_states; + static pthread_key_t _S_key; + static bool _S_key_initialized; + // Pthread key under which per thread state is stored. + // Allocator instances that are currently unclaimed by any thread. + static void _S_destructor(void *instance); + // Function to be called on thread exit to reclaim per thread + // state. + static _Pthread_alloc_per_thread_state<_Max_size> *_S_new_per_thread_state(); + // Return a recycled or new per thread state. + static _Pthread_alloc_per_thread_state<_Max_size> *_S_get_per_thread_state(); + // ensure that the current thread has an associated + // per thread state. + friend class _M_lock; + class _M_lock { public: - lock () { pthread_mutex_lock(&chunk_allocator_lock); } - ~lock () { pthread_mutex_unlock(&chunk_allocator_lock); } + _M_lock () { pthread_mutex_lock(&_S_chunk_allocator_lock); } + ~_M_lock () { pthread_mutex_unlock(&_S_chunk_allocator_lock); } }; - friend class lock; - public: - __pthread_alloc_template() : next(0) - { - memset((void *)free_list, 0, NFREELISTS * sizeof(obj *)); - } - - /* n must be > 0 */ - static void * allocate(size_t n) + /* n must be > 0 */ + static void * allocate(size_t __n) { - obj * volatile * my_free_list; - obj * __RESTRICT result; - __pthread_alloc_template<dummy>* a; + __obj * volatile * __my_free_list; + __obj * __RESTRICT __result; + _Pthread_alloc_per_thread_state<_Max_size>* __a; - if (n > MAX_BYTES) { - return(malloc(n)); + if (__n > _Max_size) { + return(malloc_alloc::allocate(__n)); } - if (!key_initialized || - !(a = (__pthread_alloc_template<dummy>*) - pthread_getspecific(key))) { - a = get_allocator_instance(); + if (!_S_key_initialized || + !(__a = (_Pthread_alloc_per_thread_state<_Max_size>*) + pthread_getspecific(_S_key))) { + __a = _S_get_per_thread_state(); } - my_free_list = a -> free_list + FREELIST_INDEX(n); - result = *my_free_list; - if (result == 0) { - void *r = a -> refill(ROUND_UP(n)); - return r; + __my_free_list = __a -> __free_list + _S_freelist_index(__n); + __result = *__my_free_list; + if (__result == 0) { + void *__r = __a -> _M_refill(_S_round_up(__n)); + return __r; } - *my_free_list = result -> free_list_link; - return (result); + *__my_free_list = __result -> __free_list_link; + return (__result); }; /* p may not be 0 */ - static void deallocate(void *p, size_t n) + static void deallocate(void *__p, size_t __n) { - obj *q = (obj *)p; - obj * volatile * my_free_list; - __pthread_alloc_template<dummy>* a; + __obj *__q = (__obj *)__p; + __obj * volatile * __my_free_list; + _Pthread_alloc_per_thread_state<_Max_size>* __a; - if (n > MAX_BYTES) { - free(p); - return; + if (__n > _Max_size) { + malloc_alloc::deallocate(__p, __n); + return; } - if (!key_initialized || - !(a = (__pthread_alloc_template<dummy>*) - pthread_getspecific(key))) { - a = get_allocator_instance(); + if (!_S_key_initialized || + !(__a = (_Pthread_alloc_per_thread_state<_Max_size> *) + pthread_getspecific(_S_key))) { + __a = _S_get_per_thread_state(); } - my_free_list = a->free_list + FREELIST_INDEX(n); - q -> free_list_link = *my_free_list; - *my_free_list = q; + __my_free_list = __a->__free_list + _S_freelist_index(__n); + __q -> __free_list_link = *__my_free_list; + *__my_free_list = __q; } - static void * reallocate(void *p, size_t old_sz, size_t new_sz); + static void * reallocate(void *__p, size_t __old_sz, size_t __new_sz); } ; -typedef __pthread_alloc_template<false> pthread_alloc; +typedef _Pthread_alloc_template<> pthread_alloc; -template <bool dummy> -void __pthread_alloc_template<dummy>::destructor(void * instance) +template <size_t _Max_size> +void _Pthread_alloc_template<_Max_size>::_S_destructor(void * __instance) { - __pthread_alloc_template<dummy>* a = - (__pthread_alloc_template<dummy>*)instance; - a -> next = free_allocators; - free_allocators = a; + _M_lock __lock_instance; // Need to acquire lock here. + _Pthread_alloc_per_thread_state<_Max_size>* __s = + (_Pthread_alloc_per_thread_state<_Max_size> *)__instance; + __s -> __next = _S_free_per_thread_states; + _S_free_per_thread_states = __s; } -template <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; +template <size_t _Max_size> +_Pthread_alloc_per_thread_state<_Max_size> * +_Pthread_alloc_template<_Max_size>::_S_new_per_thread_state() +{ + /* lock already held here. */ + if (0 != _S_free_per_thread_states) { + _Pthread_alloc_per_thread_state<_Max_size> *__result = + _S_free_per_thread_states; + _S_free_per_thread_states = _S_free_per_thread_states -> __next; + return __result; } else { - return new __pthread_alloc_template<dummy>; + return new _Pthread_alloc_per_thread_state<_Max_size>; } } -template <bool dummy> -__pthread_alloc_template<dummy>* -__pthread_alloc_template<dummy>::get_allocator_instance() +template <size_t _Max_size> +_Pthread_alloc_per_thread_state<_Max_size> * +_Pthread_alloc_template<_Max_size>::_S_get_per_thread_state() { - __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; - } + /*REFERENCED*/ + _M_lock __lock_instance; // Need to acquire lock here. + _Pthread_alloc_per_thread_state<_Max_size> * __result; + if (!_S_key_initialized) { + if (pthread_key_create(&_S_key, _S_destructor)) { + abort(); // failed + } + _S_key_initialized = true; } - result = new_allocator(); - if (pthread_setspecific(key, result)) abort(); - return result; + __result = _S_new_per_thread_state(); + if (pthread_setspecific(_S_key, __result)) abort(); + return __result; } -/* We allocate memory in large chunks in order to avoid fragmenting */ -/* the malloc heap too much. */ -/* We assume that size is properly aligned. */ -template <bool dummy> -char *__pthread_alloc_template<dummy> -::chunk_alloc(size_t size, int &nobjs) +/* We allocate memory in large chunks in order to avoid fragmenting */ +/* the malloc heap too much. */ +/* We assume that size is properly aligned. */ +template <size_t _Max_size> +char *_Pthread_alloc_template<_Max_size> +::_S_chunk_alloc(size_t __size, int &__nobjs) { { - char * result; - size_t total_bytes; - size_t bytes_left; + char * __result; + size_t __total_bytes; + size_t __bytes_left; /*REFERENCED*/ - lock lock_instance; // Acquire lock for this routine - - total_bytes = size * nobjs; - bytes_left = end_free - start_free; - if (bytes_left >= total_bytes) { - result = start_free; - start_free += total_bytes; - return(result); - } else if (bytes_left >= size) { - nobjs = bytes_left/size; - total_bytes = size * nobjs; - result = start_free; - start_free += total_bytes; - return(result); + _M_lock __lock_instance; // Acquire lock for this routine + + __total_bytes = __size * __nobjs; + __bytes_left = _S_end_free - _S_start_free; + if (__bytes_left >= __total_bytes) { + __result = _S_start_free; + _S_start_free += __total_bytes; + return(__result); + } else if (__bytes_left >= __size) { + __nobjs = __bytes_left/__size; + __total_bytes = __size * __nobjs; + __result = _S_start_free; + _S_start_free += __total_bytes; + return(__result); } else { - size_t bytes_to_get = 2 * total_bytes + ROUND_UP(heap_size >> 4); - // Try to make use of the left-over piece. - if (bytes_left > 0) { - __pthread_alloc_template<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); + size_t __bytes_to_get = + 2 * __total_bytes + _S_round_up(_S_heap_size >> 4); + // Try to make use of the left-over piece. + if (__bytes_left > 0) { + _Pthread_alloc_per_thread_state<_Max_size>* __a = + (_Pthread_alloc_per_thread_state<_Max_size>*) + pthread_getspecific(_S_key); + __obj * volatile * __my_free_list = + __a->__free_list + _S_freelist_index(__bytes_left); + + ((__obj *)_S_start_free) -> __free_list_link = *__my_free_list; + *__my_free_list = (__obj *)_S_start_free; + } +# ifdef _SGI_SOURCE + // Try to get memory that's aligned on something like a + // cache line boundary, so as to avoid parceling out + // parts of the same line to different threads and thus + // possibly different processors. + { + const int __cache_line_size = 128; // probable upper bound + __bytes_to_get &= ~(__cache_line_size-1); + _S_start_free = (char *)memalign(__cache_line_size, __bytes_to_get); + if (0 == _S_start_free) { + _S_start_free = (char *)malloc_alloc::allocate(__bytes_to_get); + } + } +# else /* !SGI_SOURCE */ + _S_start_free = (char *)malloc_alloc::allocate(__bytes_to_get); # endif - heap_size += bytes_to_get; - end_free = start_free + bytes_to_get; + _S_heap_size += __bytes_to_get; + _S_end_free = _S_start_free + __bytes_to_get; } } // lock is released here - return(chunk_alloc(size, nobjs)); + return(_S_chunk_alloc(__size, __nobjs)); } /* Returns an object of size n, and optionally adds to size n free list.*/ -/* We assume that n is properly aligned. */ -/* We hold the allocation lock. */ -template <bool dummy> -void *__pthread_alloc_template<dummy> -::refill(size_t n) +/* We assume that n is properly aligned. */ +/* We hold the allocation lock. */ +template <size_t _Max_size> +void *_Pthread_alloc_per_thread_state<_Max_size> +::_M_refill(size_t __n) { - int nobjs = 128; - char * chunk = chunk_alloc(n, nobjs); - obj * volatile * my_free_list; - obj * result; - obj * current_obj, * next_obj; - int i; - - if (1 == nobjs) { - return(chunk); + int __nobjs = 128; + char * __chunk = + _Pthread_alloc_template<_Max_size>::_S_chunk_alloc(__n, __nobjs); + __obj * volatile * __my_free_list; + __obj * __result; + __obj * __current_obj, * __next_obj; + int __i; + + if (1 == __nobjs) { + return(__chunk); } - my_free_list = free_list + FREELIST_INDEX(n); + __my_free_list = __free_list + + _Pthread_alloc_template<_Max_size>::_S_freelist_index(__n); /* Build free list in chunk */ - result = (obj *)chunk; - *my_free_list = next_obj = (obj *)(chunk + n); - for (i = 1; ; i++) { - current_obj = next_obj; - next_obj = (obj *)((char *)next_obj + n); - if (nobjs - 1 == i) { - current_obj -> free_list_link = 0; - break; - } else { - current_obj -> free_list_link = next_obj; - } + __result = (__obj *)__chunk; + *__my_free_list = __next_obj = (__obj *)(__chunk + __n); + for (__i = 1; ; __i++) { + __current_obj = __next_obj; + __next_obj = (__obj *)((char *)__next_obj + __n); + if (__nobjs - 1 == __i) { + __current_obj -> __free_list_link = 0; + break; + } else { + __current_obj -> __free_list_link = __next_obj; + } } - return(result); + return(__result); } -template <bool dummy> -void *__pthread_alloc_template<dummy> -::reallocate(void *p, size_t old_sz, size_t new_sz) +template <size_t _Max_size> +void *_Pthread_alloc_template<_Max_size> +::reallocate(void *__p, size_t __old_sz, size_t __new_sz) { - void * result; - size_t copy_sz; + void * __result; + size_t __copy_sz; - if (old_sz > MAX_BYTES && new_sz > MAX_BYTES) { - return(realloc(p, new_sz)); + if (__old_sz > _Max_size + && __new_sz > _Max_size) { + return(realloc(__p, __new_sz)); } - if (ROUND_UP(old_sz) == ROUND_UP(new_sz)) return(p); - result = allocate(new_sz); - copy_sz = new_sz > old_sz? old_sz : new_sz; - memcpy(result, p, copy_sz); - deallocate(p, old_sz); - return(result); + if (_S_round_up(__old_sz) == _S_round_up(__new_sz)) return(__p); + __result = allocate(__new_sz); + __copy_sz = __new_sz > __old_sz? __old_sz : __new_sz; + memcpy(__result, __p, __copy_sz); + deallocate(__p, __old_sz); + return(__result); } -template <bool dummy> -__pthread_alloc_template<dummy> * -__pthread_alloc_template<dummy>::free_allocators = 0; +template <size_t _Max_size> +_Pthread_alloc_per_thread_state<_Max_size> * +_Pthread_alloc_template<_Max_size>::_S_free_per_thread_states = 0; -template <bool dummy> -pthread_key_t __pthread_alloc_template<dummy>::key; +template <size_t _Max_size> +pthread_key_t _Pthread_alloc_template<_Max_size>::_S_key; -template <bool dummy> -bool __pthread_alloc_template<dummy>::key_initialized = false; +template <size_t _Max_size> +bool _Pthread_alloc_template<_Max_size>::_S_key_initialized = false; -template <bool dummy> -pthread_mutex_t __pthread_alloc_template<dummy>::chunk_allocator_lock +template <size_t _Max_size> +pthread_mutex_t _Pthread_alloc_template<_Max_size>::_S_chunk_allocator_lock = PTHREAD_MUTEX_INITIALIZER; -template <bool dummy> -char *__pthread_alloc_template<dummy> -::start_free = 0; +template <size_t _Max_size> +char *_Pthread_alloc_template<_Max_size> +::_S_start_free = 0; + +template <size_t _Max_size> +char *_Pthread_alloc_template<_Max_size> +::_S_end_free = 0; + +template <size_t _Max_size> +size_t _Pthread_alloc_template<_Max_size> +::_S_heap_size = 0; + +#ifdef __STL_USE_STD_ALLOCATORS + +template <class _Tp> +class pthread_allocator { + typedef pthread_alloc _S_Alloc; // The underlying allocator. +public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef _Tp value_type; + + template <class _Up> struct rebind { + typedef pthread_allocator<_Up> other; + }; + + pthread_allocator() __STL_NOTHROW {} + pthread_allocator(const pthread_allocator& a) __STL_NOTHROW {} + template <class _Up> pthread_allocator(const pthread_allocator<_Up>&) + __STL_NOTHROW {} + ~pthread_allocator() __STL_NOTHROW {} + + pointer address(reference __x) const { return &__x; } + const_pointer address(const_reference __x) const { return &__x; } + + // __n is permitted to be 0. The C++ standard says nothing about what + // the return value is when __n == 0. + _Tp* allocate(size_type __n, const void* = 0) { + return __n != 0 ? static_cast<_Tp*>(_S_Alloc::allocate(__n * sizeof(_Tp))) + : 0; + } + + // p is not permitted to be a null pointer. + void deallocate(pointer __p, size_type __n) + { _S_Alloc::deallocate(__p, __n * sizeof(_Tp)); } + + size_type max_size() const __STL_NOTHROW + { return size_t(-1) / sizeof(_Tp); } + + void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); } + void destroy(pointer _p) { _p->~_Tp(); } +}; + +template<> +class pthread_allocator<void> { +public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef void* pointer; + typedef const void* const_pointer; + typedef void value_type; + + template <class _Up> struct rebind { + typedef pthread_allocator<_Up> other; + }; +}; + +template <size_t _Max_size> +inline bool operator==(const _Pthread_alloc_template<_Max_size>&, + const _Pthread_alloc_template<_Max_size>&) +{ + return true; +} + +template <class _T1, class _T2> +inline bool operator==(const pthread_allocator<_T1>&, + const pthread_allocator<_T2>& a2) +{ + return true; +} + +template <class _T1, class _T2> +inline bool operator!=(const pthread_allocator<_T1>&, + const pthread_allocator<_T2>&) +{ + return false; +} + +template <class _Tp, size_t _Max_size> +struct _Alloc_traits<_Tp, _Pthread_alloc_template<_Max_size> > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, _Pthread_alloc_template<_Max_size> > _Alloc_type; + typedef __allocator<_Tp, _Pthread_alloc_template<_Max_size> > + allocator_type; +}; + +template <class _Tp, class _Up, size_t _Max> +struct _Alloc_traits<_Tp, __allocator<_Up, _Pthread_alloc_template<_Max> > > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, _Pthread_alloc_template<_Max> > _Alloc_type; + typedef __allocator<_Tp, _Pthread_alloc_template<_Max> > allocator_type; +}; + +template <class _Tp, class _Up> +struct _Alloc_traits<_Tp, pthread_allocator<_Up> > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, _Pthread_alloc_template<> > _Alloc_type; + typedef pthread_allocator<_Tp> allocator_type; +}; -template <bool dummy> -char *__pthread_alloc_template<dummy> -::end_free = 0; -template <bool dummy> -size_t __pthread_alloc_template<dummy> -::heap_size = 0; +#endif /* __STL_USE_STD_ALLOCATORS */ __STL_END_NAMESPACE diff --git a/contrib/libstdc++/stl/pthread_alloc.h b/contrib/libstdc++/stl/pthread_alloc.h index 0a2debb..774ef04 100644 --- a/contrib/libstdc++/stl/pthread_alloc.h +++ b/contrib/libstdc++/stl/pthread_alloc.h @@ -18,8 +18,8 @@ #ifdef __STL_USE_NAMESPACES -using __STD::__pthread_alloc_template; -using __STL::pthread_alloc; +using __STD::_Pthread_alloc_template; +using __STD::pthread_alloc; #endif /* __STL_USE_NAMESPACES */ diff --git a/contrib/libstdc++/stl/rope b/contrib/libstdc++/stl/rope index 9ef7382..f861500 100644 --- a/contrib/libstdc++/stl/rope +++ b/contrib/libstdc++/stl/rope @@ -15,7 +15,7 @@ #define __SGI_STL_ROPE #include <stl_algobase.h> -#include <tempbuf.h> +#include <stl_tempbuf.h> #include <stl_algo.h> #include <stl_function.h> #include <stl_numeric.h> diff --git a/contrib/libstdc++/stl/ropeimpl.h b/contrib/libstdc++/stl/ropeimpl.h index b4af525..18bb2c9 100644 --- a/contrib/libstdc++/stl/ropeimpl.h +++ b/contrib/libstdc++/stl/ropeimpl.h @@ -15,8 +15,8 @@ * You should not attempt to use it directly. */ -# include <stdio.h> -# include <iostream.h> +# include <stdio.h> /* XXX should use <cstdio> */ +# include <iostream.h> /* XXX should use <iostream> */ __STL_BEGIN_NAMESPACE @@ -25,45 +25,46 @@ __STL_BEGIN_NAMESPACE #endif // Set buf_start, buf_end, and buf_ptr appropriately, filling tmp_buf -// if necessary. Assumes path_end[leaf_index] and leaf_pos are correct. +// if necessary. Assumes _M_path_end[leaf_index] and leaf_pos are correct. // Results in a valid buf_ptr if the iterator can be legitimately // dereferenced. -template <class charT, class Alloc> -void __rope_iterator_base<charT,Alloc>::setbuf -(__rope_iterator_base<charT,Alloc> &x) +template <class _CharT, class _Alloc> +void _Rope_iterator_base<_CharT,_Alloc>::_S_setbuf( + _Rope_iterator_base<_CharT,_Alloc>& __x) { - const RopeBase * leaf = x.path_end[x.leaf_index]; - size_t leaf_pos = x.leaf_pos; - size_t pos = x.current_pos; - - switch(leaf -> tag) { - case RopeBase::leaf: - x.buf_start = ((__rope_RopeLeaf<charT,Alloc> *)leaf) -> data; - x.buf_ptr = x.buf_start + (pos - leaf_pos); - x.buf_end = x.buf_start + leaf -> size; + const _RopeRep* __leaf = __x._M_path_end[__x._M_leaf_index]; + size_t __leaf_pos = __x._M_leaf_pos; + size_t __pos = __x._M_current_pos; + + switch(__leaf->_M_tag) { + case _RopeRep::_S_leaf: + __x._M_buf_start = + ((_Rope_RopeLeaf<_CharT,_Alloc>*)__leaf)->_M_data; + __x._M_buf_ptr = __x._M_buf_start + (__pos - __leaf_pos); + __x._M_buf_end = __x._M_buf_start + __leaf->_M_size; break; - case RopeBase::function: - case RopeBase::substringfn: + case _RopeRep::_S_function: + case _RopeRep::_S_substringfn: { - size_t len = iterator_buf_len; - size_t buf_start_pos = leaf_pos; - size_t leaf_end = leaf_pos + leaf -> size; - char_producer<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; + size_t __len = _S_iterator_buf_len; + size_t __buf_start_pos = __leaf_pos; + size_t __leaf_end = __leaf_pos + __leaf->_M_size; + char_producer<_CharT>* __fn = + ((_Rope_RopeFunction<_CharT,_Alloc>*)__leaf)->_M_fn; + + if (__buf_start_pos + __len <= __pos) { + __buf_start_pos = __pos - __len/4; + if (__buf_start_pos + __len > __leaf_end) { + __buf_start_pos = __leaf_end - __len; } } - if (buf_start_pos + len > leaf_end) { - len = leaf_end - buf_start_pos; + if (__buf_start_pos + __len > __leaf_end) { + __len = __leaf_end - __buf_start_pos; } - (*fn)(buf_start_pos - leaf_pos, len, x.tmp_buf); - x.buf_ptr = x.tmp_buf + (pos - buf_start_pos); - x.buf_start = x.tmp_buf; - x.buf_end = x.tmp_buf + len; + (*__fn)(__buf_start_pos - __leaf_pos, __len, __x._M_tmp_buf); + __x._M_buf_ptr = __x._M_tmp_buf + (__pos - __buf_start_pos); + __x._M_buf_start = __x._M_tmp_buf; + __x._M_buf_end = __x._M_tmp_buf + __len; } break; default: @@ -73,339 +74,305 @@ void __rope_iterator_base<charT,Alloc>::setbuf // 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) +template <class _CharT, class _Alloc> +void _Rope_iterator_base<_CharT,_Alloc>::_S_setcache +(_Rope_iterator_base<_CharT,_Alloc>& __x) { - const RopeBase * path[RopeBase::max_rope_depth+1]; - const RopeBase * curr_rope; - int curr_depth = -1; /* index into path */ - size_t curr_start_pos = 0; - size_t pos = x.current_pos; - unsigned char dirns = 0; // Bit vector indicating right turns in the path - - __stl_assert(pos <= x.root -> size); - if (pos >= x.root -> size) { - x.buf_ptr = 0; + const _RopeRep* __path[_RopeRep::_S_max_rope_depth+1]; + const _RopeRep* __curr_rope; + int __curr_depth = -1; /* index into path */ + size_t __curr_start_pos = 0; + size_t __pos = __x._M_current_pos; + unsigned char __dirns = 0; // Bit vector marking right turns in the path + + __stl_assert(__pos <= __x._M_root->_M_size); + if (__pos >= __x._M_root->_M_size) { + __x._M_buf_ptr = 0; return; } - curr_rope = x.root; - if (0 != curr_rope -> c_string) { + __curr_rope = __x._M_root; + if (0 != __curr_rope->_M_c_string) { /* Treat the root as a leaf. */ - x.buf_start = curr_rope -> c_string; - x.buf_end = curr_rope -> c_string + curr_rope -> size; - x.buf_ptr = curr_rope -> c_string + pos; - x.path_end[0] = curr_rope; - x.leaf_index = 0; - x.leaf_pos = 0; + __x._M_buf_start = __curr_rope->_M_c_string; + __x._M_buf_end = __curr_rope->_M_c_string + __curr_rope->_M_size; + __x._M_buf_ptr = __curr_rope->_M_c_string + __pos; + __x._M_path_end[0] = __curr_rope; + __x._M_leaf_index = 0; + __x._M_leaf_pos = 0; return; } for(;;) { - ++curr_depth; - __stl_assert(curr_depth <= RopeBase::max_rope_depth); - path[curr_depth] = curr_rope; - switch(curr_rope -> tag) { - case RopeBase::leaf: - case RopeBase::function: - case RopeBase::substringfn: - x.leaf_pos = curr_start_pos; + ++__curr_depth; + __stl_assert(__curr_depth <= _RopeRep::_S_max_rope_depth); + __path[__curr_depth] = __curr_rope; + switch(__curr_rope->_M_tag) { + case _RopeRep::_S_leaf: + case _RopeRep::_S_function: + case _RopeRep::_S_substringfn: + __x._M_leaf_pos = __curr_start_pos; goto done; - case RopeBase::concat: + case _RopeRep::_S_concat: { - __rope_RopeConcatenation<charT,Alloc> *c = - (__rope_RopeConcatenation<charT,Alloc> *)curr_rope; - RopeBase * left = c -> left; - size_t left_len = left -> size; + _Rope_RopeConcatenation<_CharT,_Alloc>* __c = + (_Rope_RopeConcatenation<_CharT,_Alloc>*)__curr_rope; + _RopeRep* __left = __c->_M_left; + size_t __left_len = __left->_M_size; - dirns <<= 1; - if (pos >= curr_start_pos + left_len) { - dirns |= 1; - curr_rope = c -> right; - curr_start_pos += left_len; + __dirns <<= 1; + if (__pos >= __curr_start_pos + __left_len) { + __dirns |= 1; + __curr_rope = __c->_M_right; + __curr_start_pos += __left_len; } else { - curr_rope = left; + __curr_rope = __left; } } break; } } done: - // Copy last section of path into path_end. + // Copy last section of path into _M_path_end. { - int i = -1; - int j = curr_depth + 1 - path_cache_len; + int __i = -1; + int __j = __curr_depth + 1 - _S_path_cache_len; - if (j < 0) j = 0; - while (j <= curr_depth) { - x.path_end[++i] = path[j++]; + if (__j < 0) __j = 0; + while (__j <= __curr_depth) { + __x._M_path_end[++__i] = __path[__j++]; } - x.leaf_index = i; + __x._M_leaf_index = __i; } - x.path_directions = dirns; - setbuf(x); + __x._M_path_directions = __dirns; + _S_setbuf(__x); } // Specialized version of the above. Assumes that // the path cache is valid for the previous position. -template <class charT, class Alloc> -void __rope_iterator_base<charT,Alloc>::setcache_for_incr -(__rope_iterator_base<charT,Alloc> &x) +template <class _CharT, class _Alloc> +void _Rope_iterator_base<_CharT,_Alloc>::_S_setcache_for_incr +(_Rope_iterator_base<_CharT,_Alloc>& __x) { - int current_index = x.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) { + int __current_index = __x._M_leaf_index; + const _RopeRep* __current_node = __x._M_path_end[__current_index]; + size_t __len = __current_node->_M_size; + size_t __node_start_pos = __x._M_leaf_pos; + unsigned char __dirns = __x._M_path_directions; + _Rope_RopeConcatenation<_CharT,_Alloc>* __c; + + __stl_assert(__x._M_current_pos <= __x._M_root->_M_size); + if (__x._M_current_pos - __node_start_pos < __len) { /* More stuff in this leaf, we just didn't cache it. */ - setbuf(x); + _S_setbuf(__x); return; } - __stl_assert(node_start_pos + len == x.current_pos); + __stl_assert(__node_start_pos + __len == __x._M_current_pos); // node_start_pos is starting position of last_node. - while (--current_index >= 0) { - if (!(dirns & 1) /* Path turned left */) break; - current_node = x.path_end[current_index]; - c = (__rope_RopeConcatenation<charT,Alloc> *)current_node; + while (--__current_index >= 0) { + if (!(__dirns & 1) /* Path turned left */) + break; + __current_node = __x._M_path_end[__current_index]; + __c = (_Rope_RopeConcatenation<_CharT,_Alloc>*)__current_node; // Otherwise we were in the right child. Thus we should pop // the concatenation node. - node_start_pos -= c -> left -> size; - dirns >>= 1; + __node_start_pos -= __c->_M_left->_M_size; + __dirns >>= 1; } - if (current_index < 0) { + if (__current_index < 0) { // We underflowed the cache. Punt. - setcache(x); + _S_setcache(__x); return; } - current_node = x.path_end[current_index]; - c = (__rope_RopeConcatenation<charT,Alloc> *)current_node; + __current_node = __x._M_path_end[__current_index]; + __c = (_Rope_RopeConcatenation<_CharT,_Alloc>*)__current_node; // current_node is a concatenation node. We are positioned on the first // character in its right child. // node_start_pos is starting position of current_node. - node_start_pos += c -> left -> size; - current_node = c -> right; - x.path_end[++current_index] = current_node; - dirns |= 1; - while (RopeBase::concat == current_node -> tag) { - ++current_index; - if (path_cache_len == current_index) { - int i; - for (i = 0; i < path_cache_len-1; i++) { - x.path_end[i] = x.path_end[i+1]; + __node_start_pos += __c->_M_left->_M_size; + __current_node = __c->_M_right; + __x._M_path_end[++__current_index] = __current_node; + __dirns |= 1; + while (_RopeRep::_S_concat == __current_node->_M_tag) { + ++__current_index; + if (_S_path_cache_len == __current_index) { + int __i; + for (__i = 0; __i < _S_path_cache_len-1; __i++) { + __x._M_path_end[__i] = __x._M_path_end[__i+1]; } - --current_index; + --__current_index; } - current_node = - ((__rope_RopeConcatenation<charT,Alloc> *)current_node) -> left; - x.path_end[current_index] = current_node; - dirns <<= 1; + __current_node = + ((_Rope_RopeConcatenation<_CharT,_Alloc>*)__current_node)->_M_left; + __x._M_path_end[__current_index] = __current_node; + __dirns <<= 1; // node_start_pos is unchanged. } - x.leaf_index = current_index; - x.leaf_pos = node_start_pos; - x.path_directions = dirns; - setbuf(x); + __x._M_leaf_index = __current_index; + __x._M_leaf_pos = __node_start_pos; + __x._M_path_directions = __dirns; + _S_setbuf(__x); } -template <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); +template <class _CharT, class _Alloc> +void _Rope_iterator_base<_CharT,_Alloc>::_M_incr(size_t __n) { + _M_current_pos += __n; + if (0 != _M_buf_ptr) { + size_t __chars_left = _M_buf_end - _M_buf_ptr; + if (__chars_left > __n) { + _M_buf_ptr += __n; + } else if (__chars_left == __n) { + _M_buf_ptr += __n; + _S_setcache_for_incr(*this); } else { - buf_ptr = 0; + _M_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; +template <class _CharT, class _Alloc> +void _Rope_iterator_base<_CharT,_Alloc>::_M_decr(size_t __n) { + if (0 != _M_buf_ptr) { + size_t __chars_left = _M_buf_ptr - _M_buf_start; + if (__chars_left >= __n) { + _M_buf_ptr -= __n; } else { - buf_ptr = 0; + _M_buf_ptr = 0; } } - current_pos -= n; + _M_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> +void _Rope_iterator<_CharT,_Alloc>::_M_check() { + if (_M_root_rope->_M_tree_ptr != _M_root) { + // _Rope was modified. Get things fixed up. + _RopeRep::_S_unref(_M_root); + _M_root = _M_root_rope->_M_tree_ptr; + _RopeRep::_S_ref(_M_root); + _M_buf_ptr = 0; } } -template <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) +template <class _CharT, class _Alloc> +inline +_Rope_const_iterator<_CharT, _Alloc>::_Rope_const_iterator( + const _Rope_iterator<_CharT,_Alloc>& __x) +: _Rope_iterator_base<_CharT,_Alloc>(__x) +{ } + +template <class _CharT, class _Alloc> +inline _Rope_iterator<_CharT,_Alloc>::_Rope_iterator( + rope<_CharT,_Alloc>& __r, size_t __pos) +: _Rope_iterator_base<_CharT,_Alloc>(__r._M_tree_ptr, __pos), + _M_root_rope(&__r) { - const charT *p = s; - - while (!is0(*p)) { ++p; } - return(p - s); + _RopeRep::_S_ref(_M_root); } -template <class charT, class Alloc> -rope<charT,Alloc>::RopeLeaf * -rope<charT,Alloc>::RopeLeaf_from_char_ptr(__GC_CONST charT *s, size_t size) +template <class _CharT, class _Alloc> +inline size_t +rope<_CharT,_Alloc>::_S_char_ptr_len(const _CharT* __s) { - RopeLeaf *t = LAlloc::allocate(); + const _CharT* __p = __s; - t -> tag = RopeBase::leaf; - if (__is_basic_char_type((charT *)0)) { - // already eos terminated. - t -> c_string = s; - } else { - t -> c_string = 0; - } - t -> is_balanced = true; - t -> depth = 0; - t -> size = size; - t -> data = s; -# ifndef __GC - t -> refcount = 1; - t -> init_refcount_lock(); -# endif - return (t); + while (!_S_is0(*__p)) { ++__p; } + return (__p - __s); } -# ifdef __GC -template <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() +template <class _CharT, class _Alloc> +inline void _Rope_RopeRep<_CharT,_Alloc>::_M_free_c_string() { - charT * cstr = c_string; - if (0 != cstr) { - size_t sz = size + 1; - destroy(cstr, cstr + sz); - DataAlloc::deallocate(cstr, sz); + _CharT* __cstr = _M_c_string; + if (0 != __cstr) { + size_t __size = _M_size + 1; + destroy(__cstr, __cstr + __size); + _Data_deallocate(__cstr, __size); } } -template <class charT, class Alloc> -inline void __rope_RopeBase<charT,Alloc>::free_string(charT* s, size_t n) + +template <class _CharT, class _Alloc> +#ifdef __STL_USE_STD_ALLOCATORS + inline void _Rope_RopeRep<_CharT,_Alloc>::_S_free_string(_CharT* __s, + size_t __n, + allocator_type __a) +#else + inline void _Rope_RopeRep<_CharT,_Alloc>::_S_free_string(_CharT* __s, + size_t __n) +#endif { - if (!__is_basic_char_type((charT *)0)) { - destroy(s, s + n); + if (!_S_is_basic_char_type((_CharT*)0)) { + destroy(__s, __s + __n); } - DataAlloc::deallocate(s, rounded_up_size(n)); +// This has to be a static member, so this gets a bit messy +# ifdef __STL_USE_STD_ALLOCATORS + __a.deallocate( + __s, _Rope_RopeLeaf<_CharT,_Alloc>::_S_rounded_up_size(__n)); +# else + _Data_deallocate( + __s, _Rope_RopeLeaf<_CharT,_Alloc>::_S_rounded_up_size(__n)); +# endif } -template <class charT, class Alloc> -void __rope_RopeBase<charT,Alloc>::free_tree() + +// There are several reasons for not doing this with virtual destructors +// and a class specific delete operator: +// - A class specific delete operator can't easily get access to +// allocator instances if we need them. +// - Any virtual function would need a 4 or byte vtable pointer; +// this only requires a one byte tag per object. +template <class _CharT, class _Alloc> +void _Rope_RopeRep<_CharT,_Alloc>::_M_free_tree() { - switch(tag) { - case leaf: + switch(_M_tag) { + case _S_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); + _Rope_RopeLeaf<_CharT,_Alloc>* __l + = (_Rope_RopeLeaf<_CharT,_Alloc>*)this; + __l->_Rope_RopeLeaf<_CharT,_Alloc>::~_Rope_RopeLeaf(); + _L_deallocate(__l, 1); + break; } - break; - case concat: + case _S_concat: { - __rope_RopeConcatenation<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); + _Rope_RopeConcatenation<_CharT,_Alloc>* __c + = (_Rope_RopeConcatenation<_CharT,_Alloc>*)this; + __c->_Rope_RopeConcatenation<_CharT,_Alloc>:: + ~_Rope_RopeConcatenation(); + _C_deallocate(__c, 1); + break; } - break; - case function: + case _S_function: { - __rope_RopeFunction<charT,Alloc> * fn = - (__rope_RopeFunction<charT,Alloc> *)this; - free_c_string(); - if ( fn -> delete_when_done) { - delete fn -> fn; - } - FAlloc::deallocate(fn); + _Rope_RopeFunction<_CharT,_Alloc>* __f + = (_Rope_RopeFunction<_CharT,_Alloc>*)this; + __f->_Rope_RopeFunction<_CharT,_Alloc>::~_Rope_RopeFunction(); + _F_deallocate(__f, 1); break; } - case substringfn: + case _S_substringfn: { - __rope_RopeSubstring<charT,Alloc> * ss = - (__rope_RopeSubstring<charT,Alloc> *)this; - __rope_RopeBase *base = ss -> base; - free_c_string(); - base -> unref_nonnil(); - SAlloc::deallocate(ss); + _Rope_RopeSubstring<_CharT,_Alloc>* __ss = + (_Rope_RopeSubstring<_CharT,_Alloc>*)this; + __ss->_Rope_RopeSubstring<_CharT,_Alloc>:: + ~_Rope_RopeSubstring(); + _S_deallocate(__ss, 1); break; } } } #else -template <class charT, class Alloc> -inline void __rope_RopeBase<charT,Alloc>::free_string(charT* s, size_t n) +template <class _CharT, class _Alloc> +#ifdef __STL_USE_STD_ALLOCATORS + inline void _Rope_RopeRep<_CharT,_Alloc>::_S_free_string + (const _CharT*, size_t, allocator_type) +#else + inline void _Rope_RopeRep<_CharT,_Alloc>::_S_free_string + (const _CharT*, size_t) +#endif {} #endif @@ -413,55 +380,58 @@ inline void __rope_RopeBase<charT,Alloc>::free_string(charT* s, size_t n) // Concatenate a C string onto a leaf rope by copying the rope data. // Used for short ropes. -template <class charT, class Alloc> -rope<charT,Alloc>::RopeLeaf * -rope<charT,Alloc>::leaf_concat_char_iter - (RopeLeaf * r, const charT * iter, size_t len) +template <class _CharT, class _Alloc> +rope<_CharT,_Alloc>::_RopeLeaf* +rope<_CharT,_Alloc>::_S_leaf_concat_char_iter + (_RopeLeaf* __r, const _CharT* __iter, size_t __len) { - size_t old_len = r -> size; - charT * new_data = (charT *) - DataAlloc::allocate(rounded_up_size(old_len + len)); - RopeLeaf * result; + size_t __old_len = __r->_M_size; + _CharT* __new_data = (_CharT*) + _Data_allocate(_S_rounded_up_size(__old_len + __len)); + _RopeLeaf* __result; - uninitialized_copy_n(r -> data, old_len, new_data); - uninitialized_copy_n(iter, len, new_data + old_len); - __cond_store_eos(new_data[old_len + len]); + uninitialized_copy_n(__r->_M_data, __old_len, __new_data); + uninitialized_copy_n(__iter, __len, __new_data + __old_len); + _S_cond_store_eos(__new_data[__old_len + __len]); __STL_TRY { - result = RopeLeaf_from_char_ptr(new_data, old_len + len); + __result = _S_new_RopeLeaf(__new_data, __old_len + __len, + __r->get_allocator()); } - __STL_UNWIND(RopeBase::free_string(new_data, old_len + len)); - return result; + __STL_UNWIND(_RopeRep::__STL_FREE_STRING(__new_data, __old_len + __len, + __r->get_allocator())); + return __result; } #ifndef __GC // As above, but it's OK to clobber original if refcount is 1 -template <class charT, class Alloc> -rope<charT,Alloc>::RopeLeaf * -rope<charT,Alloc>::destr_leaf_concat_char_iter - (RopeLeaf * r, const charT * iter, size_t len) +template <class _CharT, class _Alloc> +rope<_CharT,_Alloc>::_RopeLeaf* +rope<_CharT,_Alloc>::_S_destr_leaf_concat_char_iter + (_RopeLeaf* __r, const _CharT* __iter, size_t __len) { - __stl_assert(r -> refcount >= 1); - if (r -> refcount > 1) return leaf_concat_char_iter(r, iter, len); - size_t old_len = r -> size; - if (allocated_capacity(old_len) >= old_len + len) { + __stl_assert(__r->_M_refcount >= 1); + if (__r->_M_refcount > 1) + return _S_leaf_concat_char_iter(__r, __iter, __len); + size_t __old_len = __r->_M_size; + if (_S_allocated_capacity(__old_len) >= __old_len + __len) { // The space has been partially initialized for the standard // character types. But that doesn't matter for those types. - uninitialized_copy_n(iter, len, r -> data + old_len); - if (__is_basic_char_type((charT *)0)) { - __cond_store_eos(r -> data[old_len + len]); - __stl_assert(r -> c_string == r -> data); - } else if (r -> c_string != r -> data && 0 != r -> c_string) { - r -> free_c_string(); - r -> c_string = 0; + uninitialized_copy_n(__iter, __len, __r->_M_data + __old_len); + if (_S_is_basic_char_type((_CharT*)0)) { + _S_cond_store_eos(__r->_M_data[__old_len + __len]); + __stl_assert(__r->_M_c_string == __r->_M_data); + } else if (__r->_M_c_string != __r->_M_data && 0 != __r->_M_c_string) { + __r->_M_free_c_string(); + __r->_M_c_string = 0; } - r -> size = old_len + len; - __stl_assert(r -> refcount == 1); - r -> refcount = 2; - return r; + __r->_M_size = __old_len + __len; + __stl_assert(__r->_M_refcount == 1); + __r->_M_refcount = 2; + return __r; } else { - RopeLeaf * result = leaf_concat_char_iter(r, iter, len); - __stl_assert(result -> refcount == 1); - return result; + _RopeLeaf* __result = _S_leaf_concat_char_iter(__r, __iter, __len); + __stl_assert(__result->_M_refcount == 1); + return __result; } } #endif @@ -469,292 +439,300 @@ rope<charT,Alloc>::destr_leaf_concat_char_iter // Assumes left and right are not 0. // Does not increment (nor decrement on exception) child reference counts. // Result has ref count 1. -template <class charT, class Alloc> -rope<charT,Alloc>::RopeBase * -rope<charT,Alloc>::tree_concat (RopeBase * left, RopeBase * right) +template <class _CharT, class _Alloc> +rope<_CharT,_Alloc>::_RopeRep* +rope<_CharT,_Alloc>::_S_tree_concat (_RopeRep* __left, _RopeRep* __right) { - RopeConcatenation * result = CAlloc::allocate(); - unsigned char child_depth = left -> depth; - size_t rsize; - - result -> tag = RopeBase::concat; - result -> c_string = 0; - result -> is_balanced = false; - result -> size = rsize = left -> size + right -> size; - if (right -> depth > child_depth) child_depth = right -> depth; - unsigned char depth = (unsigned char)(child_depth + 1); - result -> depth = depth; - result -> left = left; - result -> right = right; -# ifndef __GC - result -> refcount = 1; - result -> init_refcount_lock(); + _RopeConcatenation* __result = + _S_new_RopeConcatenation(__left, __right, __left->get_allocator()); + size_t __depth = __result->_M_depth; + +# ifdef __STL_USE_STD_ALLOCATORS + __stl_assert(__left->get_allocator() == __right->get_allocator()); # endif - if (depth > 20 && (rsize < 1000 || depth > RopeBase::max_rope_depth)) { - RopeBase * balanced; - + if (__depth > 20 && (__result->_M_size < 1000 || + __depth > _RopeRep::_S_max_rope_depth)) { + _RopeRep* __balanced; + __STL_TRY { - balanced = balance(result); + __balanced = _S_balance(__result); # ifndef __GC - if (result != balanced) { - __stl_assert(1 == result -> refcount - && 1 == balanced -> refcount); + if (__result != __balanced) { + __stl_assert(1 == __result->_M_refcount + && 1 == __balanced->_M_refcount); } # endif - result -> unref_nonnil(); + __result->_M_unref_nonnil(); } - __STL_UNWIND(CAlloc::deallocate(result)); + __STL_UNWIND((_C_deallocate(__result,1))); // In case of exception, we need to deallocate // otherwise dangling result node. But caller // still owns its children. Thus unref is // inappropriate. - return balanced; + return __balanced; } else { - return result; + return __result; } } -template <class charT, class Alloc> -rope<charT,Alloc>::RopeBase * rope<charT,Alloc>::concat_char_iter - (RopeBase * r, const charT *s, size_t slen) +template <class _CharT, class _Alloc> +rope<_CharT,_Alloc>::_RopeRep* rope<_CharT,_Alloc>::_S_concat_char_iter + (_RopeRep* __r, const _CharT*__s, size_t __slen) { - RopeBase *result; - if (0 == slen) { - ref(r); - return r; + _RopeRep* __result; + if (0 == __slen) { + _S_ref(__r); + return __r; } - if (0 == r) return RopeLeaf_from_unowned_char_ptr(s, slen); - if (RopeBase::leaf == r -> tag && r -> size + slen <= copy_max) { - result = leaf_concat_char_iter((RopeLeaf *)r, s, slen); + if (0 == __r) + return __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, + __r->get_allocator()); + if (_RopeRep::_S_leaf == __r->_M_tag && + __r->_M_size + __slen <= _S_copy_max) { + __result = _S_leaf_concat_char_iter((_RopeLeaf*)__r, __s, __slen); # ifndef __GC - __stl_assert(1 == result -> refcount); + __stl_assert(1 == __result->_M_refcount); # endif - return result; + return __result; } - if (RopeBase::concat == r -> tag - && RopeBase::leaf == ((RopeConcatenation *)r) -> right -> tag) { - RopeLeaf *right = (RopeLeaf *)(((RopeConcatenation *)r) -> right); - if (right -> size + slen <= copy_max) { - RopeBase * left = ((RopeConcatenation *)r) -> left; - RopeBase * nright = leaf_concat_char_iter((RopeLeaf *)right, s, slen); - left -> ref_nonnil(); + if (_RopeRep::_S_concat == __r->_M_tag + && _RopeRep::_S_leaf == ((_RopeConcatenation*)__r)->_M_right->_M_tag) { + _RopeLeaf* __right = + (_RopeLeaf* )(((_RopeConcatenation* )__r)->_M_right); + if (__right->_M_size + __slen <= _S_copy_max) { + _RopeRep* __left = ((_RopeConcatenation*)__r)->_M_left; + _RopeRep* __nright = + _S_leaf_concat_char_iter((_RopeLeaf*)__right, __s, __slen); + __left->_M_ref_nonnil(); __STL_TRY { - result = tree_concat(left, nright); + __result = _S_tree_concat(__left, __nright); } - __STL_UNWIND(unref(left); unref(nright)); + __STL_UNWIND(_S_unref(__left); _S_unref(__nright)); # ifndef __GC - __stl_assert(1 == result -> refcount); + __stl_assert(1 == __result->_M_refcount); # endif - return result; + return __result; } } - RopeBase * nright = RopeLeaf_from_unowned_char_ptr(s, slen); + _RopeRep* __nright = + __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __r->get_allocator()); __STL_TRY { - r -> ref_nonnil(); - result = tree_concat(r, nright); + __r->_M_ref_nonnil(); + __result = _S_tree_concat(__r, __nright); } - __STL_UNWIND(unref(r); unref(nright)); + __STL_UNWIND(_S_unref(__r); _S_unref(__nright)); # ifndef __GC - __stl_assert(1 == result -> refcount); + __stl_assert(1 == __result->_M_refcount); # endif - return result; + return __result; } #ifndef __GC -template <class charT, class Alloc> -rope<charT,Alloc>::RopeBase * rope<charT,Alloc> -::destr_concat_char_iter - (RopeBase * r, const charT *s, size_t slen) +template <class _CharT, class _Alloc> +rope<_CharT,_Alloc>::_RopeRep* +rope<_CharT,_Alloc>::_S_destr_concat_char_iter( + _RopeRep* __r, const _CharT* __s, size_t __slen) { - RopeBase *result; - if (0 == r) return RopeLeaf_from_unowned_char_ptr(s, slen); - size_t count = r -> refcount; - size_t orig_size = r -> size; - __stl_assert(count >= 1); - if (count > 1) return concat_char_iter(r, s, slen); - if (0 == slen) { - r -> refcount = 2; // One more than before - return r; + _RopeRep* __result; + if (0 == __r) + return __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, + __r->get_allocator()); + size_t __count = __r->_M_refcount; + size_t __orig_size = __r->_M_size; + __stl_assert(__count >= 1); + if (__count > 1) return _S_concat_char_iter(__r, __s, __slen); + if (0 == __slen) { + __r->_M_refcount = 2; // One more than before + return __r; } - if (orig_size + slen <= copy_max && RopeBase::leaf == r -> tag) { - result = destr_leaf_concat_char_iter((RopeLeaf *)r, s, slen); - return result; + if (__orig_size + __slen <= _S_copy_max && + _RopeRep::_S_leaf == __r->_M_tag) { + __result = _S_destr_leaf_concat_char_iter((_RopeLeaf*)__r, __s, __slen); + return __result; } - if (RopeBase::concat == r -> tag) { - RopeLeaf *right = (RopeLeaf *)(((RopeConcatenation *)r) -> right); - if (RopeBase::leaf == right -> tag - && right -> size + slen <= copy_max) { - RopeBase * new_right = destr_leaf_concat_char_iter(right, s, slen); - if (right == new_right) { - __stl_assert(new_right -> refcount == 2); - new_right -> refcount = 1; + if (_RopeRep::_S_concat == __r->_M_tag) { + _RopeLeaf* __right = (_RopeLeaf*)(((_RopeConcatenation*)__r)->_M_right); + if (_RopeRep::_S_leaf == __right->_M_tag + && __right->_M_size + __slen <= _S_copy_max) { + _RopeRep* __new_right = + _S_destr_leaf_concat_char_iter(__right, __s, __slen); + if (__right == __new_right) { + __stl_assert(__new_right->_M_refcount == 2); + __new_right->_M_refcount = 1; } else { - __stl_assert(new_right -> refcount >= 1); - right -> unref_nonnil(); + __stl_assert(__new_right->_M_refcount >= 1); + __right->_M_unref_nonnil(); } - __stl_assert(r -> refcount == 1); - r -> refcount = 2; // One more than before. - ((RopeConcatenation *)r) -> right = new_right; - r -> size = orig_size + slen; - if (0 != r -> c_string) { - r -> free_c_string(); - r -> c_string = 0; + __stl_assert(__r->_M_refcount == 1); + __r->_M_refcount = 2; // One more than before. + ((_RopeConcatenation*)__r)->_M_right = __new_right; + __r->_M_size = __orig_size + __slen; + if (0 != __r->_M_c_string) { + __r->_M_free_c_string(); + __r->_M_c_string = 0; } - return r; + return __r; } } - RopeBase *right = RopeLeaf_from_unowned_char_ptr(s, slen); - r -> ref_nonnil(); + _RopeRep* __right = + __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __r->get_allocator()); + __r->_M_ref_nonnil(); __STL_TRY { - result = tree_concat(r, right); + __result = _S_tree_concat(__r, __right); } - __STL_UNWIND(unref(r); unref(right)) - __stl_assert(1 == result -> refcount); - return result; + __STL_UNWIND(_S_unref(__r); _S_unref(__right)) + __stl_assert(1 == __result->_M_refcount); + return __result; } #endif /* !__GC */ -template <class charT, class Alloc> -rope<charT,Alloc>::RopeBase * -rope<charT,Alloc>::concat(RopeBase * left, RopeBase * right) +template <class _CharT, class _Alloc> +rope<_CharT,_Alloc>::_RopeRep* +rope<_CharT,_Alloc>::_S_concat(_RopeRep* __left, _RopeRep* __right) { - if (0 == left) { - ref(right); - return right; + if (0 == __left) { + _S_ref(__right); + return __right; } - if (0 == right) { - left -> ref_nonnil(); - return left; + if (0 == __right) { + __left->_M_ref_nonnil(); + return __left; } - if (RopeBase::leaf == right -> tag) { - if (RopeBase::leaf == left -> tag) { - if (right -> size + left -> size <= copy_max) { - return leaf_concat_char_iter((RopeLeaf *)left, - ((RopeLeaf *)right) -> data, - right -> size); + if (_RopeRep::_S_leaf == __right->_M_tag) { + if (_RopeRep::_S_leaf == __left->_M_tag) { + if (__right->_M_size + __left->_M_size <= _S_copy_max) { + return _S_leaf_concat_char_iter((_RopeLeaf*)__left, + ((_RopeLeaf*)__right)->_M_data, + __right->_M_size); } - } else if (RopeBase::concat == left -> tag - && RopeBase::leaf == - ((RopeConcatenation *)left) -> right -> tag) { - RopeLeaf * leftright = - (RopeLeaf *)(((RopeConcatenation *)left) -> right); - if (leftright -> size + right -> size <= copy_max) { - RopeBase * leftleft = ((RopeConcatenation *)left) -> left; - RopeBase * rest = leaf_concat_char_iter(leftright, - ((RopeLeaf *)right) -> data, - right -> size); - leftleft -> ref_nonnil(); + } else if (_RopeRep::_S_concat == __left->_M_tag + && _RopeRep::_S_leaf == + ((_RopeConcatenation*)__left)->_M_right->_M_tag) { + _RopeLeaf* __leftright = + (_RopeLeaf*)(((_RopeConcatenation*)__left)->_M_right); + if (__leftright->_M_size + __right->_M_size <= _S_copy_max) { + _RopeRep* __leftleft = ((_RopeConcatenation*)__left)->_M_left; + _RopeRep* __rest = _S_leaf_concat_char_iter(__leftright, + ((_RopeLeaf*)__right)->_M_data, + __right->_M_size); + __leftleft->_M_ref_nonnil(); __STL_TRY { - return(tree_concat(leftleft, rest)); + return(_S_tree_concat(__leftleft, __rest)); } - __STL_UNWIND(unref(leftleft); unref(rest)) + __STL_UNWIND(_S_unref(__leftleft); _S_unref(__rest)) } } } - left -> ref_nonnil(); - right -> ref_nonnil(); + __left->_M_ref_nonnil(); + __right->_M_ref_nonnil(); __STL_TRY { - return(tree_concat(left, right)); + return(_S_tree_concat(__left, __right)); } - __STL_UNWIND(unref(left); unref(right)); + __STL_UNWIND(_S_unref(__left); _S_unref(__right)); } -template <class charT, class Alloc> -rope<charT,Alloc>::RopeBase * -rope<charT,Alloc>::substring(RopeBase * base, size_t start, size_t endp1) +template <class _CharT, class _Alloc> +rope<_CharT,_Alloc>::_RopeRep* +rope<_CharT,_Alloc>::_S_substring(_RopeRep* __base, + size_t __start, size_t __endp1) { - if (0 == base) return 0; - size_t len = base -> size; - size_t adj_endp1; - const size_t lazy_threshold = 128; + if (0 == __base) return 0; + size_t __len = __base->_M_size; + size_t __adj_endp1; + const size_t __lazy_threshold = 128; - if (endp1 >= len) { - if (0 == start) { - base -> ref_nonnil(); - return base; + if (__endp1 >= __len) { + if (0 == __start) { + __base->_M_ref_nonnil(); + return __base; } else { - adj_endp1 = len; + __adj_endp1 = __len; } } else { - adj_endp1 = endp1; + __adj_endp1 = __endp1; } - switch(base -> tag) { - case RopeBase::concat: + switch(__base->_M_tag) { + case _RopeRep::_S_concat: { - RopeConcatenation *c = (RopeConcatenation *)base; - RopeBase *left = c -> left; - RopeBase *right = c -> right; - size_t left_len = left -> size; - RopeBase * result; - - if (adj_endp1 <= left_len) { - return substring(left, start, endp1); - } else if (start >= left_len) { - return substring(right, start - left_len, - adj_endp1 - left_len); + _RopeConcatenation* __c = (_RopeConcatenation*)__base; + _RopeRep* __left = __c->_M_left; + _RopeRep* __right = __c->_M_right; + size_t __left_len = __left->_M_size; + _RopeRep* __result; + + if (__adj_endp1 <= __left_len) { + return _S_substring(__left, __start, __endp1); + } else if (__start >= __left_len) { + return _S_substring(__right, __start - __left_len, + __adj_endp1 - __left_len); } - self_destruct_ptr left_result(substring(left, start, - left_len)); - self_destruct_ptr right_result( - substring(right, 0, endp1 - left_len)); - result = concat(left_result, right_result); + _Self_destruct_ptr __left_result( + _S_substring(__left, __start, __left_len)); + _Self_destruct_ptr __right_result( + _S_substring(__right, 0, __endp1 - __left_len)); + __result = _S_concat(__left_result, __right_result); # ifndef __GC - __stl_assert(1 == result -> refcount); + __stl_assert(1 == __result->_M_refcount); # endif - return result; + return __result; } - case RopeBase::leaf: + case _RopeRep::_S_leaf: { - RopeLeaf * l = (RopeLeaf *)base; - RopeLeaf * result; - size_t result_len; - if (start >= adj_endp1) return 0; - result_len = adj_endp1 - start; - if (result_len > lazy_threshold) goto lazy; + _RopeLeaf* __l = (_RopeLeaf*)__base; + _RopeLeaf* __result; + size_t __result_len; + if (__start >= __adj_endp1) return 0; + __result_len = __adj_endp1 - __start; + if (__result_len > __lazy_threshold) goto lazy; # ifdef __GC - const charT *section = l -> data + start; - result = RopeLeaf_from_char_ptr(section, result_len); - result -> c_string = 0; // Not eos terminated. + const _CharT* __section = __l->_M_data + __start; + __result = _S_new_RopeLeaf(__section, __result_len, + __base->get_allocator()); + __result->_M_c_string = 0; // Not eos terminated. # else // We should sometimes create substring node instead. - result = RopeLeaf_from_unowned_char_ptr( - l -> data + start, result_len); + __result = __STL_ROPE_FROM_UNOWNED_CHAR_PTR( + __l->_M_data + __start, __result_len, + __base->get_allocator()); # endif - return result; + return __result; } - case RopeBase::substringfn: - // Avoid introducing mutiple layers of substring nodes. + case _RopeRep::_S_substringfn: + // Avoid introducing multiple layers of substring nodes. { - RopeSubstring *old = (RopeSubstring *)base; - size_t result_len; - if (start >= adj_endp1) return 0; - result_len = adj_endp1 - start; - if (result_len > lazy_threshold) { - RopeSubstring * space = SAlloc::allocate(); - RopeSubstring * result = - new(space) RopeSubstring(old -> base, - start + old -> start, - adj_endp1 - start); - return result; - } // else fall through: + _RopeSubstring* __old = (_RopeSubstring*)__base; + size_t __result_len; + if (__start >= __adj_endp1) return 0; + __result_len = __adj_endp1 - __start; + if (__result_len > __lazy_threshold) { + _RopeSubstring* __result = + _S_new_RopeSubstring(__old->_M_base, + __start + __old->_M_start, + __adj_endp1 - __start, + __base->get_allocator()); + return __result; + + } // *** else fall through: *** } - case RopeBase::function: + case _RopeRep::_S_function: { - RopeFunction * f = (RopeFunction *)base; - charT *section; - size_t result_len; - if (start >= adj_endp1) return 0; - result_len = adj_endp1 - start; - - if (result_len > lazy_threshold) goto lazy; - section = (charT *) - DataAlloc::allocate(rounded_up_size(result_len)); + _RopeFunction* __f = (_RopeFunction*)__base; + _CharT* __section; + size_t __result_len; + if (__start >= __adj_endp1) return 0; + __result_len = __adj_endp1 - __start; + + if (__result_len > __lazy_threshold) goto lazy; + __section = (_CharT*) + _Data_allocate(_S_rounded_up_size(__result_len)); __STL_TRY { - (*(f -> fn))(start, result_len, section); + (*(__f->_M_fn))(__start, __result_len, __section); } - __STL_UNWIND(RopeBase::free_string(section, result_len)); - __cond_store_eos(section[result_len]); - return RopeLeaf_from_char_ptr(section, result_len); + __STL_UNWIND(_RopeRep::__STL_FREE_STRING( + __section, __result_len, __base->get_allocator())); + _S_cond_store_eos(__section[__result_len]); + return _S_new_RopeLeaf(__section, __result_len, + __base->get_allocator()); } } /*NOTREACHED*/ @@ -762,141 +740,146 @@ rope<charT,Alloc>::substring(RopeBase * base, size_t start, size_t endp1) lazy: { // Create substring node. - RopeSubstring * space = SAlloc::allocate(); - RopeSubstring * result = new(space) RopeSubstring(base, start, - adj_endp1 - start); - return result; + return _S_new_RopeSubstring(__base, __start, __adj_endp1 - __start, + __base->get_allocator()); } } -template<class charT> -class __rope_flatten_char_consumer : public __rope_char_consumer<charT> { +template<class _CharT> +class _Rope_flatten_char_consumer : public _Rope_char_consumer<_CharT> { private: - charT * buf_ptr; + _CharT* _M_buf_ptr; public: - charT * buffer; - __rope_flatten_char_consumer(charT * buffer) { - buf_ptr = buffer; + // _CharT* _M_buffer; // XXX not used + + _Rope_flatten_char_consumer(_CharT* __buffer) { + _M_buf_ptr = __buffer; }; - ~__rope_flatten_char_consumer() {} - bool operator() (const charT* leaf, size_t n) { - uninitialized_copy_n(leaf, n, buf_ptr); - buf_ptr += n; + ~_Rope_flatten_char_consumer() {} + bool operator() (const _CharT* __leaf, size_t __n) { + uninitialized_copy_n(__leaf, __n, _M_buf_ptr); + _M_buf_ptr += __n; return true; } }; -template<class charT> -class __rope_find_char_char_consumer : public __rope_char_consumer<charT> { +template<class _CharT> +class _Rope_find_char_char_consumer : public _Rope_char_consumer<_CharT> { private: - charT pattern; + _CharT _M_pattern; public: - size_t count; // Number of nonmatching characters - __rope_find_char_char_consumer(charT p) : pattern(p), count(0) {} - ~__rope_find_char_char_consumer() {} - bool operator() (const charT* leaf, size_t n) { - size_t i; - for (i = 0; i < n; i++) { - if (leaf[i] == pattern) { - count += i; return false; + size_t _M_count; // Number of nonmatching characters + _Rope_find_char_char_consumer(_CharT __p) + : _M_pattern(__p), _M_count(0) {} + ~_Rope_find_char_char_consumer() {} + bool operator() (const _CharT* __leaf, size_t __n) { + size_t __i; + for (__i = 0; __i < __n; __i++) { + if (__leaf[__i] == _M_pattern) { + _M_count += __i; return false; } } - count += n; return true; + _M_count += __n; return true; } }; -template<class charT> -class __rope_insert_char_consumer : public __rope_char_consumer<charT> { +template<class _CharT> +class _Rope_insert_char_consumer : public _Rope_char_consumer<_CharT> { private: - typedef ostream insert_ostream; - insert_ostream & o; + typedef ostream _Insert_ostream; + _Insert_ostream& _M_o; public: - charT * buffer; - __rope_insert_char_consumer(insert_ostream & writer) : o(writer) {}; - ~__rope_insert_char_consumer() { }; + // _CharT* buffer; // XXX not used + _Rope_insert_char_consumer(_Insert_ostream& __writer) + : _M_o(__writer) {}; + ~_Rope_insert_char_consumer() { }; // Caller is presumed to own the ostream - bool operator() (const charT* leaf, size_t n); + bool operator() (const _CharT* __leaf, size_t __n); // Returns true to continue traversal. }; -template<class charT> -bool __rope_insert_char_consumer<charT>::operator() - (const charT * leaf, size_t n) +template<class _CharT> +bool _Rope_insert_char_consumer<_CharT>::operator() + (const _CharT* __leaf, size_t __n) { - size_t i; + size_t __i; // We assume that formatting is set up correctly for each element. - for (i = 0; i < n; i++) o << leaf[i]; + for (__i = 0; __i < __n; __i++) _M_o << __leaf[__i]; return true; } -inline bool __rope_insert_char_consumer<char>::operator() - (const char * leaf, size_t n) +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]); + size_t __i; + for (__i = 0; __i < __n; __i++) _M_o.put(__leaf[__i]); return true; } -#if !defined(_MSC_VER) && !defined(__BORLANDC__) -// I couldn't get this to work with the VC++ version of basic_ostream. -inline bool __rope_insert_char_consumer<wchar_t>::operator() - (const wchar_t * leaf, size_t n) +#if 0 +// I couldn't get this to work work with the VC++ version of basic_ostream. +// It also doesn't really do the right thing unless o is a wide stream. +// Given that wchar_t is often 4 bytes, its not clear to me how useful +// this stuff is anyway. +inline bool _Rope_insert_char_consumer<wchar_t>::operator() + (const wchar_t* __leaf, size_t __n) { - size_t i; - for (i = 0; i < n; i++) o.put(leaf[i]); + size_t __i; + for (__i = 0; __i < __n; __i++) _M_o.put(__leaf[__i]); return true; } #endif /* !_MSC_VER && !BORLAND */ -template <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) +template <class _CharT, class _Alloc> +bool rope<_CharT, _Alloc>::_S_apply_to_pieces( + _Rope_char_consumer<_CharT>& __c, + const _RopeRep* __r, + size_t __begin, size_t __end) { - if (0 == r) return true; - switch(r -> tag) { - case RopeBase::concat: + if (0 == __r) return true; + switch(__r->_M_tag) { + case _RopeRep::_S_concat: { - RopeConcatenation *conc = (RopeConcatenation *)r; - RopeBase *left = conc -> left; - size_t left_len = left -> size; - if (begin < left_len) { - size_t left_end = min(left_len, end); - if (!apply_to_pieces(c, left, begin, left_end)) { + _RopeConcatenation* __conc = (_RopeConcatenation*)__r; + _RopeRep* __left = __conc->_M_left; + size_t __left_len = __left->_M_size; + if (__begin < __left_len) { + size_t __left_end = min(__left_len, __end); + if (!_S_apply_to_pieces(__c, __left, __begin, __left_end)) return false; - } } - if (end > left_len) { - RopeBase *right = conc -> right; - size_t right_start = max(left_len, begin); - if (!apply_to_pieces(c, right, - right_start - left_len, - end - left_len)) { + if (__end > __left_len) { + _RopeRep* __right = __conc->_M_right; + size_t __right_start = max(__left_len, __begin); + if (!_S_apply_to_pieces(__c, __right, + __right_start - __left_len, + __end - __left_len)) { return false; } } } return true; - case RopeBase::leaf: + case _RopeRep::_S_leaf: { - RopeLeaf * l = (RopeLeaf *)r; - return c(l -> data + begin, end - begin); + _RopeLeaf* __l = (_RopeLeaf*)__r; + return __c(__l->_M_data + __begin, __end - __begin); } - case RopeBase::function: - case RopeBase::substringfn: + case _RopeRep::_S_function: + case _RopeRep::_S_substringfn: { - RopeFunction * f = (RopeFunction *)r; - size_t len = end - begin; - bool result; - charT * buffer = DataAlloc::allocate(len); + _RopeFunction* __f = (_RopeFunction*)__r; + size_t __len = __end - __begin; + bool __result; + _CharT* __buffer = + (_CharT*)alloc::allocate(__len * sizeof(_CharT)); __STL_TRY { - (*(f -> fn))(begin, end, buffer); - result = c(buffer, len); - DataAlloc::deallocate(buffer, len); + (*(__f->_M_fn))(__begin, __end, __buffer); + __result = __c(__buffer, __len); + alloc::deallocate(__buffer, __len * sizeof(_CharT)); } - __STL_UNWIND(DataAlloc::deallocate(buffer, len)) - return result; + __STL_UNWIND((alloc::deallocate(__buffer, + __len * sizeof(_CharT)))) + return __result; } default: __stl_assert(false); @@ -905,98 +888,102 @@ bool rope<charT, Alloc>::apply_to_pieces( } } -inline void __rope_fill(ostream& o, size_t n) +inline void _Rope_fill(ostream& __o, size_t __n) { - char f = o.fill(); - size_t i; + char __f = __o.fill(); + size_t __i; - for (i = 0; i < n; i++) o.put(f); + for (__i = 0; __i < __n; __i++) __o.put(__f); } -template <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> 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) +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); + size_t __w = __o.width(); + bool __left = bool(__o.flags() & ios::left); + size_t __pad_len; + size_t __rope_len = __r.size(); + _Rope_insert_char_consumer<_CharT> __c(__o); + bool __is_simple = _Rope_is_simple((_CharT*)0); - if (rope_len < w) { - pad_len = w - rope_len; + if (__rope_len < __w) { + __pad_len = __w - __rope_len; } else { - pad_len = 0; + __pad_len = 0; } - if (!is_simple) o.width(w/rope_len); + if (!__is_simple) __o.width(__w/__rope_len); __STL_TRY { - if (is_simple && !left && pad_len > 0) { - __rope_fill(o, pad_len); + if (__is_simple && !__left && __pad_len > 0) { + _Rope_fill(__o, __pad_len); } - r.apply_to_pieces(0, r.size(), c); - if (is_simple && left && pad_len > 0) { - __rope_fill(o, pad_len); + __r.apply_to_pieces(0, __r.size(), __c); + if (__is_simple && __left && __pad_len > 0) { + _Rope_fill(__o, __pad_len); } - if (!is_simple) - o.width(w); + if (!__is_simple) + __o.width(__w); } - __STL_UNWIND(if (!is_simple) o.width(w)) - return o; + __STL_UNWIND(if (!__is_simple) __o.width(__w)) + return __o; } -template <class charT, class Alloc> -charT * -rope<charT,Alloc>::flatten(RopeBase * r, - size_t start, size_t len, - charT * buffer) +template <class _CharT, class _Alloc> +_CharT* +rope<_CharT,_Alloc>::_S_flatten(_RopeRep* __r, + size_t __start, size_t __len, + _CharT* __buffer) { - __rope_flatten_char_consumer<charT> c(buffer); - apply_to_pieces(c, r, start, start + len); - return(buffer + len); + _Rope_flatten_char_consumer<_CharT> __c(__buffer); + _S_apply_to_pieces(__c, __r, __start, __start + __len); + return(__buffer + __len); } -template <class charT, class Alloc> +template <class _CharT, class _Alloc> size_t -rope<charT,Alloc>::find(charT pattern, size_t start) const +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; + _Rope_find_char_char_consumer<_CharT> __c(__pattern); + _S_apply_to_pieces(__c, _M_tree_ptr, __start, size()); + size_type __result_pos = __start + __c._M_count; +# ifndef __STL_OLD_ROPE_SEMANTICS + if (__result_pos == size()) __result_pos = npos; +# endif + return __result_pos; } -template <class charT, class Alloc> -charT * -rope<charT,Alloc>::flatten(RopeBase * r, charT * buffer) +template <class _CharT, class _Alloc> +_CharT* +rope<_CharT,_Alloc>::_S_flatten(_RopeRep* __r, _CharT* __buffer) { - if (0 == r) return buffer; - switch(r -> tag) { - case RopeBase::concat: + if (0 == __r) return __buffer; + switch(__r->_M_tag) { + case _RopeRep::_S_concat: { - RopeConcatenation *c = (RopeConcatenation *)r; - RopeBase *left = c -> left; - RopeBase *right = c -> right; - charT * rest = flatten(left, buffer); - return flatten(right, rest); + _RopeConcatenation* __c = (_RopeConcatenation*)__r; + _RopeRep* __left = __c->_M_left; + _RopeRep* __right = __c->_M_right; + _CharT* __rest = _S_flatten(__left, __buffer); + return _S_flatten(__right, __rest); } - case RopeBase::leaf: + case _RopeRep::_S_leaf: { - RopeLeaf * l = (RopeLeaf *)r; - return copy_n(l -> data, l -> size, buffer).second; + _RopeLeaf* __l = (_RopeLeaf*)__r; + return copy_n(__l->_M_data, __l->_M_size, __buffer).second; } - case RopeBase::function: - case RopeBase::substringfn: + case _RopeRep::_S_function: + case _RopeRep::_S_substringfn: // We dont yet do anything with substring nodes. // This needs to be fixed before ropefiles will work well. { - RopeFunction * f = (RopeFunction *)r; - (*(f -> fn))(0, f -> size, buffer); - return buffer + f -> size; + _RopeFunction* __f = (_RopeFunction*)__r; + (*(__f->_M_fn))(0, __f->_M_size, __buffer); + return __buffer + __f->_M_size; } default: __stl_assert(false); @@ -1006,72 +993,75 @@ rope<charT,Alloc>::flatten(RopeBase * r, charT * buffer) } -// This needs work for charT != char -template <class charT, class Alloc> +// This needs work for _CharT != char +template <class _CharT, class _Alloc> void -rope<charT,Alloc>::dump(RopeBase * r, int indent) +rope<_CharT,_Alloc>::_S_dump(_RopeRep* __r, int __indent) { - for (int i = 0; i < indent; i++) putchar(' '); - if (0 == r) { + for (int __i = 0; __i < __indent; __i++) putchar(' '); + if (0 == __r) { printf("NULL\n"); return; } - if (RopeBase::concat == r -> tag) { - RopeConcatenation *c = (RopeConcatenation *)r; - RopeBase *left = c -> left; - RopeBase *right = c -> right; + if (_RopeRep::_S_concat == __r->_M_tag) { + _RopeConcatenation* __c = (_RopeConcatenation*)__r; + _RopeRep* __left = __c->_M_left; + _RopeRep* __right = __c->_M_right; # ifdef __GC printf("Concatenation %p (depth = %d, len = %ld, %s balanced)\n", - r, r -> depth, r -> size, r -> is_balanced? "" : "not"); + __r, __r->_M_depth, __r->_M_size, __r->_M_is_balanced? "" : "not"); # else - printf("Concatenation %p (rc = %ld, depth = %d, len = %ld, %s balanced)\n", - r, r -> refcount, r -> depth, r -> size, - r -> is_balanced? "" : "not"); + printf("Concatenation %p (rc = %ld, depth = %d, " + "len = %ld, %s balanced)\n", + __r, __r->_M_refcount, __r->_M_depth, __r->_M_size, + __r->_M_is_balanced? "" : "not"); # endif - dump(left, indent + 2); - dump(right, indent + 2); + _S_dump(__left, __indent + 2); + _S_dump(__right, __indent + 2); return; } else { - char * kind; + char* __kind; - switch (r -> tag) { - case RopeBase::leaf: - kind = "Leaf"; + switch (__r->_M_tag) { + case _RopeRep::_S_leaf: + __kind = "Leaf"; break; - case RopeBase::function: - kind = "Function"; + case _RopeRep::_S_function: + __kind = "Function"; break; - case RopeBase::substringfn: - kind = "Function representing substring"; + case _RopeRep::_S_substringfn: + __kind = "Function representing substring"; break; default: - kind = "(corrupted kind field!)"; + __kind = "(corrupted kind field!)"; } # ifdef __GC printf("%s %p (depth = %d, len = %ld) ", - kind, r, r -> depth, r -> size); + __kind, __r, __r->_M_depth, __r->_M_size); # else printf("%s %p (rc = %ld, depth = %d, len = %ld) ", - kind, r, r -> refcount, r -> depth, r -> size); + __kind, __r, __r->_M_refcount, __r->_M_depth, __r->_M_size); # endif - if (__is_one_byte_char_type((charT *)0)) { - const int max_len = 40; - self_destruct_ptr prefix(substring(r, 0, max_len)); - charT buffer[max_len + 1]; - bool too_big = r -> size > prefix-> size; - - flatten(prefix, buffer); - buffer[prefix -> size] = __eos((charT *)0); - printf("%s%s\n", (char *)buffer, too_big? "...\n" : "\n"); + if (_S_is_one_byte_char_type((_CharT*)0)) { + const int __max_len = 40; + _Self_destruct_ptr __prefix(_S_substring(__r, 0, __max_len)); + _CharT __buffer[__max_len + 1]; + bool __too_big = __r->_M_size > __prefix->_M_size; + + _S_flatten(__prefix, __buffer); + __buffer[__prefix->_M_size] = _S_eos((_CharT*)0); + printf("%s%s\n", + (char*)__buffer, __too_big? "...\n" : "\n"); } else { printf("\n"); } } } -template <class charT, class Alloc> +template <class _CharT, class _Alloc> const unsigned long -rope<charT,Alloc>::min_len[__rope_RopeBase<charT,Alloc>::max_rope_depth + 1] = { +rope<_CharT,_Alloc>::_S_min_len[ + _Rope_RopeRep<_CharT,_Alloc>::_S_max_rope_depth + 1] = { /* 0 */1, /* 1 */2, /* 2 */3, /* 3 */5, /* 4 */8, /* 5 */13, /* 6 */21, /* 7 */34, /* 8 */55, /* 9 */89, /* 10 */144, /* 11 */233, /* 12 */377, /* 13 */610, /* 14 */987, /* 15 */1597, /* 16 */2584, /* 17 */4181, @@ -1082,148 +1072,150 @@ rope<charT,Alloc>::min_len[__rope_RopeBase<charT,Alloc>::max_rope_depth + 1] = { /* 35 */24157817, /* 36 */39088169, /* 37 */63245986, /* 38 */102334155, /* 39 */165580141, /* 40 */267914296, /* 41 */433494437, /* 42 */701408733, /* 43 */1134903170, /* 44 */1836311903, -/* 45 */2971215073 }; +/* 45 */2971215073u }; // These are Fibonacci numbers < 2**32. -template <class charT, class Alloc> -rope<charT,Alloc>::RopeBase * -rope<charT,Alloc>::balance(RopeBase *r) +template <class _CharT, class _Alloc> +rope<_CharT,_Alloc>::_RopeRep* +rope<_CharT,_Alloc>::_S_balance(_RopeRep* __r) { - RopeBase * forest[RopeBase::max_rope_depth + 1]; - RopeBase * result = 0; - int i; - // Inariant: - // The concatenation of forest in descending order is equal to r. - // forest[i].size >= min_len[i] - // forest[i].depth = i + _RopeRep* __forest[_RopeRep::_S_max_rope_depth + 1]; + _RopeRep* __result = 0; + int __i; + // Invariant: + // The concatenation of forest in descending order is equal to __r. + // __forest[__i]._M_size >= _S_min_len[__i] + // __forest[__i]._M_depth = __i // References from forest are included in refcount. - for (i = 0; i <= RopeBase::max_rope_depth; ++i) forest[i] = 0; + for (__i = 0; __i <= _RopeRep::_S_max_rope_depth; ++__i) + __forest[__i] = 0; __STL_TRY { - add_to_forest(r, forest); - for (i = 0; i <= RopeBase::max_rope_depth; ++i) if (0 != forest[i]) { + _S_add_to_forest(__r, __forest); + for (__i = 0; __i <= _RopeRep::_S_max_rope_depth; ++__i) + if (0 != __forest[__i]) { # ifndef __GC - self_destruct_ptr old(result); + _Self_destruct_ptr __old(__result); # endif - result = concat(forest[i], result); - forest[i] -> unref_nonnil(); + __result = _S_concat(__forest[__i], __result); + __forest[__i]->_M_unref_nonnil(); # if !defined(__GC) && defined(__STL_USE_EXCEPTIONS) - forest[i] = 0; + __forest[__i] = 0; # endif } } - __STL_UNWIND(for(i = 0; i <= RopeBase::max_rope_depth; i++) - unref(forest[i])) - if (result -> depth > RopeBase::max_rope_depth) abort(); - return(result); + __STL_UNWIND(for(__i = 0; __i <= _RopeRep::_S_max_rope_depth; __i++) + _S_unref(__forest[__i])) + if (__result->_M_depth > _RopeRep::_S_max_rope_depth) abort(); + return(__result); } -template <class charT, class Alloc> +template <class _CharT, class _Alloc> void -rope<charT,Alloc>::add_to_forest(RopeBase *r, RopeBase **forest) +rope<_CharT,_Alloc>::_S_add_to_forest(_RopeRep* __r, _RopeRep** __forest) { - if (r -> is_balanced) { - add_leaf_to_forest(r, forest); + if (__r->_M_is_balanced) { + _S_add_leaf_to_forest(__r, __forest); return; } - __stl_assert(r -> tag == RopeBase::concat); + __stl_assert(__r->_M_tag == _RopeRep::_S_concat); { - RopeConcatenation *c = (RopeConcatenation *)r; + _RopeConcatenation* __c = (_RopeConcatenation*)__r; - add_to_forest(c -> left, forest); - add_to_forest(c -> right, forest); + _S_add_to_forest(__c->_M_left, __forest); + _S_add_to_forest(__c->_M_right, __forest); } } -template <class charT, class Alloc> +template <class _CharT, class _Alloc> void -rope<charT,Alloc>::add_leaf_to_forest(RopeBase *r, RopeBase **forest) +rope<_CharT,_Alloc>::_S_add_leaf_to_forest(_RopeRep* __r, _RopeRep** __forest) { - RopeBase * insertee; // included in refcount - RopeBase * too_tiny = 0; // included in refcount - int i; // forest[0..i-1] is empty - size_t s = r -> size; + _RopeRep* __insertee; // included in refcount + _RopeRep* __too_tiny = 0; // included in refcount + int __i; // forest[0..__i-1] is empty + size_t __s = __r->_M_size; - for (i = 0; s >= min_len[i+1]/* not this bucket */; ++i) { - if (0 != forest[i]) { + for (__i = 0; __s >= _S_min_len[__i+1]/* not this bucket */; ++__i) { + if (0 != __forest[__i]) { # ifndef __GC - self_destruct_ptr old(too_tiny); + _Self_destruct_ptr __old(__too_tiny); # endif - too_tiny = concat_and_set_balanced(forest[i], too_tiny); - forest[i] -> unref_nonnil(); - forest[i] = 0; + __too_tiny = _S_concat_and_set_balanced(__forest[__i], __too_tiny); + __forest[__i]->_M_unref_nonnil(); + __forest[__i] = 0; } } { # ifndef __GC - self_destruct_ptr old(too_tiny); + _Self_destruct_ptr __old(__too_tiny); # endif - insertee = concat_and_set_balanced(too_tiny, r); + __insertee = _S_concat_and_set_balanced(__too_tiny, __r); } // Too_tiny dead, and no longer included in refcount. // Insertee is live and included. - __stl_assert(is_almost_balanced(insertee)); - __stl_assert(insertee -> depth <= r -> depth + 1); - for (;; ++i) { - if (0 != forest[i]) { + __stl_assert(_S_is_almost_balanced(__insertee)); + __stl_assert(__insertee->_M_depth <= __r->_M_depth + 1); + for (;; ++__i) { + if (0 != __forest[__i]) { # ifndef __GC - self_destruct_ptr old(insertee); + _Self_destruct_ptr __old(__insertee); # endif - insertee = concat_and_set_balanced(forest[i], insertee); - forest[i] -> unref_nonnil(); - forest[i] = 0; - __stl_assert(is_almost_balanced(insertee)); + __insertee = _S_concat_and_set_balanced(__forest[__i], __insertee); + __forest[__i]->_M_unref_nonnil(); + __forest[__i] = 0; + __stl_assert(_S_is_almost_balanced(__insertee)); } - __stl_assert(min_len[i] <= insertee -> size); - __stl_assert(forest[i] == 0); - if (i == RopeBase::max_rope_depth - || insertee -> size < min_len[i+1]) { - forest[i] = insertee; - // refcount is OK since insertee is now dead. + __stl_assert(_S_min_len[__i] <= __insertee->_M_size); + __stl_assert(__forest[__i] == 0); + if (__i == _RopeRep::_S_max_rope_depth || + __insertee->_M_size < _S_min_len[__i+1]) { + __forest[__i] = __insertee; + // refcount is OK since __insertee is now dead. return; } } } -template <class charT, class Alloc> -charT -rope<charT,Alloc>::fetch(RopeBase *r, size_type i) +template <class _CharT, class _Alloc> +_CharT +rope<_CharT,_Alloc>::_S_fetch(_RopeRep* __r, size_type __i) { - __GC_CONST charT * cstr = r -> c_string; + __GC_CONST _CharT* __cstr = __r->_M_c_string; - __stl_assert(i < r -> size); - if (0 != cstr) return cstr[i]; + __stl_assert(__i < __r->_M_size); + if (0 != __cstr) return __cstr[__i]; for(;;) { - switch(r -> tag) { - case RopeBase::concat: + switch(__r->_M_tag) { + case _RopeRep::_S_concat: { - RopeConcatenation *c = (RopeConcatenation *)r; - RopeBase *left = c -> left; - size_t left_len = left -> size; + _RopeConcatenation* __c = (_RopeConcatenation*)__r; + _RopeRep* __left = __c->_M_left; + size_t __left_len = __left->_M_size; - if (i >= left_len) { - i -= left_len; - r = c -> right; + if (__i >= __left_len) { + __i -= __left_len; + __r = __c->_M_right; } else { - r = left; + __r = __left; } } break; - case RopeBase::leaf: + case _RopeRep::_S_leaf: { - RopeLeaf * l = (RopeLeaf *)r; - return l -> data[i]; + _RopeLeaf* __l = (_RopeLeaf*)__r; + return __l->_M_data[__i]; } - case RopeBase::function: - case RopeBase::substringfn: + case _RopeRep::_S_function: + case _RopeRep::_S_substringfn: { - RopeFunction * f = (RopeFunction *)r; - charT result; + _RopeFunction* __f = (_RopeFunction*)__r; + _CharT __result; - (*(f -> fn))(i, 1, &result); - return result; + (*(__f->_M_fn))(__i, 1, &__result); + return __result; } } } @@ -1232,46 +1224,46 @@ rope<charT,Alloc>::fetch(RopeBase *r, size_type i) # ifndef __GC // Return a uniquely referenced character slot for the given // position, or 0 if that's not possible. -template <class charT, class Alloc> -charT* -rope<charT,Alloc>::fetch_ptr(RopeBase *r, size_type i) +template <class _CharT, class _Alloc> +_CharT* +rope<_CharT,_Alloc>::_S_fetch_ptr(_RopeRep* __r, size_type __i) { - RopeBase * clrstack[RopeBase::max_rope_depth]; - size_t csptr = 0; + _RopeRep* __clrstack[_RopeRep::_S_max_rope_depth]; + size_t __csptr = 0; for(;;) { - if (r -> refcount > 1) return 0; - switch(r -> tag) { - case RopeBase::concat: + if (__r->_M_refcount > 1) return 0; + switch(__r->_M_tag) { + case _RopeRep::_S_concat: { - RopeConcatenation *c = (RopeConcatenation *)r; - RopeBase *left = c -> left; - size_t left_len = left -> size; - - if (c -> c_string != 0) clrstack[csptr++] = c; - if (i >= left_len) { - i -= left_len; - r = c -> right; + _RopeConcatenation* __c = (_RopeConcatenation*)__r; + _RopeRep* __left = __c->_M_left; + size_t __left_len = __left->_M_size; + + if (__c->_M_c_string != 0) __clrstack[__csptr++] = __c; + if (__i >= __left_len) { + __i -= __left_len; + __r = __c->_M_right; } else { - r = left; + __r = __left; } } break; - case RopeBase::leaf: + case _RopeRep::_S_leaf: { - RopeLeaf * l = (RopeLeaf *)r; - if (l -> c_string != l -> data && l -> c_string != 0) - clrstack[csptr++] = l; - while (csptr > 0) { - -- csptr; - RopeBase * d = clrstack[csptr]; - d -> free_c_string(); - d -> c_string = 0; + _RopeLeaf* __l = (_RopeLeaf*)__r; + if (__l->_M_c_string != __l->_M_data && __l->_M_c_string != 0) + __clrstack[__csptr++] = __l; + while (__csptr > 0) { + -- __csptr; + _RopeRep* __d = __clrstack[__csptr]; + __d->_M_free_c_string(); + __d->_M_c_string = 0; } - return l -> data + i; + return __l->_M_data + __i; } - case RopeBase::function: - case RopeBase::substringfn: + case _RopeRep::_S_function: + case _RopeRep::_S_substringfn: return 0; } } @@ -1282,233 +1274,253 @@ rope<charT,Alloc>::fetch_ptr(RopeBase *r, size_type i) // lexicographical_compare_3way. // We do a little more work to avoid dealing with rope iterators for // flat strings. -template <class charT, class Alloc> +template <class _CharT, class _Alloc> int -rope<charT,Alloc>::compare (const RopeBase *left, const RopeBase *right) +rope<_CharT,_Alloc>::_S_compare (const _RopeRep* __left, + const _RopeRep* __right) { - size_t left_len; - size_t right_len; - - if (0 == right) return 0 != left; - if (0 == left) return -1; - left_len = left -> size; - right_len = right -> size; - if (RopeBase::leaf == left -> tag) { - RopeLeaf *l = (RopeLeaf *) left; - if (RopeBase::leaf == right -> tag) { - RopeLeaf *r = (RopeLeaf *) right; + size_t __left_len; + size_t __right_len; + + if (0 == __right) return 0 != __left; + if (0 == __left) return -1; + __left_len = __left->_M_size; + __right_len = __right->_M_size; + if (_RopeRep::_S_leaf == __left->_M_tag) { + _RopeLeaf* __l = (_RopeLeaf*) __left; + if (_RopeRep::_S_leaf == __right->_M_tag) { + _RopeLeaf* __r = (_RopeLeaf*) __right; return lexicographical_compare_3way( - l -> data, l -> data + left_len, - r -> data, r -> data + right_len); + __l->_M_data, __l->_M_data + __left_len, + __r->_M_data, __r->_M_data + __right_len); } else { - const_iterator rstart(right, 0); - const_iterator rend(right, right_len); + const_iterator __rstart(__right, 0); + const_iterator __rend(__right, __right_len); return lexicographical_compare_3way( - l -> data, l -> data + left_len, - rstart, rend); + __l->_M_data, __l->_M_data + __left_len, + __rstart, __rend); } } else { - const_iterator lstart(left, 0); - const_iterator lend(left, left_len); - if (RopeBase::leaf == right -> tag) { - RopeLeaf *r = (RopeLeaf *) right; + const_iterator __lstart(__left, 0); + const_iterator __lend(__left, __left_len); + if (_RopeRep::_S_leaf == __right->_M_tag) { + _RopeLeaf* __r = (_RopeLeaf*) __right; return lexicographical_compare_3way( - lstart, lend, - r -> data, r -> data + right_len); + __lstart, __lend, + __r->_M_data, __r->_M_data + __right_len); } else { - const_iterator rstart(right, 0); - const_iterator rend(right, right_len); + const_iterator __rstart(__right, 0); + const_iterator __rend(__right, __right_len); return lexicographical_compare_3way( - lstart, lend, - rstart, rend); + __lstart, __lend, + __rstart, __rend); } } } // Assignment to reference proxies. -template <class charT, class Alloc> -__rope_charT_ref_proxy<charT, Alloc>& -__rope_charT_ref_proxy<charT, Alloc>::operator= (charT c) { - RopeBase * old = root -> tree_ptr; +template <class _CharT, class _Alloc> +_Rope_char_ref_proxy<_CharT, _Alloc>& +_Rope_char_ref_proxy<_CharT, _Alloc>::operator= (_CharT __c) { + _RopeRep* __old = _M_root->_M_tree_ptr; # ifndef __GC // First check for the case in which everything is uniquely // referenced. In that case we can do this destructively. - charT * charT_ptr = my_rope::fetch_ptr(old, pos); - if (0 != charT_ptr) { - *charT_ptr = c; + _CharT* __ptr = _My_rope::_S_fetch_ptr(__old, _M_pos); + if (0 != __ptr) { + *__ptr = __c; return *this; } # endif - self_destruct_ptr left(my_rope::substring(old, 0, pos)); - self_destruct_ptr right(my_rope::substring(old, pos+1, old -> size)); - self_destruct_ptr result_left(my_rope::destr_concat_char_iter(left, &c, 1)); + _Self_destruct_ptr __left( + _My_rope::_S_substring(__old, 0, _M_pos)); + _Self_destruct_ptr __right( + _My_rope::_S_substring(__old, _M_pos+1, __old->_M_size)); + _Self_destruct_ptr __result_left( + _My_rope::_S_destr_concat_char_iter(__left, &__c, 1)); + # ifndef __GC - __stl_assert(left == result_left || 1 == result_left -> refcount); + __stl_assert(__left == __result_left || 1 == __result_left->_M_refcount); # endif - RopeBase * result = - my_rope::concat(result_left, right); + _RopeRep* __result = + _My_rope::_S_concat(__result_left, __right); # ifndef __GC - __stl_assert(1 <= result -> refcount); - RopeBase::unref(old); + __stl_assert(1 <= __result->_M_refcount); + _RopeRep::_S_unref(__old); # endif - root -> tree_ptr = result; + _M_root->_M_tree_ptr = __result; return *this; } -template <class charT, class Alloc> -inline __rope_charT_ref_proxy<charT, Alloc>::operator charT () const +template <class _CharT, class _Alloc> +inline _Rope_char_ref_proxy<_CharT, _Alloc>::operator _CharT () const { - if (current_valid) { - return current; + if (_M_current_valid) { + return _M_current; } else { - return my_rope::fetch(root->tree_ptr, pos); + return _My_rope::_S_fetch(_M_root->_M_tree_ptr, _M_pos); } } -template <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_char_ptr_proxy<_CharT, _Alloc> +_Rope_char_ref_proxy<_CharT, _Alloc>::operator& () const { + return _Rope_char_ptr_proxy<_CharT, _Alloc>(*this); } -template <class charT, class Alloc> -rope<charT, Alloc>::rope(size_t n, charT c) +template <class _CharT, class _Alloc> +rope<_CharT, _Alloc>::rope(size_t __n, _CharT __c, + const allocator_type& __a) +: _Base(__a) { - rope result; - const size_t exponentiate_threshold = 32; - size_t exponent; - size_t rest; - charT *rest_buffer; - RopeBase * remainder; - rope remainder_rope; - - if (0 == n) { tree_ptr = 0; return; } - exponent = n / exponentiate_threshold; - rest = n % exponentiate_threshold; - if (0 == rest) { - remainder = 0; + rope<_CharT,_Alloc> __result; + const size_t __exponentiate_threshold = 32; + size_t __exponent; + size_t __rest; + _CharT* __rest_buffer; + _RopeRep* __remainder; + rope<_CharT,_Alloc> __remainder_rope; + + if (0 == __n) + return; + + __exponent = __n / __exponentiate_threshold; + __rest = __n % __exponentiate_threshold; + if (0 == __rest) { + __remainder = 0; } else { - rest_buffer = DataAlloc::allocate(rounded_up_size(rest)); - uninitialized_fill_n(rest_buffer, rest, c); - __cond_store_eos(rest_buffer[rest]); + __rest_buffer = _Data_allocate(_S_rounded_up_size(__rest)); + uninitialized_fill_n(__rest_buffer, __rest, __c); + _S_cond_store_eos(__rest_buffer[__rest]); __STL_TRY { - remainder = RopeLeaf_from_char_ptr(rest_buffer, rest); + __remainder = _S_new_RopeLeaf(__rest_buffer, __rest, __a); } - __STL_UNWIND(RopeBase::free_string(rest_buffer, rest)) + __STL_UNWIND(_RopeRep::__STL_FREE_STRING(__rest_buffer, __rest, __a)) } - remainder_rope.tree_ptr = remainder; - if (exponent != 0) { - charT * base_buffer = - DataAlloc::allocate(rounded_up_size(exponentiate_threshold)); - RopeLeaf * base_leaf; - rope base_rope; - uninitialized_fill_n(base_buffer, exponentiate_threshold, c); - __cond_store_eos(base_buffer[exponentiate_threshold]); + __remainder_rope._M_tree_ptr = __remainder; + if (__exponent != 0) { + _CharT* __base_buffer = + _Data_allocate(_S_rounded_up_size(__exponentiate_threshold)); + _RopeLeaf* __base_leaf; + rope __base_rope; + uninitialized_fill_n(__base_buffer, __exponentiate_threshold, __c); + _S_cond_store_eos(__base_buffer[__exponentiate_threshold]); __STL_TRY { - base_leaf = RopeLeaf_from_char_ptr(base_buffer, - exponentiate_threshold); + __base_leaf = _S_new_RopeLeaf(__base_buffer, + __exponentiate_threshold, __a); } - __STL_UNWIND(RopeBase::free_string(base_buffer, exponentiate_threshold)) - base_rope.tree_ptr = base_leaf; - if (1 == exponent) { - result = base_rope; + __STL_UNWIND(_RopeRep::__STL_FREE_STRING(__base_buffer, + __exponentiate_threshold, __a)) + __base_rope._M_tree_ptr = __base_leaf; + if (1 == __exponent) { + __result = __base_rope; # ifndef __GC - __stl_assert(1 == result -> tree_ptr -> refcount); + __stl_assert(2 == __result._M_tree_ptr->_M_refcount); + // One each for base_rope and __result # endif } else { - result = power(base_rope, exponent, concat_fn()); + // XXX what is power()? + __result = power(__base_rope, __exponent, _Concat_fn()); } - if (0 != remainder) { - result += remainder_rope; + if (0 != __remainder) { + __result += __remainder_rope; } } else { - result = remainder_rope; + __result = __remainder_rope; } - tree_ptr = result.tree_ptr; - tree_ptr -> ref_nonnil(); + _M_tree_ptr = __result._M_tree_ptr; + _M_tree_ptr->_M_ref_nonnil(); } -template<class charT, class Alloc> charT rope<charT,Alloc>::empty_c_str[1]; +template<class _CharT, class _Alloc> + _CharT rope<_CharT,_Alloc>::_S_empty_c_str[1]; # ifdef __STL_PTHREADS - template<class charT, class Alloc> - pthread_mutex_t rope<charT,Alloc>::swap_lock = PTHREAD_MUTEX_INITIALIZER; + template<class _CharT, class _Alloc> + pthread_mutex_t + rope<_CharT,_Alloc>::_S_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, +template<class _CharT, class _Alloc> +const _CharT* rope<_CharT,_Alloc>::c_str() const { + if (0 == _M_tree_ptr) { + _S_empty_c_str[0] = _S_eos((_CharT*)0); // Possibly redundant, // but probably fast. - return empty_c_str; + return _S_empty_c_str; } - __GC_CONST charT * old_c_string = tree_ptr -> c_string; - if (0 != old_c_string) return(old_c_string); - size_t s = size(); - charT * result = DataAlloc::allocate(s + 1); - flatten(tree_ptr, result); - result[s] = __eos((charT *)0); + __GC_CONST _CharT* __old_c_string = _M_tree_ptr->_M_c_string; + if (0 != __old_c_string) return(__old_c_string); + size_t __s = size(); + _CharT* __result = _Data_allocate(__s + 1); + _S_flatten(_M_tree_ptr, __result); + __result[__s] = _S_eos((_CharT*)0); # ifdef __GC - tree_ptr -> c_string = result; + _M_tree_ptr->_M_c_string = __result; # else - if ((old_c_string = atomic_swap(&(tree_ptr -> c_string), result)) != 0) { + if ((__old_c_string = + _S_atomic_swap(&(_M_tree_ptr->_M_c_string), __result)) != 0) { // It must have been added in the interim. Hence it had to have been // separately allocated. Deallocate the old copy, since we just // replaced it. - destroy(old_c_string, old_c_string + s + 1); - DataAlloc::deallocate(old_c_string, s + 1); + destroy(__old_c_string, __old_c_string + __s + 1); + _Data_deallocate(__old_c_string, __s + 1); } # endif - return(result); + return(__result); } -template<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; +template<class _CharT, class _Alloc> +const _CharT* rope<_CharT,_Alloc>::replace_with_c_str() { + if (0 == _M_tree_ptr) { + _S_empty_c_str[0] = _S_eos((_CharT*)0); + return _S_empty_c_str; } - __GC_CONST charT * old_c_string = tree_ptr -> c_string; - if (RopeBase::leaf == tree_ptr -> tag && 0 != old_c_string) { - return(old_c_string); + __GC_CONST _CharT* __old_c_string = _M_tree_ptr->_M_c_string; + if (_RopeRep::_S_leaf == _M_tree_ptr->_M_tag && 0 != __old_c_string) { + return(__old_c_string); } - size_t s = size(); - charT * result = DataAlloc::allocate(rounded_up_size(s)); - flatten(tree_ptr, result); - result[s] = __eos((charT *)0); - tree_ptr -> unref_nonnil(); - tree_ptr = RopeLeaf_from_char_ptr(result, s); - return(result); + size_t __s = size(); + _CharT* __result = _Data_allocate(_S_rounded_up_size(__s)); + _S_flatten(_M_tree_ptr, __result); + __result[__s] = _S_eos((_CharT*)0); + _M_tree_ptr->_M_unref_nonnil(); + _M_tree_ptr = _S_new_RopeLeaf(__result, __s, get_allocator()); + return(__result); } // Algorithm specializations. More should be added. #ifndef _MSC_VER // I couldn't get this to work with VC++ -template<class charT,class Alloc> +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; +_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 !defined(__GNUC__) +// Appears to confuse g++ +inline void rotate(_Rope_iterator<char,__STL_DEFAULT_ALLOCATOR(char)> __first, + _Rope_iterator<char,__STL_DEFAULT_ALLOCATOR(char)> __middle, + _Rope_iterator<char,__STL_DEFAULT_ALLOCATOR(char)> __last) { + _Rope_rotate(__first, __middle, __last); } +#endif # if 0 // Probably not useful for several reasons: @@ -1518,10 +1530,11 @@ inline void rotate(__rope_iterator<char,__ALLOC> first, // - wchar_t is 4 bytes wide on most UNIX platforms, making it unattractive // for unicode strings. Unsigned short may be a better character // type. -inline void rotate(__rope_iterator<wchar_t,__ALLOC> first, - __rope_iterator<wchar_t,__ALLOC> middle, - __rope_iterator<wchar_t,__ALLOC> last) { - __rope_rotate(first, middle, last); +inline void rotate( + _Rope_iterator<wchar_t,__STL_DEFAULT_ALLOCATOR(char)> __first, + _Rope_iterator<wchar_t,__STL_DEFAULT_ALLOCATOR(char)> __middle, + _Rope_iterator<wchar_t,__STL_DEFAULT_ALLOCATOR(char)> __last) { + _Rope_rotate(__first, __middle, __last); } # endif #endif /* _MSC_VER */ diff --git a/contrib/libstdc++/stl/stl_algo.h b/contrib/libstdc++/stl/stl_algo.h index 5cde42c..e9beaee 100644 --- a/contrib/libstdc++/stl/stl_algo.h +++ b/contrib/libstdc++/stl/stl_algo.h @@ -39,2453 +39,2685 @@ __STL_BEGIN_NAMESPACE #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; +// __median (an extension, not present in the C++ standard). + +template <class _Tp> +inline const _Tp& __median(const _Tp& __a, const _Tp& __b, const _Tp& __c) { + if (__a < __b) + if (__b < __c) + return __b; + else if (__a < __c) + return __c; else - return a; - else if (a < c) - return a; - else if (b < c) - return c; + return __a; + else if (__a < __c) + return __a; + else if (__b < __c) + return __c; else - return b; + return __b; } -template <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; +template <class _Tp, class _Compare> +inline const _Tp& +__median(const _Tp& __a, const _Tp& __b, const _Tp& __c, _Compare __comp) { + if (__comp(__a, __b)) + if (__comp(__b, __c)) + return __b; + else if (__comp(__a, __c)) + return __c; else - return a; - else if (comp(a, c)) - return a; - else if (comp(b, c)) - return c; + return __a; + else if (__comp(__a, __c)) + return __a; + else if (__comp(__b, __c)) + return __c; else - return b; + return __b; } -template <class InputIterator, class Function> -Function for_each(InputIterator first, InputIterator last, Function f) { - for ( ; first != last; ++first) - f(*first); - return f; +// for_each. Apply a function to every element of a range. +template <class _InputIter, class _Function> +_Function for_each(_InputIter __first, _InputIter __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; +// find and find_if. + +template <class _InputIter, class _Tp> +inline _InputIter find(_InputIter __first, _InputIter __last, + const _Tp& __val, + input_iterator_tag) +{ + while (__first != __last && *__first != __val) + ++__first; + return __first; +} + +template <class _InputIter, class _Predicate> +inline _InputIter find_if(_InputIter __first, _InputIter __last, + _Predicate __pred, + input_iterator_tag) +{ + while (__first != __last && !__pred(*__first)) + ++__first; + return __first; +} + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + +template <class _RandomAccessIter, class _Tp> +_RandomAccessIter find(_RandomAccessIter __first, _RandomAccessIter __last, + const _Tp& __val, + random_access_iterator_tag) +{ + typename iterator_traits<_RandomAccessIter>::difference_type __trip_count + = (__last - __first) >> 2; + + for ( ; __trip_count > 0 ; --__trip_count) { + if (*__first == __val) return __first; + ++__first; + + if (*__first == __val) return __first; + ++__first; + + if (*__first == __val) return __first; + ++__first; + + if (*__first == __val) return __first; + ++__first; + } + + switch(__last - __first) { + case 3: + if (*__first == __val) return __first; + ++__first; + case 2: + if (*__first == __val) return __first; + ++__first; + case 1: + if (*__first == __val) return __first; + ++__first; + case 0: + default: + return __last; + } +} + +template <class _RandomAccessIter, class _Predicate> +_RandomAccessIter find_if(_RandomAccessIter __first, _RandomAccessIter __last, + _Predicate __pred, + random_access_iterator_tag) +{ + typename iterator_traits<_RandomAccessIter>::difference_type __trip_count + = (__last - __first) >> 2; + + for ( ; __trip_count > 0 ; --__trip_count) { + if (__pred(*__first)) return __first; + ++__first; + + if (__pred(*__first)) return __first; + ++__first; + + if (__pred(*__first)) return __first; + ++__first; + + if (__pred(*__first)) return __first; + ++__first; + } + + switch(__last - __first) { + case 3: + if (__pred(*__first)) return __first; + ++__first; + case 2: + if (__pred(*__first)) return __first; + ++__first; + case 1: + if (__pred(*__first)) return __first; + ++__first; + case 0: + default: + return __last; + } +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template <class _InputIter, class _Tp> +inline _InputIter find(_InputIter __first, _InputIter __last, + const _Tp& __val) +{ + return find(__first, __last, __val, __ITERATOR_CATEGORY(__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 _InputIter, class _Predicate> +inline _InputIter find_if(_InputIter __first, _InputIter __last, + _Predicate __pred) { + return find_if(__first, __last, __pred, __ITERATOR_CATEGORY(__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; +// adjacent_find. + +template <class _ForwardIter> +_ForwardIter adjacent_find(_ForwardIter __first, _ForwardIter __last) { + if (__first == __last) + return __last; + _ForwardIter __next = __first; + while(++__next != __last) { + if (*__first == *__next) + return __first; + __first = __next; } - return last; + return __last; } -template <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; +template <class _ForwardIter, class _BinaryPredicate> +_ForwardIter adjacent_find(_ForwardIter __first, _ForwardIter __last, + _BinaryPredicate __binary_pred) { + if (__first == __last) + return __last; + _ForwardIter __next = __first; + while(++__next != __last) { + if (__binary_pred(*__first, *__next)) + return __first; + __first = __next; } - return last; + return __last; } -template <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; +// count and count_if. There are two version of each, one whose return type +// type is void and one (present only if we have partial specialization) +// whose return type is iterator_traits<_InputIter>::difference_type. The +// C++ standard only has the latter version, but the former, which was present +// in the HP STL, is retained for backward compatibility. + +template <class _InputIter, class _Tp, class _Size> +void count(_InputIter __first, _InputIter __last, const _Tp& __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; +template <class _InputIter, class _Predicate, class _Size> +void count_if(_InputIter __first, _InputIter __last, _Predicate __pred, + _Size& __n) { + for ( ; __first != __last; ++__first) + if (__pred(*__first)) + ++__n; } #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION -template <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 _InputIter, class _Tp> +typename iterator_traits<_InputIter>::difference_type +count(_InputIter __first, _InputIter __last, const _Tp& __value) { + typename iterator_traits<_InputIter>::difference_type __n = 0; + for ( ; __first != __last; ++__first) + if (*__first == __value) + ++__n; + return __n; } -template <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; +template <class _InputIter, class _Predicate> +typename iterator_traits<_InputIter>::difference_type +count_if(_InputIter __first, _InputIter __last, _Predicate __pred) { + typename iterator_traits<_InputIter>::difference_type __n = 0; + for ( ; __first != __last; ++__first) + if (__pred(*__first)) + ++__n; + return __n; } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ -template <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); +// search. - if (d1 < d2) return last1; +template <class _ForwardIter1, class _ForwardIter2> +_ForwardIter1 search(_ForwardIter1 __first1, _ForwardIter1 __last1, + _ForwardIter2 __first2, _ForwardIter2 __last2) +{ + // Test for empty ranges + if (__first1 == __last1 || __first2 == __last2) + return __first1; - ForwardIterator1 current1 = first1; - ForwardIterator2 current2 = first2; + // Test for a pattern of length 1. + _ForwardIter2 __tmp(__first2); + ++__tmp; + if (__tmp == __last2) + return find(__first1, __last1, *__first2); - while (current2 != last2) - if (*current1 == *current2) { - ++current1; - ++current2; - } - else { - if (d1 == d2) - return last1; - else { - current1 = ++first1; - current2 = first2; - --d1; - } + // General case. + + _ForwardIter2 __p1, __p; + + __p1 = __first2; ++__p1; + + _ForwardIter1 __current = __first1; + + while (__first1 != __last1) { + __first1 = find(__first1, __last1, *__first2); + if (__first1 == __last1) + return __last1; + + __p = __p1; + __current = __first1; + if (++__current == __last1) + return __last1; + + while (*__current == *__p) { + if (++__p == __last2) + return __first1; + if (++__current == __last1) + return __last1; } - return first1; + + ++__first1; + } + return __first1; } -template <class ForwardIterator1, class ForwardIterator2> -inline ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2) +template <class _ForwardIter1, class _ForwardIter2, class _BinaryPred> +_ForwardIter1 search(_ForwardIter1 __first1, _ForwardIter1 __last1, + _ForwardIter2 __first2, _ForwardIter2 __last2, + _BinaryPred __predicate) { - return __search(first1, last1, first2, last2, distance_type(first1), - distance_type(first2)); -} + // Test for empty ranges + if (__first1 == __last1 || __first2 == __last2) + return __first1; + + // Test for a pattern of length 1. + _ForwardIter2 __tmp(__first2); + ++__tmp; + if (__tmp == __last2) + return find(__first1, __last1, *__first2); -template <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); + // General case. - if (d1 < d2) return last1; + _ForwardIter2 __p1, __p; - ForwardIterator1 current1 = first1; - ForwardIterator2 current2 = first2; + __p1 = __first2; ++__p1; - while (current2 != last2) - if (binary_pred(*current1, *current2)) { - ++current1; - ++current2; + _ForwardIter1 __current = __first1; + + while (__first1 != __last1) { + while (__first1 != __last1) { + if (__predicate(*__first1, *__first2)) + break; + ++__first1; } - else { - if (d1 == d2) - return last1; - else { - current1 = ++first1; - current2 = first2; - --d1; - } + while (__first1 != __last1 && !__predicate(*__first1, *__first2)) + ++__first1; + if (__first1 == __last1) + return __last1; + + __p = __p1; + __current = __first1; + if (++__current == __last1) return __last1; + + while (__predicate(*__current, *__p)) { + if (++__p == __last2) + return __first1; + if (++__current == __last1) + return __last1; } - return first1; -} -template <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)); + ++__first1; + } + return __first1; } -template <class ForwardIterator, class Integer, class T> -ForwardIterator search_n(ForwardIterator first, ForwardIterator last, - Integer count, const T& value) { - if (count <= 0) - return first; +// search_n. Search for __count consecutive copies of __val. + +template <class _ForwardIter, class _Integer, class _Tp> +_ForwardIter search_n(_ForwardIter __first, _ForwardIter __last, + _Integer __count, const _Tp& __val) { + if (__count <= 0) + return __first; else { - first = find(first, last, value); - while (first != last) { - Integer n = count - 1; - ForwardIterator i = first; - ++i; - while (i != last && n != 0 && *i == value) { - ++i; - --n; + __first = find(__first, __last, __val); + while (__first != __last) { + _Integer __n = __count - 1; + _ForwardIter __i = __first; + ++__i; + while (__i != __last && __n != 0 && *__i == __val) { + ++__i; + --__n; } - if (n == 0) - return first; + if (__n == 0) + return __first; else - first = find(i, last, value); + __first = find(__i, __last, __val); } - return last; + return __last; } } -template <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; +template <class _ForwardIter, class _Integer, class _Tp, class _BinaryPred> +_ForwardIter search_n(_ForwardIter __first, _ForwardIter __last, + _Integer __count, const _Tp& __val, + _BinaryPred __binary_pred) { + if (__count <= 0) + return __first; else { - while (first != last) { - if (binary_pred(*first, value)) break; - ++first; - } - while (first != last) { - Integer n = count - 1; - ForwardIterator i = first; - ++i; - while (i != last && n != 0 && binary_pred(*i, value)) { - ++i; - --n; + while (__first != __last) { + if (__binary_pred(*__first, __val)) + break; + ++__first; + } + while (__first != __last) { + _Integer __n = __count - 1; + _ForwardIter __i = __first; + ++__i; + while (__i != __last && __n != 0 && __binary_pred(*__i, __val)) { + ++__i; + --__n; } - if (n == 0) - return first; + if (__n == 0) + return __first; else { - while (i != last) { - if (binary_pred(*i, value)) break; - ++i; + while (__i != __last) { + if (__binary_pred(*__i, __val)) + break; + ++__i; } - first = i; + __first = __i; } } - return last; + return __last; } } -template <class ForwardIterator1, class ForwardIterator2> -ForwardIterator2 swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2) { - for ( ; first1 != last1; ++first1, ++first2) - iter_swap(first1, first2); - return first2; +// swap_ranges + +template <class _ForwardIter1, class _ForwardIter2> +_ForwardIter2 swap_ranges(_ForwardIter1 __first1, _ForwardIter1 __last1, + _ForwardIter2 __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; +// transform + +template <class _InputIter, class _OutputIter, class _UnaryOperation> +_OutputIter transform(_InputIter __first, _InputIter __last, + _OutputIter __result, _UnaryOperation __oper) { + for ( ; __first != __last; ++__first, ++__result) + *__result = __oper(*__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 _InputIter1, class _InputIter2, class _OutputIter, + class _BinaryOperation> +_OutputIter transform(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _OutputIter __result, + _BinaryOperation __binary_op) { + for ( ; __first1 != __last1; ++__first1, ++__first2, ++__result) + *__result = __binary_op(*__first1, *__first2); + return __result; } -template <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; +// replace, replace_if, replace_copy, replace_copy_if + +template <class _ForwardIter, class _Tp> +void replace(_ForwardIter __first, _ForwardIter __last, + const _Tp& __old_value, const _Tp& __new_value) { + for ( ; __first != __last; ++__first) + if (*__first == __old_value) + *__first = __new_value; } -template <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 _ForwardIter, class _Predicate, class _Tp> +void replace_if(_ForwardIter __first, _ForwardIter __last, + _Predicate __pred, const _Tp& __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 _InputIter, class _OutputIter, class _Tp> +_OutputIter replace_copy(_InputIter __first, _InputIter __last, + _OutputIter __result, + const _Tp& __old_value, const _Tp& __new_value) { + for ( ; __first != __last; ++__first, ++__result) + *__result = *__first == __old_value ? __new_value : *__first; + return __result; } -template <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 Iterator, class _OutputIter, class _Predicate, class _Tp> +_OutputIter replace_copy_if(Iterator __first, Iterator __last, + _OutputIter __result, + _Predicate __pred, const _Tp& __new_value) { + for ( ; __first != __last; ++__first, ++__result) + *__result = __pred(*__first) ? __new_value : *__first; + return __result; } -template <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; +// generate and generate_n + +template <class _ForwardIter, class _Generator> +void generate(_ForwardIter __first, _ForwardIter __last, _Generator __gen) { + for ( ; __first != __last; ++__first) + *__first = __gen(); } -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 _OutputIter, class _Size, class _Generator> +_OutputIter generate_n(_OutputIter __first, _Size __n, _Generator __gen) { + for ( ; __n > 0; --__n, ++__first) + *__first = __gen(); + return __first; } -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; -} +// remove, remove_if, remove_copy, remove_copy_if -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 _InputIter, class _OutputIter, class _Tp> +_OutputIter remove_copy(_InputIter __first, _InputIter __last, + _OutputIter __result, const _Tp& __value) { + for ( ; __first != __last; ++__first) + if (*__first != __value) { + *__result = *__first; + ++__result; + } + return __result; } -template <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 _InputIter, class _OutputIter, class _Predicate> +_OutputIter remove_copy_if(_InputIter __first, _InputIter __last, + _OutputIter __result, _Predicate __pred) { + for ( ; __first != __last; ++__first) + if (!__pred(*__first)) { + *__result = *__first; + ++__result; + } + return __result; +} + +template <class _ForwardIter, class _Tp> +_ForwardIter remove(_ForwardIter __first, _ForwardIter __last, + const _Tp& __value) { + __first = find(__first, __last, __value); + _ForwardIter __i = __first; + return __first == __last ? __first + : remove_copy(++__i, __last, __first, __value); } -template <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 _ForwardIter, class _Predicate> +_ForwardIter remove_if(_ForwardIter __first, _ForwardIter __last, + _Predicate __pred) { + __first = find_if(__first, __last, __pred); + _ForwardIter __i = __first; + return __first == __last ? __first + : remove_copy_if(++__i, __last, __first, __pred); } +// unique and unique_copy -template <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; +template <class _InputIter, class _OutputIter, class _Tp> +_OutputIter __unique_copy(_InputIter __first, _InputIter __last, + _OutputIter __result, _Tp*) { + _Tp __value = *__first; + *__result = __value; + while (++__first != __last) + if (__value != *__first) { + __value = *__first; + *++__result = __value; } - return ++result; + return ++__result; } -template <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 _InputIter, class _OutputIter> +inline _OutputIter __unique_copy(_InputIter __first, _InputIter __last, + _OutputIter __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 _InputIter, class _ForwardIter> +_ForwardIter __unique_copy(_InputIter __first, _InputIter __last, + _ForwardIter __result, forward_iterator_tag) { + *__result = *__first; + while (++__first != __last) + if (*__result != *__first) *++__result = *__first; + return ++__result; } -template <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 _InputIter, class _OutputIter> +inline _OutputIter unique_copy(_InputIter __first, _InputIter __last, + _OutputIter __result) { + if (__first == __last) return __result; + return __unique_copy(__first, __last, __result, + __ITERATOR_CATEGORY(__result)); } -template <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; +template <class _InputIter, class _OutputIter, class _BinaryPredicate, + class _Tp> +_OutputIter __unique_copy(_InputIter __first, _InputIter __last, + _OutputIter __result, + _BinaryPredicate __binary_pred, _Tp*) { + _Tp __value = *__first; + *__result = __value; + while (++__first != __last) + if (!__binary_pred(__value, *__first)) { + __value = *__first; + *++__result = __value; } - return ++result; + return ++__result; } -template <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 _InputIter, class _OutputIter, class _BinaryPredicate> +inline _OutputIter __unique_copy(_InputIter __first, _InputIter __last, + _OutputIter __result, + _BinaryPredicate __binary_pred, + output_iterator_tag) { + return __unique_copy(__first, __last, __result, __binary_pred, + __VALUE_TYPE(__first)); } -template <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 _InputIter, class _ForwardIter, class _BinaryPredicate> +_ForwardIter __unique_copy(_InputIter __first, _InputIter __last, + _ForwardIter __result, + _BinaryPredicate __binary_pred, + forward_iterator_tag) { + *__result = *__first; + while (++__first != __last) + if (!__binary_pred(*__result, *__first)) *++__result = *__first; + return ++__result; +} -template <class ForwardIterator> -ForwardIterator unique(ForwardIterator first, ForwardIterator last) { - first = adjacent_find(first, last); - return unique_copy(first, last, first); +template <class _InputIter, class _OutputIter, class _BinaryPredicate> +inline _OutputIter unique_copy(_InputIter __first, _InputIter __last, + _OutputIter __result, + _BinaryPredicate __binary_pred) { + if (__first == __last) return __result; + return __unique_copy(__first, __last, __result, __binary_pred, + __ITERATOR_CATEGORY(__result)); } - -template <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 _ForwardIter> +_ForwardIter unique(_ForwardIter __first, _ForwardIter __last) { + __first = adjacent_find(__first, __last); + return unique_copy(__first, __last, __first); } -template <class BidirectionalIterator> -void __reverse(BidirectionalIterator first, BidirectionalIterator last, +template <class _ForwardIter, class _BinaryPredicate> +_ForwardIter unique(_ForwardIter __first, _ForwardIter __last, + _BinaryPredicate __binary_pred) { + __first = adjacent_find(__first, __last, __binary_pred); + return unique_copy(__first, __last, __first, __binary_pred); +} + +// reverse and reverse_copy, and their auxiliary functions + +template <class _BidirectionalIter> +void __reverse(_BidirectionalIter __first, _BidirectionalIter __last, bidirectional_iterator_tag) { while (true) - if (first == last || first == --last) + if (__first == __last || __first == --__last) return; else - iter_swap(first++, last); + iter_swap(__first++, __last); } -template <class RandomAccessIterator> -void __reverse(RandomAccessIterator first, RandomAccessIterator last, +template <class _RandomAccessIter> +void __reverse(_RandomAccessIter __first, _RandomAccessIter __last, random_access_iterator_tag) { - while (first < last) iter_swap(first++, --last); + while (__first < __last) + iter_swap(__first++, --__last); } -template <class BidirectionalIterator> -inline void reverse(BidirectionalIterator first, BidirectionalIterator last) { - __reverse(first, last, iterator_category(first)); +template <class _BidirectionalIter> +inline void reverse(_BidirectionalIter __first, _BidirectionalIter __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; +template <class _BidirectionalIter, class _OutputIter> +_OutputIter reverse_copy(_BidirectionalIter __first, + _BidirectionalIter __last, + _OutputIter __result) { + while (__first != __last) { + --__last; + *__result = *__last; + ++__result; } - return 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; +// rotate and rotate_copy, and their auxiliary functions + +template <class _EuclideanRingElement> +_EuclideanRingElement __gcd(_EuclideanRingElement __m, + _EuclideanRingElement __n) +{ + while (__n != 0) { + _EuclideanRingElement __t = __m % __n; + __m = __n; + __n = __t; } + return __m; } -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 _ForwardIter, class _Distance> +_ForwardIter __rotate(_ForwardIter __first, + _ForwardIter __middle, + _ForwardIter __last, + _Distance*, + forward_iterator_tag) { + if (__first == __middle) + return __last; + if (__last == __middle) + return __first; + + _ForwardIter __first2 = __middle; + do { + swap(*__first++, *__first2++); + if (__first == __middle) + __middle = __first2; + } while (__first2 != __last); + + _ForwardIter __new_middle = __first; + + __first2 = __middle; + + while (__first2 != __last) { + swap (*__first++, *__first2++); + if (__first == __middle) + __middle = __first2; + else if (__first2 == __last) + __first2 = __middle; + } + + return __new_middle; } -template <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)); + +template <class _BidirectionalIter, class _Distance> +_BidirectionalIter __rotate(_BidirectionalIter __first, + _BidirectionalIter __middle, + _BidirectionalIter __last, + _Distance*, + bidirectional_iterator_tag) { + if (__first == __middle) + return __last; + if (__last == __middle) + return __first; + + __reverse(__first, __middle, bidirectional_iterator_tag()); + __reverse(__middle, __last, bidirectional_iterator_tag()); + + while (__first != __middle && __middle != __last) + swap (*__first++, *--__last); + + if (__first == __middle) { + __reverse(__middle, __last, bidirectional_iterator_tag()); + return __last; + } + else { + __reverse(__first, __middle, bidirectional_iterator_tag()); + return __first; } - *ptr1 = value; } -template <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 _RandomAccessIter, class _Distance, class _Tp> +_RandomAccessIter __rotate(_RandomAccessIter __first, + _RandomAccessIter __middle, + _RandomAccessIter __last, + _Distance *, _Tp *) { + + _Distance __n = __last - __first; + _Distance __k = __middle - __first; + _Distance __l = __n - __k; + _RandomAccessIter __result = __first + (__last - __middle); + + if (__k == __l) { + swap_ranges(__first, __middle, __middle); + return __result; + } + + _Distance __d = __gcd(__n, __k); + + for (_Distance __i = 0; __i < __d; __i++) { + _Tp __tmp = *__first; + _RandomAccessIter __p = __first; + + if (__k < __l) { + for (_Distance __j = 0; __j < __l/__d; __j++) { + if (__p > __first + __l) { + *__p = *(__p - __l); + __p -= __l; + } + + *__p = *(__p + __k); + __p += __k; + } + } + + else { + for (_Distance __j = 0; __j < __k/__d - 1; __j ++) { + if (__p < __last - __k) { + *__p = *(__p + __k); + __p += __k; + } + + *__p = * (__p - __l); + __p -= __l; + } + } + + *__p = __tmp; + ++__first; + } + + return __result; } -template <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 _ForwardIter> +inline _ForwardIter rotate(_ForwardIter __first, _ForwardIter __middle, + _ForwardIter __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 _ForwardIter, class _OutputIter> +_OutputIter rotate_copy(_ForwardIter __first, _ForwardIter __middle, + _ForwardIter __last, _OutputIter __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) +// Return a random number in the range [0, __n). This function encapsulates +// whether we're using rand (part of the standard C library) or lrand48 +// (not standard, but a much better choice whenever it's available). + +template <class _Distance> +inline _Distance __random_number(_Distance __n) { #ifdef __STL_NO_DRAND48 - iter_swap(i, first + Distance(rand() % ((i - first) + 1))); + return rand() % __n; #else - iter_swap(i, first + Distance(lrand48() % ((i - first) + 1))); + return lrand48() % __n; #endif } -template <class RandomAccessIterator> -inline void random_shuffle(RandomAccessIterator first, - RandomAccessIterator last) { - __random_shuffle(first, last, distance_type(first)); +// random_shuffle + +template <class _RandomAccessIter> +inline void random_shuffle(_RandomAccessIter __first, + _RandomAccessIter __last) { + if (__first == __last) return; + for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i) + iter_swap(__i, __first + __random_number((__i - __first) + 1)); } -template <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 _RandomAccessIter, class _RandomNumberGenerator> +void random_shuffle(_RandomAccessIter __first, _RandomAccessIter __last, + _RandomNumberGenerator& __rand) { + if (__first == __last) return; + for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i) + iter_swap(__i, __first + __rand((__i - __first) + 1)); } -template <class ForwardIterator, class OutputIterator, class Distance> -OutputIterator random_sample_n(ForwardIterator first, ForwardIterator last, - OutputIterator out, const Distance n) +// random_sample and random_sample_n (extensions, not part of the standard). + +template <class _ForwardIter, class _OutputIter, class _Distance> +_OutputIter random_sample_n(_ForwardIter __first, _ForwardIter __last, + _OutputIter __out, const _Distance __n) { - Distance remaining = 0; - distance(first, last, remaining); - Distance m = min(n, remaining); + _Distance __remaining = 0; + distance(__first, __last, __remaining); + _Distance __m = min(__n, __remaining); - while (m > 0) { -#ifdef __STL_NO_DRAND48 - if (rand() % remaining < m) { -#else - if (lrand48() % remaining < m) { -#endif - *out = *first; - ++out; - --m; + while (__m > 0) { + if (__random_number(__remaining) < __m) { + *__out = *__first; + ++__out; + --__m; } - --remaining; - ++first; + --__remaining; + ++__first; } - return out; + return __out; } -template <class ForwardIterator, class OutputIterator, class Distance, - class RandomNumberGenerator> -OutputIterator random_sample_n(ForwardIterator first, ForwardIterator last, - OutputIterator out, const Distance n, - RandomNumberGenerator& rand) +template <class _ForwardIter, class _OutputIter, class _Distance, + class _RandomNumberGenerator> +_OutputIter random_sample_n(_ForwardIter __first, _ForwardIter __last, + _OutputIter __out, const _Distance __n, + _RandomNumberGenerator& __rand) { - Distance remaining = 0; - distance(first, last, remaining); - Distance m = min(n, remaining); + _Distance __remaining = 0; + distance(__first, __last, __remaining); + _Distance __m = min(__n, __remaining); - while (m > 0) { - if (rand(remaining) < m) { - *out = *first; - ++out; - --m; + while (__m > 0) { + if (__rand(__remaining) < __m) { + *__out = *__first; + ++__out; + --__m; } - --remaining; - ++first; + --__remaining; + ++__first; } - return out; + return __out; } -template <class InputIterator, class RandomAccessIterator, class Distance> -RandomAccessIterator __random_sample(InputIterator first, InputIterator last, - RandomAccessIterator out, - const Distance n) +template <class _InputIter, class _RandomAccessIter, class _Distance> +_RandomAccessIter __random_sample(_InputIter __first, _InputIter __last, + _RandomAccessIter __out, + const _Distance __n) { - Distance m = 0; - Distance t = n; - for ( ; first != last && m < n; ++m, ++first) - out[m] = *first; + _Distance __m = 0; + _Distance __t = __n; + for ( ; __first != __last && __m < __n; ++__m, ++__first) + __out[__m] = *__first; - while (first != last) { - ++t; -#ifdef __STL_NO_DRAND48 - Distance M = rand() % t; -#else - Distance M = lrand48() % t; -#endif - if (M < n) - out[M] = *first; - ++first; + while (__first != __last) { + ++__t; + _Distance __M = __random_number(__t); + if (__M < __n) + __out[__M] = *__first; + ++__first; } - return out + m; + return __out + __m; } -template <class InputIterator, class RandomAccessIterator, - class RandomNumberGenerator, class Distance> -RandomAccessIterator __random_sample(InputIterator first, InputIterator last, - RandomAccessIterator out, - RandomNumberGenerator& rand, - const Distance n) +template <class _InputIter, class _RandomAccessIter, + class _RandomNumberGenerator, class _Distance> +_RandomAccessIter __random_sample(_InputIter __first, _InputIter __last, + _RandomAccessIter __out, + _RandomNumberGenerator& __rand, + const _Distance __n) { - Distance m = 0; - Distance t = n; - for ( ; first != last && m < n; ++m, ++first) - out[m] = *first; + _Distance __m = 0; + _Distance __t = __n; + for ( ; __first != __last && __m < __n; ++__m, ++__first) + __out[__m] = *__first; - while (first != last) { - ++t; - Distance M = rand(t); - if (M < n) - out[M] = *first; - ++first; + while (__first != __last) { + ++__t; + _Distance __M = __rand(__t); + if (__M < __n) + __out[__M] = *__first; + ++__first; } - return out + m; + return __out + __m; } -template <class InputIterator, class RandomAccessIterator> -inline RandomAccessIterator -random_sample(InputIterator first, InputIterator last, - RandomAccessIterator out_first, RandomAccessIterator out_last) +template <class _InputIter, class _RandomAccessIter> +inline _RandomAccessIter +random_sample(_InputIter __first, _InputIter __last, + _RandomAccessIter __out_first, _RandomAccessIter __out_last) { - return __random_sample(first, last, out_first, out_last - out_first); + return __random_sample(__first, __last, + __out_first, __out_last - __out_first); } -template <class InputIterator, class RandomAccessIterator, - class RandomNumberGenerator> -inline RandomAccessIterator -random_sample(InputIterator first, InputIterator last, - RandomAccessIterator out_first, RandomAccessIterator out_last, - RandomNumberGenerator& rand) + +template <class _InputIter, class _RandomAccessIter, + class _RandomNumberGenerator> +inline _RandomAccessIter +random_sample(_InputIter __first, _InputIter __last, + _RandomAccessIter __out_first, _RandomAccessIter __out_last, + _RandomNumberGenerator& __rand) { - return __random_sample(first, last, out_first, rand, out_last - out_first); + return __random_sample(__first, __last, + __out_first, __rand, + __out_last - __out_first); } +// partition, stable_partition, and their auxiliary functions + +template <class _ForwardIter, class _Predicate> +_ForwardIter __partition(_ForwardIter __first, + _ForwardIter __last, + _Predicate __pred, + forward_iterator_tag) { + if (__first == __last) return __first; + + while (__pred(*__first)) + if (++__first == __last) return __first; + + _ForwardIter __next = __first; + while (++__next != __last) + if (__pred(*__next)) { + swap(*__first, *__next); + ++__first; + } + + return __first; +} -template <class BidirectionalIterator, class Predicate> -BidirectionalIterator partition(BidirectionalIterator first, - BidirectionalIterator last, Predicate pred) { +template <class _BidirectionalIter, class _Predicate> +_BidirectionalIter __partition(_BidirectionalIter __first, + _BidirectionalIter __last, + _Predicate __pred, + bidirectional_iterator_tag) { while (true) { while (true) - if (first == last) - return first; - else if (pred(*first)) - ++first; + if (__first == __last) + return __first; + else if (__pred(*__first)) + ++__first; else break; - --last; + --__last; while (true) - if (first == last) - return first; - else if (!pred(*last)) - --last; + if (__first == __last) + return __first; + else if (!__pred(*__last)) + --__last; else break; - iter_swap(first, last); - ++first; - } -} - -template <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; + iter_swap(__first, __last); + ++__first; + } +} + +template <class _ForwardIter, class _Predicate> +inline _ForwardIter partition(_ForwardIter __first, + _ForwardIter __last, + _Predicate __pred) { + return __partition(__first, __last, __pred, __ITERATOR_CATEGORY(__first)); +} + + +template <class _ForwardIter, class _Predicate, class _Distance> +_ForwardIter __inplace_stable_partition(_ForwardIter __first, + _ForwardIter __last, + _Predicate __pred, _Distance __len) { + if (__len == 1) + return __pred(*__first) ? __last : __first; + _ForwardIter __middle = __first; + advance(__middle, __len / 2); + return rotate(__inplace_stable_partition(__first, __middle, __pred, + __len / 2), + __middle, + __inplace_stable_partition(__middle, __last, __pred, + __len - __len / 2)); +} + +template <class _ForwardIter, class _Pointer, class _Predicate, + class _Distance> +_ForwardIter __stable_partition_adaptive(_ForwardIter __first, + _ForwardIter __last, + _Predicate __pred, _Distance __len, + _Pointer __buffer, + _Distance __buffer_size) +{ + if (__len <= __buffer_size) { + _ForwardIter __result1 = __first; + _Pointer __result2 = __buffer; + for ( ; __first != __last ; ++__first) + if (__pred(*__first)) { + *__result1 = *__first; + ++__result1; } else { - *result2 = *first; - ++result2; + *__result2 = *__first; + ++__result2; } - copy(buffer, result2, result1); - return result1; + copy(__buffer, __result2, __result1); + return __result1; } else { - ForwardIterator middle = first; - advance(middle, len / 2); - ForwardIterator first_cut = - __stable_partition_adaptive(first, middle, pred, len / 2, - buffer, buffer_size); - ForwardIterator second_cut = - __stable_partition_adaptive(middle, last, pred, len - len / 2, - buffer, buffer_size); - - rotate(first_cut, middle, second_cut); - len = 0; - distance(middle, second_cut, len); - advance(first_cut, len); - return first_cut; - } -} - -template <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()); + _ForwardIter __middle = __first; + advance(__middle, __len / 2); + return rotate(__stable_partition_adaptive( + __first, __middle, __pred, + __len / 2, __buffer, __buffer_size), + __middle, + __stable_partition_adaptive( + __middle, __last, __pred, + __len - __len / 2, __buffer, __buffer_size)); + } +} + +template <class _ForwardIter, class _Predicate, class _Tp, class _Distance> +inline _ForwardIter +__stable_partition_aux(_ForwardIter __first, _ForwardIter __last, + _Predicate __pred, _Tp*, _Distance*) +{ + _Temporary_buffer<_ForwardIter, _Tp> __buf(__first, __last); + if (__buf.size() > 0) + return __stable_partition_adaptive(__first, __last, __pred, + _Distance(__buf.requested_size()), + __buf.begin(), __buf.size()); else - return __inplace_stable_partition(first, last, pred, - Distance(buf.requested_size())); + return __inplace_stable_partition(__first, __last, __pred, + _Distance(__buf.requested_size())); } -template <class ForwardIterator, class Predicate> -inline ForwardIterator stable_partition(ForwardIterator first, - ForwardIterator last, - Predicate pred) { - if (first == last) - return first; +template <class _ForwardIter, class _Predicate> +inline _ForwardIter stable_partition(_ForwardIter __first, + _ForwardIter __last, + _Predicate __pred) { + if (__first == __last) + return __first; else - return __stable_partition_aux(first, last, pred, - value_type(first), distance_type(first)); + return __stable_partition_aux(__first, __last, __pred, + __VALUE_TYPE(__first), + __DISTANCE_TYPE(__first)); } -template <class RandomAccessIterator, class T> -RandomAccessIterator __unguarded_partition(RandomAccessIterator first, - RandomAccessIterator last, - T pivot) { +template <class _RandomAccessIter, class _Tp> +_RandomAccessIter __unguarded_partition(_RandomAccessIter __first, + _RandomAccessIter __last, + _Tp __pivot) +{ while (true) { - while (*first < pivot) ++first; - --last; - while (pivot < *last) --last; - if (!(first < last)) return first; - iter_swap(first, last); - ++first; + while (*__first < __pivot) + ++__first; + --__last; + while (__pivot < *__last) + --__last; + if (!(__first < __last)) + return __first; + iter_swap(__first, __last); + ++__first; } } -template <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; +template <class _RandomAccessIter, class _Tp, class _Compare> +_RandomAccessIter __unguarded_partition(_RandomAccessIter __first, + _RandomAccessIter __last, + _Tp __pivot, _Compare __comp) +{ + while (true) { + while (__comp(*__first, __pivot)) + ++__first; + --__last; + while (__comp(__pivot, *__last)) + --__last; + if (!(__first < __last)) + return __first; + iter_swap(__first, __last); + ++__first; } } const int __stl_threshold = 16; +// sort() and its auxiliary functions. -template <class RandomAccessIterator, class T> -void __unguarded_linear_insert(RandomAccessIterator last, T value) { - RandomAccessIterator next = last; - --next; - while (value < *next) { - *last = *next; - last = next; - --next; +template <class _RandomAccessIter, class _Tp> +void __unguarded_linear_insert(_RandomAccessIter __last, _Tp __val) { + _RandomAccessIter __next = __last; + --__next; + while (__val < *__next) { + *__last = *__next; + __last = __next; + --__next; } - *last = value; + *__last = __val; } -template <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; +template <class _RandomAccessIter, class _Tp, class _Compare> +void __unguarded_linear_insert(_RandomAccessIter __last, _Tp __val, + _Compare __comp) { + _RandomAccessIter __next = __last; + --__next; + while (__comp(__val, *__next)) { + *__last = *__next; + __last = __next; + --__next; } - *last = value; + *__last = __val; } -template <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; +template <class _RandomAccessIter, class _Tp> +inline void __linear_insert(_RandomAccessIter __first, + _RandomAccessIter __last, _Tp*) { + _Tp __val = *__last; + if (__val < *__first) { + copy_backward(__first, __last, __last + 1); + *__first = __val; } else - __unguarded_linear_insert(last, value); + __unguarded_linear_insert(__last, __val); } -template <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; +template <class _RandomAccessIter, class _Tp, class _Compare> +inline void __linear_insert(_RandomAccessIter __first, + _RandomAccessIter __last, _Tp*, _Compare __comp) { + _Tp __val = *__last; + if (__comp(__val, *__first)) { + copy_backward(__first, __last, __last + 1); + *__first = __val; } else - __unguarded_linear_insert(last, value, comp); + __unguarded_linear_insert(__last, __val, __comp); } -template <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 _RandomAccessIter> +void __insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last) { + if (__first == __last) return; + for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i) + __linear_insert(__first, __i, __VALUE_TYPE(__first)); } -template <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 _RandomAccessIter, class _Compare> +void __insertion_sort(_RandomAccessIter __first, + _RandomAccessIter __last, _Compare __comp) { + if (__first == __last) return; + for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i) + __linear_insert(__first, __i, __VALUE_TYPE(__first), __comp); } -template <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 _RandomAccessIter, class _Tp> +void __unguarded_insertion_sort_aux(_RandomAccessIter __first, + _RandomAccessIter __last, _Tp*) { + for (_RandomAccessIter __i = __first; __i != __last; ++__i) + __unguarded_linear_insert(__i, _Tp(*__i)); } -template <class RandomAccessIterator> -inline void __unguarded_insertion_sort(RandomAccessIterator first, - RandomAccessIterator last) { - __unguarded_insertion_sort_aux(first, last, value_type(first)); +template <class _RandomAccessIter> +inline void __unguarded_insertion_sort(_RandomAccessIter __first, + _RandomAccessIter __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 _RandomAccessIter, class _Tp, class _Compare> +void __unguarded_insertion_sort_aux(_RandomAccessIter __first, + _RandomAccessIter __last, + _Tp*, _Compare __comp) { + for (_RandomAccessIter __i = __first; __i != __last; ++__i) + __unguarded_linear_insert(__i, _Tp(*__i), __comp); } -template <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 _RandomAccessIter, class _Compare> +inline void __unguarded_insertion_sort(_RandomAccessIter __first, + _RandomAccessIter __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); +template <class _RandomAccessIter> +void __final_insertion_sort(_RandomAccessIter __first, + _RandomAccessIter __last) { + if (__last - __first > __stl_threshold) { + __insertion_sort(__first, __first + __stl_threshold); + __unguarded_insertion_sort(__first + __stl_threshold, __last); } else - __insertion_sort(first, last); + __insertion_sort(__first, __last); } -template <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); +template <class _RandomAccessIter, class _Compare> +void __final_insertion_sort(_RandomAccessIter __first, + _RandomAccessIter __last, _Compare __comp) { + if (__last - __first > __stl_threshold) { + __insertion_sort(__first, __first + __stl_threshold, __comp); + __unguarded_insertion_sort(__first + __stl_threshold, __last, __comp); } else - __insertion_sort(first, last, comp); + __insertion_sort(__first, __last, __comp); } -template <class Size> -inline Size __lg(Size n) { - Size k; - for (k = 0; n > 1; n >>= 1) ++k; - return k; +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); +template <class _RandomAccessIter, class _Tp, class _Size> +void __introsort_loop(_RandomAccessIter __first, + _RandomAccessIter __last, _Tp*, + _Size __depth_limit) +{ + while (__last - __first > __stl_threshold) { + if (__depth_limit == 0) { + partial_sort(__first, __last, __last); return; } - --depth_limit; - RandomAccessIterator cut = __unguarded_partition - (first, last, T(__median(*first, *(first + (last - first)/2), - *(last - 1)))); - __introsort_loop(cut, last, value_type(first), depth_limit); - last = cut; + --__depth_limit; + _RandomAccessIter __cut = + __unguarded_partition(__first, __last, + _Tp(__median(*__first, + *(__first + (__last - __first)/2), + *(__last - 1)))); + __introsort_loop(__cut, __last, (_Tp*) 0, __depth_limit); + __last = __cut; } } -template <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); +template <class _RandomAccessIter, class _Tp, class _Size, class _Compare> +void __introsort_loop(_RandomAccessIter __first, + _RandomAccessIter __last, _Tp*, + _Size __depth_limit, _Compare __comp) +{ + while (__last - __first > __stl_threshold) { + if (__depth_limit == 0) { + partial_sort(__first, __last, __last, __comp); return; } - --depth_limit; - RandomAccessIterator cut = __unguarded_partition - (first, last, T(__median(*first, *(first + (last - first)/2), - *(last - 1), comp)), comp); - __introsort_loop(cut, last, value_type(first), depth_limit, comp); - last = cut; + --__depth_limit; + _RandomAccessIter __cut = + __unguarded_partition(__first, __last, + _Tp(__median(*__first, + *(__first + (__last - __first)/2), + *(__last - 1), __comp)), + __comp); + __introsort_loop(__cut, __last, (_Tp*) 0, __depth_limit, __comp); + __last = __cut; } } -template <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 _RandomAccessIter> +inline void sort(_RandomAccessIter __first, _RandomAccessIter __last) { + if (__first != __last) { + __introsort_loop(__first, __last, + __VALUE_TYPE(__first), + __lg(__last - __first) * 2); + __final_insertion_sort(__first, __last); } } -template <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 _RandomAccessIter, class _Compare> +inline void sort(_RandomAccessIter __first, _RandomAccessIter __last, + _Compare __comp) { + if (__first != __last) { + __introsort_loop(__first, __last, + __VALUE_TYPE(__first), + __lg(__last - __first) * 2, + __comp); + __final_insertion_sort(__first, __last, __comp); } } +// stable_sort() and its auxiliary functions. -template <class RandomAccessIterator> -void __inplace_stable_sort(RandomAccessIterator first, - RandomAccessIterator last) { - if (last - first < 15) { - __insertion_sort(first, last); +template <class _RandomAccessIter> +void __inplace_stable_sort(_RandomAccessIter __first, + _RandomAccessIter __last) { + if (__last - __first < 15) { + __insertion_sort(__first, __last); return; } - RandomAccessIterator middle = first + (last - first) / 2; - __inplace_stable_sort(first, middle); - __inplace_stable_sort(middle, last); - __merge_without_buffer(first, middle, last, middle - first, last - middle); + _RandomAccessIter __middle = __first + (__last - __first) / 2; + __inplace_stable_sort(__first, __middle); + __inplace_stable_sort(__middle, __last); + __merge_without_buffer(__first, __middle, __last, + __middle - __first, + __last - __middle); } -template <class RandomAccessIterator, class Compare> -void __inplace_stable_sort(RandomAccessIterator first, - RandomAccessIterator last, Compare comp) { - if (last - first < 15) { - __insertion_sort(first, last, comp); +template <class _RandomAccessIter, class _Compare> +void __inplace_stable_sort(_RandomAccessIter __first, + _RandomAccessIter __last, _Compare __comp) { + if (__last - __first < 15) { + __insertion_sort(__first, __last, __comp); return; } - RandomAccessIterator middle = first + (last - first) / 2; - __inplace_stable_sort(first, middle, comp); - __inplace_stable_sort(middle, last, comp); - __merge_without_buffer(first, middle, last, middle - first, - last - middle, comp); + _RandomAccessIter __middle = __first + (__last - __first) / 2; + __inplace_stable_sort(__first, __middle, __comp); + __inplace_stable_sort(__middle, __last, __comp); + __merge_without_buffer(__first, __middle, __last, + __middle - __first, + __last - __middle, + __comp); } -template <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; +template <class _RandomAccessIter1, class _RandomAccessIter2, + class _Distance> +void __merge_sort_loop(_RandomAccessIter1 __first, + _RandomAccessIter1 __last, + _RandomAccessIter2 __result, _Distance __step_size) { + _Distance __two_step = 2 * __step_size; - while (last - first >= two_step) { - result = merge(first, first + step_size, - first + step_size, first + two_step, result); - first += two_step; + while (__last - __first >= __two_step) { + __result = merge(__first, __first + __step_size, + __first + __step_size, __first + __two_step, + __result); + __first += __two_step; } - step_size = min(Distance(last - first), step_size); - merge(first, first + step_size, first + step_size, last, result); + __step_size = min(_Distance(__last - __first), __step_size); + merge(__first, __first + __step_size, __first + __step_size, __last, + __result); } -template <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; +template <class _RandomAccessIter1, class _RandomAccessIter2, + class _Distance, class _Compare> +void __merge_sort_loop(_RandomAccessIter1 __first, + _RandomAccessIter1 __last, + _RandomAccessIter2 __result, _Distance __step_size, + _Compare __comp) { + _Distance __two_step = 2 * __step_size; - while (last - first >= two_step) { - result = merge(first, first + step_size, - first + step_size, first + two_step, result, comp); - first += two_step; + while (__last - __first >= __two_step) { + __result = merge(__first, __first + __step_size, + __first + __step_size, __first + __two_step, + __result, + __comp); + __first += __two_step; } - step_size = min(Distance(last - first), step_size); + __step_size = min(_Distance(__last - __first), __step_size); - merge(first, first + step_size, first + step_size, last, result, comp); + merge(__first, __first + __step_size, + __first + __step_size, __last, + __result, + __comp); } const int __stl_chunk_size = 7; -template <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 _RandomAccessIter, class _Distance> +void __chunk_insertion_sort(_RandomAccessIter __first, + _RandomAccessIter __last, _Distance __chunk_size) +{ + while (__last - __first >= __chunk_size) { + __insertion_sort(__first, __first + __chunk_size); + __first += __chunk_size; + } + __insertion_sort(__first, __last); } -template <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; +template <class _RandomAccessIter, class _Distance, class _Compare> +void __chunk_insertion_sort(_RandomAccessIter __first, + _RandomAccessIter __last, + _Distance __chunk_size, _Compare __comp) +{ + while (__last - __first >= __chunk_size) { + __insertion_sort(__first, __first + __chunk_size, __comp); + __first += __chunk_size; } - __insertion_sort(first, last); + __insertion_sort(__first, __last, __comp); } -template <class RandomAccessIterator> -inline void nth_element(RandomAccessIterator first, RandomAccessIterator nth, - RandomAccessIterator last) { - __nth_element(first, nth, last, value_type(first)); -} +template <class _RandomAccessIter, class _Pointer, class _Distance> +void __merge_sort_with_buffer(_RandomAccessIter __first, + _RandomAccessIter __last, + _Pointer __buffer, _Distance*) { + _Distance __len = __last - __first; + _Pointer __buffer_last = __buffer + __len; -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; + _Distance __step_size = __stl_chunk_size; + __chunk_insertion_sort(__first, __last, __step_size); + + while (__step_size < __len) { + __merge_sort_loop(__first, __last, __buffer, __step_size); + __step_size *= 2; + __merge_sort_loop(__buffer, __buffer_last, __first, __step_size); + __step_size *= 2; } - __insertion_sort(first, last, comp); } -template <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 _RandomAccessIter, class _Pointer, class _Distance, + class _Compare> +void __merge_sort_with_buffer(_RandomAccessIter __first, + _RandomAccessIter __last, _Pointer __buffer, + _Distance*, _Compare __comp) { + _Distance __len = __last - __first; + _Pointer __buffer_last = __buffer + __len; -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; + _Distance __step_size = __stl_chunk_size; + __chunk_insertion_sort(__first, __last, __step_size, __comp); - while (len > 0) { - half = len >> 1; - middle = first; - advance(middle, half); - if (*middle < value) { - first = middle; - ++first; - len = len - half - 1; - } - else - len = half; + while (__step_size < __len) { + __merge_sort_loop(__first, __last, __buffer, __step_size, __comp); + __step_size *= 2; + __merge_sort_loop(__buffer, __buffer_last, __first, __step_size, __comp); + __step_size *= 2; } - return first; } -template <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; +template <class _RandomAccessIter, class _Pointer, class _Distance> +void __stable_sort_adaptive(_RandomAccessIter __first, + _RandomAccessIter __last, _Pointer __buffer, + _Distance __buffer_size) { + _Distance __len = (__last - __first + 1) / 2; + _RandomAccessIter __middle = __first + __len; + if (__len > __buffer_size) { + __stable_sort_adaptive(__first, __middle, __buffer, __buffer_size); + __stable_sort_adaptive(__middle, __last, __buffer, __buffer_size); + } + else { + __merge_sort_with_buffer(__first, __middle, __buffer, (_Distance*)0); + __merge_sort_with_buffer(__middle, __last, __buffer, (_Distance*)0); + } + __merge_adaptive(__first, __middle, __last, _Distance(__middle - __first), + _Distance(__last - __middle), __buffer, __buffer_size); +} + +template <class _RandomAccessIter, class _Pointer, class _Distance, + class _Compare> +void __stable_sort_adaptive(_RandomAccessIter __first, + _RandomAccessIter __last, _Pointer __buffer, + _Distance __buffer_size, _Compare __comp) { + _Distance __len = (__last - __first + 1) / 2; + _RandomAccessIter __middle = __first + __len; + if (__len > __buffer_size) { + __stable_sort_adaptive(__first, __middle, __buffer, __buffer_size, + __comp); + __stable_sort_adaptive(__middle, __last, __buffer, __buffer_size, + __comp); } - return first; + else { + __merge_sort_with_buffer(__first, __middle, __buffer, (_Distance*)0, + __comp); + __merge_sort_with_buffer(__middle, __last, __buffer, (_Distance*)0, + __comp); + } + __merge_adaptive(__first, __middle, __last, _Distance(__middle - __first), + _Distance(__last - __middle), __buffer, __buffer_size, + __comp); } -template <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 _RandomAccessIter, class _Tp, class _Distance> +inline void __stable_sort_aux(_RandomAccessIter __first, + _RandomAccessIter __last, _Tp*, _Distance*) { + _Temporary_buffer<_RandomAccessIter, _Tp> buf(__first, __last); + if (buf.begin() == 0) + __inplace_stable_sort(__first, __last); + else + __stable_sort_adaptive(__first, __last, buf.begin(), + _Distance(buf.size())); } -template <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; +template <class _RandomAccessIter, class _Tp, class _Distance, class _Compare> +inline void __stable_sort_aux(_RandomAccessIter __first, + _RandomAccessIter __last, _Tp*, _Distance*, + _Compare __comp) { + _Temporary_buffer<_RandomAccessIter, _Tp> buf(__first, __last); + if (buf.begin() == 0) + __inplace_stable_sort(__first, __last, __comp); + else + __stable_sort_adaptive(__first, __last, buf.begin(), + _Distance(buf.size()), + __comp); +} + +template <class _RandomAccessIter> +inline void stable_sort(_RandomAccessIter __first, + _RandomAccessIter __last) { + __stable_sort_aux(__first, __last, + __VALUE_TYPE(__first), + __DISTANCE_TYPE(__first)); +} + +template <class _RandomAccessIter, class _Compare> +inline void stable_sort(_RandomAccessIter __first, + _RandomAccessIter __last, _Compare __comp) { + __stable_sort_aux(__first, __last, + __VALUE_TYPE(__first), + __DISTANCE_TYPE(__first), + __comp); +} + +// partial_sort, partial_sort_copy, and auxiliary functions. + +template <class _RandomAccessIter, class _Tp> +void __partial_sort(_RandomAccessIter __first, _RandomAccessIter __middle, + _RandomAccessIter __last, _Tp*) { + make_heap(__first, __middle); + for (_RandomAccessIter __i = __middle; __i < __last; ++__i) + if (*__i < *__first) + __pop_heap(__first, __middle, __i, _Tp(*__i), + __DISTANCE_TYPE(__first)); + sort_heap(__first, __middle); +} + +template <class _RandomAccessIter> +inline void partial_sort(_RandomAccessIter __first, + _RandomAccessIter __middle, + _RandomAccessIter __last) { + __partial_sort(__first, __middle, __last, __VALUE_TYPE(__first)); +} + +template <class _RandomAccessIter, class _Tp, class _Compare> +void __partial_sort(_RandomAccessIter __first, _RandomAccessIter __middle, + _RandomAccessIter __last, _Tp*, _Compare __comp) { + make_heap(__first, __middle, __comp); + for (_RandomAccessIter __i = __middle; __i < __last; ++__i) + if (__comp(*__i, *__first)) + __pop_heap(__first, __middle, __i, _Tp(*__i), __comp, + __DISTANCE_TYPE(__first)); + sort_heap(__first, __middle, __comp); +} + +template <class _RandomAccessIter, class _Compare> +inline void partial_sort(_RandomAccessIter __first, + _RandomAccessIter __middle, + _RandomAccessIter __last, _Compare __comp) { + __partial_sort(__first, __middle, __last, __VALUE_TYPE(__first), __comp); +} + +template <class _InputIter, class _RandomAccessIter, class _Distance, + class _Tp> +_RandomAccessIter __partial_sort_copy(_InputIter __first, + _InputIter __last, + _RandomAccessIter __result_first, + _RandomAccessIter __result_last, + _Distance*, _Tp*) { + if (__result_first == __result_last) return __result_last; + _RandomAccessIter __result_real_last = __result_first; + while(__first != __last && __result_real_last != __result_last) { + *__result_real_last = *__first; + ++__result_real_last; + ++__first; + } + make_heap(__result_first, __result_real_last); + while (__first != __last) { + if (*__first < *__result_first) + __adjust_heap(__result_first, _Distance(0), + _Distance(__result_real_last - __result_first), + _Tp(*__first)); + ++__first; + } + sort_heap(__result_first, __result_real_last); + return __result_real_last; +} + +template <class _InputIter, class _RandomAccessIter> +inline _RandomAccessIter +partial_sort_copy(_InputIter __first, _InputIter __last, + _RandomAccessIter __result_first, + _RandomAccessIter __result_last) { + return __partial_sort_copy(__first, __last, __result_first, __result_last, + __DISTANCE_TYPE(__result_first), + __VALUE_TYPE(__first)); +} + +template <class _InputIter, class _RandomAccessIter, class _Compare, + class _Distance, class _Tp> +_RandomAccessIter __partial_sort_copy(_InputIter __first, + _InputIter __last, + _RandomAccessIter __result_first, + _RandomAccessIter __result_last, + _Compare __comp, _Distance*, _Tp*) { + if (__result_first == __result_last) return __result_last; + _RandomAccessIter __result_real_last = __result_first; + while(__first != __last && __result_real_last != __result_last) { + *__result_real_last = *__first; + ++__result_real_last; + ++__first; + } + make_heap(__result_first, __result_real_last, __comp); + while (__first != __last) { + if (__comp(*__first, *__result_first)) + __adjust_heap(__result_first, _Distance(0), + _Distance(__result_real_last - __result_first), + _Tp(*__first), + __comp); + ++__first; + } + sort_heap(__result_first, __result_real_last, __comp); + return __result_real_last; +} + +template <class _InputIter, class _RandomAccessIter, class _Compare> +inline _RandomAccessIter +partial_sort_copy(_InputIter __first, _InputIter __last, + _RandomAccessIter __result_first, + _RandomAccessIter __result_last, _Compare __comp) { + return __partial_sort_copy(__first, __last, __result_first, __result_last, + __comp, + __DISTANCE_TYPE(__result_first), + __VALUE_TYPE(__first)); +} + +// nth_element() and its auxiliary functions. + +template <class _RandomAccessIter, class _Tp> +void __nth_element(_RandomAccessIter __first, _RandomAccessIter __nth, + _RandomAccessIter __last, _Tp*) { + while (__last - __first > 3) { + _RandomAccessIter __cut = + __unguarded_partition(__first, __last, + _Tp(__median(*__first, + *(__first + (__last - __first)/2), + *(__last - 1)))); + if (__cut <= __nth) + __first = __cut; + else + __last = __cut; + } + __insertion_sort(__first, __last); +} + +template <class _RandomAccessIter> +inline void nth_element(_RandomAccessIter __first, _RandomAccessIter __nth, + _RandomAccessIter __last) { + __nth_element(__first, __nth, __last, __VALUE_TYPE(__first)); +} + +template <class _RandomAccessIter, class _Tp, class _Compare> +void __nth_element(_RandomAccessIter __first, _RandomAccessIter __nth, + _RandomAccessIter __last, _Tp*, _Compare __comp) { + while (__last - __first > 3) { + _RandomAccessIter __cut = + __unguarded_partition(__first, __last, + _Tp(__median(*__first, + *(__first + (__last - __first)/2), + *(__last - 1), + __comp)), + __comp); + if (__cut <= __nth) + __first = __cut; + else + __last = __cut; } - return first; + __insertion_sort(__first, __last, __comp); } -template <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 _RandomAccessIter, class _Compare> +inline void nth_element(_RandomAccessIter __first, _RandomAccessIter __nth, + _RandomAccessIter __last, _Compare __comp) { + __nth_element(__first, __nth, __last, __VALUE_TYPE(__first), __comp); } -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; +// Binary search (lower_bound, upper_bound, equal_range, binary_search). - while (len > 0) { - half = len >> 1; - middle = first; - advance(middle, half); - if (value < *middle) - len = half; - else { - first = middle; - ++first; - len = len - half - 1; +template <class _ForwardIter, class _Tp, class _Distance> +_ForwardIter __lower_bound(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val, _Distance*) +{ + _Distance __len = 0; + distance(__first, __last, __len); + _Distance __half; + _ForwardIter __middle; + + while (__len > 0) { + __half = __len >> 1; + __middle = __first; + advance(__middle, __half); + if (*__middle < __val) { + __first = __middle; + ++__first; + __len = __len - __half - 1; } + else + __len = __half; } - return first; + return __first; } -template <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; +template <class _ForwardIter, class _Tp> +inline _ForwardIter lower_bound(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val) { + return __lower_bound(__first, __last, __val, + __DISTANCE_TYPE(__first)); +} - while (len > 0) { - half = len >> 1; - middle = first + half; - if (value < *middle) - len = half; - else { - first = middle + 1; - len = len - half - 1; +template <class _ForwardIter, class _Tp, class _Compare, class _Distance> +_ForwardIter __lower_bound(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val, _Compare __comp, _Distance*) +{ + _Distance __len = 0; + distance(__first, __last, __len); + _Distance __half; + _ForwardIter __middle; + + while (__len > 0) { + __half = __len >> 1; + __middle = __first; + advance(__middle, __half); + if (__comp(*__middle, __val)) { + __first = __middle; + ++__first; + __len = __len - __half - 1; } + else + __len = __half; } - return first; + return __first; } -template <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 _ForwardIter, class _Tp, class _Compare> +inline _ForwardIter lower_bound(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val, _Compare __comp) { + return __lower_bound(__first, __last, __val, __comp, + __DISTANCE_TYPE(__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; +template <class _ForwardIter, class _Tp, class _Distance> +_ForwardIter __upper_bound(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val, _Distance*) +{ + _Distance __len = 0; + distance(__first, __last, __len); + _Distance __half; + _ForwardIter __middle; + + while (__len > 0) { + __half = __len >> 1; + __middle = __first; + advance(__middle, __half); + if (__val < *__middle) + __len = __half; else { - first = middle; - ++first; - len = len - half - 1; + __first = __middle; + ++__first; + __len = __len - __half - 1; } } - return first; + return __first; } -template <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; +template <class _ForwardIter, class _Tp> +inline _ForwardIter upper_bound(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val) { + return __upper_bound(__first, __last, __val, + __DISTANCE_TYPE(__first)); +} - while (len > 0) { - half = len >> 1; - middle = first + half; - if (comp(value, *middle)) - len = half; +template <class _ForwardIter, class _Tp, class _Compare, class _Distance> +_ForwardIter __upper_bound(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val, _Compare __comp, _Distance*) +{ + _Distance __len = 0; + distance(__first, __last, __len); + _Distance __half; + _ForwardIter __middle; + + while (__len > 0) { + __half = __len >> 1; + __middle = __first; + advance(__middle, __half); + if (__comp(__val, *__middle)) + __len = __half; else { - first = middle + 1; - len = len - half - 1; + __first = __middle; + ++__first; + __len = __len - __half - 1; } } - return first; + return __first; } -template <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 _ForwardIter, class _Tp, class _Compare> +inline _ForwardIter upper_bound(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val, _Compare __comp) { + return __upper_bound(__first, __last, __val, __comp, + __DISTANCE_TYPE(__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; +template <class _ForwardIter, class _Tp, class _Distance> +pair<_ForwardIter, _ForwardIter> +__equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, + _Distance*) +{ + _Distance __len = 0; + distance(__first, __last, __len); + _Distance __half; + _ForwardIter __middle, __left, __right; + + while (__len > 0) { + __half = __len >> 1; + __middle = __first; + advance(__middle, __half); + if (*__middle < __val) { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + else if (__val < *__middle) + __len = __half; else { - left = lower_bound(first, middle, value); - advance(first, len); - right = upper_bound(++middle, first, value); - return pair<ForwardIterator, ForwardIterator>(left, right); + __left = lower_bound(__first, __middle, __val); + advance(__first, __len); + __right = upper_bound(++__middle, __first, __val); + return pair<_ForwardIter, _ForwardIter>(__left, __right); } } - return pair<ForwardIterator, ForwardIterator>(first, first); + return pair<_ForwardIter, _ForwardIter>(__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 _ForwardIter, class _Tp> +inline pair<_ForwardIter, _ForwardIter> +equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val) { + return __equal_range(__first, __last, __val, + __DISTANCE_TYPE(__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; +template <class _ForwardIter, class _Tp, class _Compare, class _Distance> +pair<_ForwardIter, _ForwardIter> +__equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, + _Compare __comp, _Distance*) +{ + _Distance __len = 0; + distance(__first, __last, __len); + _Distance __half; + _ForwardIter __middle, __left, __right; + + while (__len > 0) { + __half = __len >> 1; + __middle = __first; + advance(__middle, __half); + if (__comp(*__middle, __val)) { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + else if (__comp(__val, *__middle)) + __len = __half; else { - left = lower_bound(first, middle, value, comp); - right = upper_bound(++middle, first + len, value, comp); - return pair<RandomAccessIterator, RandomAccessIterator>(left, - right); + __left = lower_bound(__first, __middle, __val, __comp); + advance(__first, __len); + __right = upper_bound(++__middle, __first, __val, __comp); + return pair<_ForwardIter, _ForwardIter>(__left, __right); } } - return pair<RandomAccessIterator, RandomAccessIterator>(first, first); + return pair<_ForwardIter, _ForwardIter>(__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 _ForwardIter, class _Tp, class _Compare> +inline pair<_ForwardIter, _ForwardIter> +equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, + _Compare __comp) { + return __equal_range(__first, __last, __val, __comp, + __DISTANCE_TYPE(__first)); +} -template <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 _ForwardIter, class _Tp> +bool binary_search(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val) { + _ForwardIter __i = lower_bound(__first, __last, __val); + return __i != __last && !(__val < *__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 _ForwardIter, class _Tp, class _Compare> +bool binary_search(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val, + _Compare __comp) { + _ForwardIter __i = lower_bound(__first, __last, __val, __comp); + return __i != __last && !__comp(__val, *__i); } -template <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; +// merge, with and without an explicitly supplied comparison function. + +template <class _InputIter1, class _InputIter2, class _OutputIter> +_OutputIter merge(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result) { + while (__first1 != __last1 && __first2 != __last2) { + if (*__first2 < *__first1) { + *__result = *__first2; + ++__first2; } else { - *result = *first1; - ++first1; + *__result = *__first1; + ++__first1; } - ++result; + ++__result; } - return copy(first2, last2, copy(first1, last1, result)); + return copy(__first2, __last2, copy(__first1, __last1, __result)); } -template <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; +template <class _InputIter1, class _InputIter2, class _OutputIter, + class _Compare> +_OutputIter merge(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result, _Compare __comp) { + while (__first1 != __last1 && __first2 != __last2) { + if (__comp(*__first2, *__first1)) { + *__result = *__first2; + ++__first2; } else { - *result = *first1; - ++first1; + *__result = *__first1; + ++__first1; } - ++result; + ++__result; } - return copy(first2, last2, copy(first1, last1, result)); + return copy(__first2, __last2, copy(__first1, __last1, __result)); } -template <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); +// inplace_merge and its auxiliary functions. + +template <class _BidirectionalIter, class _Distance> +void __merge_without_buffer(_BidirectionalIter __first, + _BidirectionalIter __middle, + _BidirectionalIter __last, + _Distance __len1, _Distance __len2) { + if (__len1 == 0 || __len2 == 0) + return; + if (__len1 + __len2 == 2) { + if (*__middle < *__first) + iter_swap(__first, __middle); return; } - BidirectionalIterator first_cut = first; - BidirectionalIterator second_cut = middle; - Distance len11 = 0; - Distance len22 = 0; - if (len1 > len2) { - len11 = len1 / 2; - advance(first_cut, len11); - second_cut = lower_bound(middle, last, *first_cut); - distance(middle, second_cut, len22); + _BidirectionalIter __first_cut = __first; + _BidirectionalIter __second_cut = __middle; + _Distance __len11 = 0; + _Distance __len22 = 0; + if (__len1 > __len2) { + __len11 = __len1 / 2; + advance(__first_cut, __len11); + __second_cut = lower_bound(__middle, __last, *__first_cut); + distance(__middle, __second_cut, __len22); } else { - len22 = len2 / 2; - advance(second_cut, len22); - first_cut = upper_bound(first, middle, *second_cut); - distance(first, first_cut, len11); - } - rotate(first_cut, middle, second_cut); - BidirectionalIterator new_middle = first_cut; - advance(new_middle, len22); - __merge_without_buffer(first, first_cut, new_middle, len11, len22); - __merge_without_buffer(new_middle, second_cut, last, len1 - len11, - len2 - len22); -} - -template <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); + __len22 = __len2 / 2; + advance(__second_cut, __len22); + __first_cut = upper_bound(__first, __middle, *__second_cut); + distance(__first, __first_cut, __len11); + } + _BidirectionalIter __new_middle + = rotate(__first_cut, __middle, __second_cut); + __merge_without_buffer(__first, __first_cut, __new_middle, + __len11, __len22); + __merge_without_buffer(__new_middle, __second_cut, __last, __len1 - __len11, + __len2 - __len22); +} + +template <class _BidirectionalIter, class _Distance, class _Compare> +void __merge_without_buffer(_BidirectionalIter __first, + _BidirectionalIter __middle, + _BidirectionalIter __last, + _Distance __len1, _Distance __len2, + _Compare __comp) { + if (__len1 == 0 || __len2 == 0) + return; + if (__len1 + __len2 == 2) { + if (__comp(*__middle, *__first)) + iter_swap(__first, __middle); return; } - BidirectionalIterator first_cut = first; - BidirectionalIterator second_cut = middle; - Distance len11 = 0; - Distance len22 = 0; - if (len1 > len2) { - len11 = len1 / 2; - advance(first_cut, len11); - second_cut = lower_bound(middle, last, *first_cut, comp); - distance(middle, second_cut, len22); + _BidirectionalIter __first_cut = __first; + _BidirectionalIter __second_cut = __middle; + _Distance __len11 = 0; + _Distance __len22 = 0; + if (__len1 > __len2) { + __len11 = __len1 / 2; + advance(__first_cut, __len11); + __second_cut = lower_bound(__middle, __last, *__first_cut, __comp); + distance(__middle, __second_cut, __len22); } else { - len22 = len2 / 2; - advance(second_cut, len22); - first_cut = upper_bound(first, middle, *second_cut, comp); - distance(first, first_cut, len11); - } - rotate(first_cut, middle, second_cut); - BidirectionalIterator new_middle = first_cut; - advance(new_middle, len22); - __merge_without_buffer(first, first_cut, new_middle, len11, len22, comp); - __merge_without_buffer(new_middle, second_cut, last, len1 - len11, - len2 - len22, comp); -} - -template <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; + __len22 = __len2 / 2; + advance(__second_cut, __len22); + __first_cut = upper_bound(__first, __middle, *__second_cut, __comp); + distance(__first, __first_cut, __len11); + } + _BidirectionalIter __new_middle + = rotate(__first_cut, __middle, __second_cut); + __merge_without_buffer(__first, __first_cut, __new_middle, __len11, __len22, + __comp); + __merge_without_buffer(__new_middle, __second_cut, __last, __len1 - __len11, + __len2 - __len22, __comp); +} + +template <class _BidirectionalIter1, class _BidirectionalIter2, + class _Distance> +_BidirectionalIter1 __rotate_adaptive(_BidirectionalIter1 __first, + _BidirectionalIter1 __middle, + _BidirectionalIter1 __last, + _Distance __len1, _Distance __len2, + _BidirectionalIter2 __buffer, + _Distance __buffer_size) { + _BidirectionalIter2 __buffer_end; + if (__len1 > __len2 && __len2 <= __buffer_size) { + __buffer_end = copy(__middle, __last, __buffer); + copy_backward(__first, __middle, __last); + return copy(__buffer, __buffer_end, __first); + } + else if (__len1 <= __buffer_size) { + __buffer_end = copy(__first, __middle, __buffer); + copy(__middle, __last, __first); + return copy_backward(__buffer, __buffer_end, __last); + } + else + return rotate(__first, __middle, __last); +} + +template <class _BidirectionalIter1, class _BidirectionalIter2, + class _BidirectionalIter3> +_BidirectionalIter3 __merge_backward(_BidirectionalIter1 __first1, + _BidirectionalIter1 __last1, + _BidirectionalIter2 __first2, + _BidirectionalIter2 __last2, + _BidirectionalIter3 __result) { + if (__first1 == __last1) + return copy_backward(__first2, __last2, __result); + if (__first2 == __last2) + return copy_backward(__first1, __last1, __result); + --__last1; + --__last2; while (true) { - if (*last2 < *last1) { - *--result = *last1; - if (first1 == last1) return copy_backward(first2, ++last2, result); - --last1; + if (*__last2 < *__last1) { + *--__result = *__last1; + if (__first1 == __last1) + return copy_backward(__first2, ++__last2, __result); + --__last1; } else { - *--result = *last2; - if (first2 == last2) return copy_backward(first1, ++last1, result); - --last2; - } - } -} - -template <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; + *--__result = *__last2; + if (__first2 == __last2) + return copy_backward(__first1, ++__last1, __result); + --__last2; + } + } +} + +template <class _BidirectionalIter1, class _BidirectionalIter2, + class _BidirectionalIter3, class _Compare> +_BidirectionalIter3 __merge_backward(_BidirectionalIter1 __first1, + _BidirectionalIter1 __last1, + _BidirectionalIter2 __first2, + _BidirectionalIter2 __last2, + _BidirectionalIter3 __result, + _Compare __comp) { + if (__first1 == __last1) + return copy_backward(__first2, __last2, __result); + if (__first2 == __last2) + return copy_backward(__first1, __last1, __result); + --__last1; + --__last2; while (true) { - if (comp(*last2, *last1)) { - *--result = *last1; - if (first1 == last1) return copy_backward(first2, ++last2, result); - --last1; + if (__comp(*__last2, *__last1)) { + *--__result = *__last1; + if (__first1 == __last1) + return copy_backward(__first2, ++__last2, __result); + --__last1; } else { - *--result = *last2; - if (first2 == last2) return copy_backward(first1, ++last1, result); - --last2; + *--__result = *__last2; + if (__first2 == __last2) + return copy_backward(__first1, ++__last1, __result); + --__last2; } } } -template <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); +template <class _BidirectionalIter, class _Distance, class _Pointer> +void __merge_adaptive(_BidirectionalIter __first, + _BidirectionalIter __middle, + _BidirectionalIter __last, + _Distance __len1, _Distance __len2, + _Pointer __buffer, _Distance __buffer_size) { + if (__len1 <= __len2 && __len1 <= __buffer_size) { + _Pointer __buffer_end = copy(__first, __middle, __buffer); + merge(__buffer, __buffer_end, __middle, __last, __first); } - else if (len2 <= buffer_size) { - Pointer end_buffer = copy(middle, last, buffer); - __merge_backward(first, middle, buffer, end_buffer, last); + else if (__len2 <= __buffer_size) { + _Pointer __buffer_end = copy(__middle, __last, __buffer); + __merge_backward(__first, __middle, __buffer, __buffer_end, __last); } else { - BidirectionalIterator first_cut = first; - BidirectionalIterator second_cut = middle; - Distance len11 = 0; - Distance len22 = 0; - if (len1 > len2) { - len11 = len1 / 2; - advance(first_cut, len11); - second_cut = lower_bound(middle, last, *first_cut); - distance(middle, second_cut, len22); + _BidirectionalIter __first_cut = __first; + _BidirectionalIter __second_cut = __middle; + _Distance __len11 = 0; + _Distance __len22 = 0; + if (__len1 > __len2) { + __len11 = __len1 / 2; + advance(__first_cut, __len11); + __second_cut = lower_bound(__middle, __last, *__first_cut); + distance(__middle, __second_cut, __len22); } else { - len22 = len2 / 2; - advance(second_cut, len22); - first_cut = upper_bound(first, middle, *second_cut); - distance(first, first_cut, len11); - } - BidirectionalIterator new_middle = - __rotate_adaptive(first_cut, middle, second_cut, len1 - len11, - len22, buffer, buffer_size); - __merge_adaptive(first, first_cut, new_middle, len11, len22, buffer, - buffer_size); - __merge_adaptive(new_middle, second_cut, last, len1 - len11, - len2 - len22, buffer, buffer_size); - } -} - -template <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); + __len22 = __len2 / 2; + advance(__second_cut, __len22); + __first_cut = upper_bound(__first, __middle, *__second_cut); + distance(__first, __first_cut, __len11); + } + _BidirectionalIter __new_middle = + __rotate_adaptive(__first_cut, __middle, __second_cut, __len1 - __len11, + __len22, __buffer, __buffer_size); + __merge_adaptive(__first, __first_cut, __new_middle, __len11, + __len22, __buffer, __buffer_size); + __merge_adaptive(__new_middle, __second_cut, __last, __len1 - __len11, + __len2 - __len22, __buffer, __buffer_size); + } +} + +template <class _BidirectionalIter, class _Distance, class _Pointer, + class _Compare> +void __merge_adaptive(_BidirectionalIter __first, + _BidirectionalIter __middle, + _BidirectionalIter __last, + _Distance __len1, _Distance __len2, + _Pointer __buffer, _Distance __buffer_size, + _Compare __comp) { + if (__len1 <= __len2 && __len1 <= __buffer_size) { + _Pointer __buffer_end = copy(__first, __middle, __buffer); + merge(__buffer, __buffer_end, __middle, __last, __first, __comp); + } + else if (__len2 <= __buffer_size) { + _Pointer __buffer_end = copy(__middle, __last, __buffer); + __merge_backward(__first, __middle, __buffer, __buffer_end, __last, + __comp); } else { - BidirectionalIterator first_cut = first; - BidirectionalIterator second_cut = middle; - Distance len11 = 0; - Distance len22 = 0; - if (len1 > len2) { - len11 = len1 / 2; - advance(first_cut, len11); - second_cut = lower_bound(middle, last, *first_cut, comp); - distance(middle, second_cut, len22); + _BidirectionalIter __first_cut = __first; + _BidirectionalIter __second_cut = __middle; + _Distance __len11 = 0; + _Distance __len22 = 0; + if (__len1 > __len2) { + __len11 = __len1 / 2; + advance(__first_cut, __len11); + __second_cut = lower_bound(__middle, __last, *__first_cut, __comp); + distance(__middle, __second_cut, __len22); } else { - len22 = len2 / 2; - advance(second_cut, len22); - first_cut = upper_bound(first, middle, *second_cut, comp); - distance(first, first_cut, len11); - } - BidirectionalIterator new_middle = - __rotate_adaptive(first_cut, middle, second_cut, len1 - len11, - len22, buffer, buffer_size); - __merge_adaptive(first, first_cut, new_middle, len11, len22, buffer, - buffer_size, comp); - __merge_adaptive(new_middle, second_cut, last, len1 - len11, - len2 - len22, buffer, buffer_size, comp); - } -} - -template <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); + __len22 = __len2 / 2; + advance(__second_cut, __len22); + __first_cut = upper_bound(__first, __middle, *__second_cut, __comp); + distance(__first, __first_cut, __len11); + } + _BidirectionalIter __new_middle = + __rotate_adaptive(__first_cut, __middle, __second_cut, __len1 - __len11, + __len22, __buffer, __buffer_size); + __merge_adaptive(__first, __first_cut, __new_middle, __len11, + __len22, __buffer, __buffer_size, __comp); + __merge_adaptive(__new_middle, __second_cut, __last, __len1 - __len11, + __len2 - __len22, __buffer, __buffer_size, __comp); + } +} + +template <class _BidirectionalIter, class _Tp, class _Distance> +inline void __inplace_merge_aux(_BidirectionalIter __first, + _BidirectionalIter __middle, + _BidirectionalIter __last, _Tp*, _Distance*) { + _Distance __len1 = 0; + distance(__first, __middle, __len1); + _Distance __len2 = 0; + distance(__middle, __last, __len2); + + _Temporary_buffer<_BidirectionalIter, _Tp> __buf(__first, __last); + if (__buf.begin() == 0) + __merge_without_buffer(__first, __middle, __last, __len1, __len2); else - __merge_adaptive(first, middle, last, len1, len2, - buf.begin(), Distance(buf.size())); + __merge_adaptive(__first, __middle, __last, __len1, __len2, + __buf.begin(), _Distance(__buf.size())); +} + +template <class _BidirectionalIter, class _Tp, + class _Distance, class _Compare> +inline void __inplace_merge_aux(_BidirectionalIter __first, + _BidirectionalIter __middle, + _BidirectionalIter __last, _Tp*, _Distance*, + _Compare __comp) { + _Distance __len1 = 0; + distance(__first, __middle, __len1); + _Distance __len2 = 0; + distance(__middle, __last, __len2); + + _Temporary_buffer<_BidirectionalIter, _Tp> __buf(__first, __last); + if (__buf.begin() == 0) + __merge_without_buffer(__first, __middle, __last, __len1, __len2, __comp); + else + __merge_adaptive(__first, __middle, __last, __len1, __len2, + __buf.begin(), _Distance(__buf.size()), + __comp); } -template <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); +template <class _BidirectionalIter> +inline void inplace_merge(_BidirectionalIter __first, + _BidirectionalIter __middle, + _BidirectionalIter __last) { + if (__first == __middle || __middle == __last) + return; + __inplace_merge_aux(__first, __middle, __last, + __VALUE_TYPE(__first), __DISTANCE_TYPE(__first)); +} - temporary_buffer<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) +template <class _BidirectionalIter, class _Compare> +inline void inplace_merge(_BidirectionalIter __first, + _BidirectionalIter __middle, + _BidirectionalIter __last, _Compare __comp) { + if (__first == __middle || __middle == __last) + return; + __inplace_merge_aux(__first, __middle, __last, + __VALUE_TYPE(__first), __DISTANCE_TYPE(__first), + __comp); +} + +// Set algorithms: includes, set_union, set_intersection, set_difference, +// set_symmetric_difference. All of these algorithms have the precondition +// that their input ranges are sorted and the postcondition that their output +// ranges are sorted. + +template <class _InputIter1, class _InputIter2> +bool includes(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2) { + while (__first1 != __last1 && __first2 != __last2) + if (*__first2 < *__first1) return false; - else if(*first1 < *first2) - ++first1; + else if(*__first1 < *__first2) + ++__first1; else - ++first1, ++first2; + ++__first1, ++__first2; - return first2 == last2; + return __first2 == __last2; } -template <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)) +template <class _InputIter1, class _InputIter2, class _Compare> +bool includes(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, _Compare __comp) { + while (__first1 != __last1 && __first2 != __last2) + if (__comp(*__first2, *__first1)) return false; - else if(comp(*first1, *first2)) - ++first1; + else if(__comp(*__first1, *__first2)) + ++__first1; else - ++first1, ++first2; + ++__first1, ++__first2; - return first2 == last2; + return __first2 == __last2; } -template <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; +template <class _InputIter1, class _InputIter2, class _OutputIter> +_OutputIter set_union(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result) { + while (__first1 != __last1 && __first2 != __last2) { + if (*__first1 < *__first2) { + *__result = *__first1; + ++__first1; } - else if (*first2 < *first1) { - *result = *first2; - ++first2; + else if (*__first2 < *__first1) { + *__result = *__first2; + ++__first2; } else { - *result = *first1; - ++first1; - ++first2; + *__result = *__first1; + ++__first1; + ++__first2; } - ++result; + ++__result; } - return copy(first2, last2, copy(first1, last1, result)); + return copy(__first2, __last2, copy(__first1, __last1, __result)); } -template <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; +template <class _InputIter1, class _InputIter2, class _OutputIter, + class _Compare> +_OutputIter set_union(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result, _Compare __comp) { + while (__first1 != __last1 && __first2 != __last2) { + if (__comp(*__first1, *__first2)) { + *__result = *__first1; + ++__first1; } - else if (comp(*first2, *first1)) { - *result = *first2; - ++first2; + else if (__comp(*__first2, *__first1)) { + *__result = *__first2; + ++__first2; } else { - *result = *first1; - ++first1; - ++first2; + *__result = *__first1; + ++__first1; + ++__first2; } - ++result; + ++__result; } - return copy(first2, last2, copy(first1, last1, result)); + return copy(__first2, __last2, copy(__first1, __last1, __result)); } -template <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; +template <class _InputIter1, class _InputIter2, class _OutputIter> +_OutputIter set_intersection(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result) { + while (__first1 != __last1 && __first2 != __last2) + if (*__first1 < *__first2) + ++__first1; + else if (*__first2 < *__first1) + ++__first2; else { - *result = *first1; - ++first1; - ++first2; - ++result; - } - return result; -} - -template <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; + *__result = *__first1; + ++__first1; + ++__first2; + ++__result; + } + return __result; +} + +template <class _InputIter1, class _InputIter2, class _OutputIter, + class _Compare> +_OutputIter set_intersection(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result, _Compare __comp) { + while (__first1 != __last1 && __first2 != __last2) + if (__comp(*__first1, *__first2)) + ++__first1; + else if (__comp(*__first2, *__first1)) + ++__first2; else { - *result = *first1; - ++first1; - ++first2; - ++result; - } - return result; -} - -template <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; + *__result = *__first1; + ++__first1; + ++__first2; + ++__result; + } + return __result; +} + +template <class _InputIter1, class _InputIter2, class _OutputIter> +_OutputIter set_difference(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result) { + while (__first1 != __last1 && __first2 != __last2) + if (*__first1 < *__first2) { + *__result = *__first1; + ++__first1; + ++__result; + } + else if (*__first2 < *__first1) + ++__first2; else { - ++first1; - ++first2; + ++__first1; + ++__first2; } - return copy(first1, last1, result); + return copy(__first1, __last1, __result); } -template <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; +template <class _InputIter1, class _InputIter2, class _OutputIter, + class _Compare> +_OutputIter set_difference(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result, _Compare __comp) { + while (__first1 != __last1 && __first2 != __last2) + if (__comp(*__first1, *__first2)) { + *__result = *__first1; + ++__first1; + ++__result; } - else if (comp(*first2, *first1)) - ++first2; + else if (__comp(*__first2, *__first1)) + ++__first2; else { - ++first1; - ++first2; + ++__first1; + ++__first2; } - return copy(first1, last1, result); + return copy(__first1, __last1, __result); } -template <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; +template <class _InputIter1, class _InputIter2, class _OutputIter> +_OutputIter +set_symmetric_difference(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result) { + while (__first1 != __last1 && __first2 != __last2) + if (*__first1 < *__first2) { + *__result = *__first1; + ++__first1; + ++__result; } - else if (*first2 < *first1) { - *result = *first2; - ++first2; - ++result; + else if (*__first2 < *__first1) { + *__result = *__first2; + ++__first2; + ++__result; } else { - ++first1; - ++first2; - } - return copy(first2, last2, copy(first1, last1, result)); -} - -template <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; + ++__first1; + ++__first2; + } + return copy(__first2, __last2, copy(__first1, __last1, __result)); +} + +template <class _InputIter1, class _InputIter2, class _OutputIter, + class _Compare> +_OutputIter +set_symmetric_difference(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result, + _Compare __comp) { + while (__first1 != __last1 && __first2 != __last2) + if (__comp(*__first1, *__first2)) { + *__result = *__first1; + ++__first1; + ++__result; + } + else if (__comp(*__first2, *__first1)) { + *__result = *__first2; + ++__first2; + ++__result; } else { - ++first1; - ++first2; - } - return copy(first2, last2, copy(first1, last1, result)); -} - -template <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; + ++__first1; + ++__first2; + } + return copy(__first2, __last2, copy(__first1, __last1, __result)); +} + +// min_element and max_element, with and without an explicitly supplied +// comparison function. + +template <class _ForwardIter> +_ForwardIter max_element(_ForwardIter __first, _ForwardIter __last) { + if (__first == __last) return __first; + _ForwardIter __result = __first; + while (++__first != __last) + if (*__result < *__first) + __result = __first; + return __result; +} + +template <class _ForwardIter, class _Compare> +_ForwardIter max_element(_ForwardIter __first, _ForwardIter __last, + _Compare __comp) { + if (__first == __last) return __first; + _ForwardIter __result = __first; + while (++__first != __last) + if (__comp(*__result, *__first)) __result = __first; + return __result; +} + +template <class _ForwardIter> +_ForwardIter min_element(_ForwardIter __first, _ForwardIter __last) { + if (__first == __last) return __first; + _ForwardIter __result = __first; + while (++__first != __last) + if (*__first < *__result) + __result = __first; + return __result; +} + +template <class _ForwardIter, class _Compare> +_ForwardIter min_element(_ForwardIter __first, _ForwardIter __last, + _Compare __comp) { + if (__first == __last) return __first; + _ForwardIter __result = __first; + while (++__first != __last) + if (__comp(*__first, *__result)) + __result = __first; + return __result; +} + +// next_permutation and prev_permutation, with and without an explicitly +// supplied comparison function. + +template <class _BidirectionalIter> +bool next_permutation(_BidirectionalIter __first, _BidirectionalIter __last) { + if (__first == __last) + return false; + _BidirectionalIter __i = __first; + ++__i; + if (__i == __last) + return false; + __i = __last; + --__i; for(;;) { - BidirectionalIterator ii = i; - --i; - if (*i < *ii) { - BidirectionalIterator j = last; - while (!(*i < *--j)); - iter_swap(i, j); - reverse(ii, last); + _BidirectionalIter __ii = __i; + --__i; + if (*__i < *__ii) { + _BidirectionalIter __j = __last; + while (!(*__i < *--__j)) + {} + iter_swap(__i, __j); + reverse(__ii, __last); return true; } - if (i == first) { - reverse(first, last); + if (__i == __first) { + reverse(__first, __last); return false; } } } -template <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; +template <class _BidirectionalIter, class _Compare> +bool next_permutation(_BidirectionalIter __first, _BidirectionalIter __last, + _Compare __comp) { + if (__first == __last) + return false; + _BidirectionalIter __i = __first; + ++__i; + if (__i == __last) + return false; + __i = __last; + --__i; for(;;) { - BidirectionalIterator ii = i; - --i; - if (comp(*i, *ii)) { - BidirectionalIterator j = last; - while (!comp(*i, *--j)); - iter_swap(i, j); - reverse(ii, last); + _BidirectionalIter __ii = __i; + --__i; + if (__comp(*__i, *__ii)) { + _BidirectionalIter __j = __last; + while (!__comp(*__i, *--__j)) + {} + iter_swap(__i, __j); + reverse(__ii, __last); return true; } - if (i == first) { - reverse(first, last); + if (__i == __first) { + reverse(__first, __last); return false; } } } -template <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; +template <class _BidirectionalIter> +bool prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last) { + if (__first == __last) + return false; + _BidirectionalIter __i = __first; + ++__i; + if (__i == __last) + return false; + __i = __last; + --__i; for(;;) { - BidirectionalIterator ii = i; - --i; - if (*ii < *i) { - BidirectionalIterator j = last; - while (!(*--j < *i)); - iter_swap(i, j); - reverse(ii, last); + _BidirectionalIter __ii = __i; + --__i; + if (*__ii < *__i) { + _BidirectionalIter __j = __last; + while (!(*--__j < *__i)) + {} + iter_swap(__i, __j); + reverse(__ii, __last); return true; } - if (i == first) { - reverse(first, last); + if (__i == __first) { + reverse(__first, __last); return false; } } } -template <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; +template <class _BidirectionalIter, class _Compare> +bool prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last, + _Compare __comp) { + if (__first == __last) + return false; + _BidirectionalIter __i = __first; + ++__i; + if (__i == __last) + return false; + __i = __last; + --__i; for(;;) { - BidirectionalIterator ii = i; - --i; - if (comp(*ii, *i)) { - BidirectionalIterator j = last; - while (!comp(*--j, *i)); - iter_swap(i, j); - reverse(ii, last); + _BidirectionalIter __ii = __i; + --__i; + if (__comp(*__ii, *__i)) { + _BidirectionalIter __j = __last; + while (!__comp(*--__j, *__i)) + {} + iter_swap(__i, __j); + reverse(__ii, __last); return true; } - if (i == first) { - reverse(first, last); + if (__i == __first) { + reverse(__first, __last); return false; } } } -template <class InputIterator, class ForwardIterator> -InputIterator find_first_of(InputIterator first1, InputIterator last1, - ForwardIterator first2, ForwardIterator last2) +// find_first_of, with and without an explicitly supplied comparison function. + +template <class _InputIter, class _ForwardIter> +_InputIter find_first_of(_InputIter __first1, _InputIter __last1, + _ForwardIter __first2, _ForwardIter __last2) { - for ( ; first1 != last1; ++first1) - for (ForwardIterator iter = first2; iter != last2; ++iter) - if (*first1 == *iter) - return first1; - return last1; + for ( ; __first1 != __last1; ++__first1) + for (_ForwardIter __iter = __first2; __iter != __last2; ++__iter) + if (*__first1 == *__iter) + return __first1; + return __last1; } -template <class InputIterator, class ForwardIterator, class BinaryPredicate> -InputIterator find_first_of(InputIterator first1, InputIterator last1, - ForwardIterator first2, ForwardIterator last2, - BinaryPredicate comp) +template <class _InputIter, class _ForwardIter, class _BinaryPredicate> +_InputIter find_first_of(_InputIter __first1, _InputIter __last1, + _ForwardIter __first2, _ForwardIter __last2, + _BinaryPredicate __comp) { - for ( ; first1 != last1; ++first1) - for (ForwardIterator iter = first2; iter != last2; ++iter) - if (comp(*first1, *iter)) - return first1; - return last1; + for ( ; __first1 != __last1; ++__first1) + for (_ForwardIter __iter = __first2; __iter != __last2; ++__iter) + if (__comp(*__first1, *__iter)) + return __first1; + return __last1; } -// Search [first2, last2) as a subsequence in [first1, last1). +// find_end, with and without an explicitly supplied comparison function. +// Search [first2, last2) as a subsequence in [first1, last1), and return +// the *last* possible match. Note that find_end for bidirectional iterators +// is much faster than for forward iterators. // find_end for forward iterators. -template <class ForwardIterator1, class ForwardIterator2> -ForwardIterator1 __find_end(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - forward_iterator_tag, forward_iterator_tag) +template <class _ForwardIter1, class _ForwardIter2> +_ForwardIter1 __find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, + _ForwardIter2 __first2, _ForwardIter2 __last2, + forward_iterator_tag, forward_iterator_tag) { - if (first2 == last2) - return last1; + if (__first2 == __last2) + return __last1; else { - ForwardIterator1 result = last1; + _ForwardIter1 __result = __last1; while (1) { - ForwardIterator1 new_result = search(first1, last1, first2, last2); - if (new_result == last1) - return result; + _ForwardIter1 __new_result + = search(__first1, __last1, __first2, __last2); + if (__new_result == __last1) + return __result; else { - result = new_result; - first1 = new_result; - ++first1; + __result = __new_result; + __first1 = __new_result; + ++__first1; } } } } -template <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) +template <class _ForwardIter1, class _ForwardIter2, + class _BinaryPredicate> +_ForwardIter1 __find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, + _ForwardIter2 __first2, _ForwardIter2 __last2, + forward_iterator_tag, forward_iterator_tag, + _BinaryPredicate __comp) { - if (first2 == last2) - return last1; + if (__first2 == __last2) + return __last1; else { - ForwardIterator1 result = last1; + _ForwardIter1 __result = __last1; while (1) { - ForwardIterator1 new_result = search(first1, last1, first2, last2, comp); - if (new_result == last1) - return result; + _ForwardIter1 __new_result + = search(__first1, __last1, __first2, __last2, __comp); + if (__new_result == __last1) + return __result; else { - result = new_result; - first1 = new_result; - ++first1; + __result = __new_result; + __first1 = __new_result; + ++__first1; } } } @@ -2494,167 +2726,155 @@ ForwardIterator1 __find_end(ForwardIterator1 first1, ForwardIterator1 last1, // find_end for bidirectional iterators. Requires partial specialization. #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION -template <class BidirectionalIterator1, class BidirectionalIterator2> -BidirectionalIterator1 -__find_end(BidirectionalIterator1 first1, BidirectionalIterator1 last1, - BidirectionalIterator2 first2, BidirectionalIterator2 last2, +template <class _BidirectionalIter1, class _BidirectionalIter2> +_BidirectionalIter1 +__find_end(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1, + _BidirectionalIter2 __first2, _BidirectionalIter2 __last2, bidirectional_iterator_tag, bidirectional_iterator_tag) { - typedef reverse_iterator<BidirectionalIterator1> reviter1; - typedef reverse_iterator<BidirectionalIterator2> reviter2; + typedef reverse_iterator<_BidirectionalIter1> _RevIter1; + typedef reverse_iterator<_BidirectionalIter2> _RevIter2; - reviter1 rlast1(first1); - reviter2 rlast2(first2); - reviter1 rresult = search(reviter1(last1), rlast1, reviter2(last2), rlast2); + _RevIter1 __rlast1(__first1); + _RevIter2 __rlast2(__first2); + _RevIter1 __rresult = search(_RevIter1(__last1), __rlast1, + _RevIter2(__last2), __rlast2); - if (rresult == rlast1) - return last1; + if (__rresult == __rlast1) + return __last1; else { - BidirectionalIterator1 result = rresult.base(); - advance(result, -distance(first2, last2)); - return result; + _BidirectionalIter1 __result = __rresult.base(); + advance(__result, -distance(__first2, __last2)); + return __result; } } -template <class BidirectionalIterator1, class BidirectionalIterator2, - class BinaryPredicate> -BidirectionalIterator1 -__find_end(BidirectionalIterator1 first1, BidirectionalIterator1 last1, - BidirectionalIterator2 first2, BidirectionalIterator2 last2, +template <class _BidirectionalIter1, class _BidirectionalIter2, + class _BinaryPredicate> +_BidirectionalIter1 +__find_end(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1, + _BidirectionalIter2 __first2, _BidirectionalIter2 __last2, bidirectional_iterator_tag, bidirectional_iterator_tag, - BinaryPredicate comp) + _BinaryPredicate __comp) { - typedef reverse_iterator<BidirectionalIterator1> reviter1; - typedef reverse_iterator<BidirectionalIterator2> reviter2; + typedef reverse_iterator<_BidirectionalIter1> _RevIter1; + typedef reverse_iterator<_BidirectionalIter2> _RevIter2; - reviter1 rlast1(first1); - reviter2 rlast2(first2); - reviter1 rresult = search(reviter1(last1), rlast1, reviter2(last2), rlast2, - comp); + _RevIter1 __rlast1(__first1); + _RevIter2 __rlast2(__first2); + _RevIter1 __rresult = search(_RevIter1(__last1), __rlast1, + _RevIter2(__last2), __rlast2, + __comp); - if (rresult == rlast1) - return last1; + if (__rresult == __rlast1) + return __last1; else { - BidirectionalIterator1 result = rresult.base(); - advance(result, -distance(first2, last2)); - return result; + _BidirectionalIter1 __result = __rresult.base(); + advance(__result, -distance(__first2, __last2)); + return __result; } } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ -// Dispatching functions. +// Dispatching functions for find_end. -template <class ForwardIterator1, class ForwardIterator2> -inline ForwardIterator1 -find_end(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2) +template <class _ForwardIter1, class _ForwardIter2> +inline _ForwardIter1 +find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, + _ForwardIter2 __first2, _ForwardIter2 __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 */ + return __find_end(__first1, __last1, __first2, __last2, + __ITERATOR_CATEGORY(__first1), + __ITERATOR_CATEGORY(__first2)); } -template <class ForwardIterator1, class ForwardIterator2, - class BinaryPredicate> -inline ForwardIterator1 -find_end(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - BinaryPredicate comp) +template <class _ForwardIter1, class _ForwardIter2, + class _BinaryPredicate> +inline _ForwardIter1 +find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, + _ForwardIter2 __first2, _ForwardIter2 __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 */ + return __find_end(__first1, __last1, __first2, __last2, + __ITERATOR_CATEGORY(__first1), + __ITERATOR_CATEGORY(__first2), + __comp); } -template <class RandomAccessIterator, class Distance> -bool __is_heap(RandomAccessIterator first, RandomAccessIterator last, - Distance*) -{ - const Distance n = last - first; +// is_heap, a predicate testing whether or not a range is +// a heap. This function is an extension, not part of the C++ +// standard. - Distance parent = 0; - for (Distance child = 1; child < n; ++child) { - if (first[parent] < first[child]) +template <class _RandomAccessIter, class _Distance> +bool __is_heap(_RandomAccessIter __first, _Distance __n) +{ + _Distance __parent = 0; + for (_Distance __child = 1; __child < __n; ++__child) { + if (__first[__parent] < __first[__child]) return false; - if ((child & 1) == 0) - ++parent; + 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*) +template <class _RandomAccessIter, class _Distance, class _StrictWeakOrdering> +bool __is_heap(_RandomAccessIter __first, _StrictWeakOrdering __comp, + _Distance __n) { - const Distance n = last - first; - - Distance parent = 0; - for (Distance child = 1; child < n; ++child) { - if (comp(first[parent], first[child])) + _Distance __parent = 0; + for (_Distance __child = 1; __child < __n; ++__child) { + if (__comp(__first[__parent], __first[__child])) return false; - if ((child & 1) == 0) - ++parent; + if ((__child & 1) == 0) + ++__parent; } return true; } -template <class RandomAccessIterator, class StrictWeakOrdering> -inline bool is_heap(RandomAccessIterator first, RandomAccessIterator last, - StrictWeakOrdering comp) +template <class _RandomAccessIter> +inline bool is_heap(_RandomAccessIter __first, _RandomAccessIter __last) +{ + return __is_heap(__first, __last - __first); +} + + +template <class _RandomAccessIter, class _StrictWeakOrdering> +inline bool is_heap(_RandomAccessIter __first, _RandomAccessIter __last, + _StrictWeakOrdering __comp) { - return __is_heap(first, last, comp, distance_type(first)); + return __is_heap(__first, __comp, __last - __first); } +// is_sorted, a predicated testing whether a range is sorted in +// nondescending order. This is an extension, not part of the C++ +// standard. -template <class ForwardIterator> -bool is_sorted(ForwardIterator first, ForwardIterator last) +template <class _ForwardIter> +bool is_sorted(_ForwardIter __first, _ForwardIter __last) { - if (first == last) + if (__first == __last) return true; - ForwardIterator next = first; - for (++next; next != last; first = next, ++next) { - if (*next < *first) + _ForwardIter __next = __first; + for (++__next; __next != __last; __first = __next, ++__next) { + if (*__next < *__first) return false; } return true; } -template <class ForwardIterator, class StrictWeakOrdering> -bool is_sorted(ForwardIterator first, ForwardIterator last, - StrictWeakOrdering comp) +template <class _ForwardIter, class _StrictWeakOrdering> +bool is_sorted(_ForwardIter __first, _ForwardIter __last, + _StrictWeakOrdering __comp) { - if (first == last) + if (__first == __last) return true; - ForwardIterator next = first; - for (++next; next != last; first = next, ++next) { - if (comp(*next, *first)) + _ForwardIter __next = __first; + for (++__next; __next != __last; __first = __next, ++__next) { + if (__comp(*__next, *__first)) return false; } diff --git a/contrib/libstdc++/stl/stl_algobase.h b/contrib/libstdc++/stl/stl_algobase.h index 101fea5..15e535f 100644 --- a/contrib/libstdc++/stl/stl_algobase.h +++ b/contrib/libstdc++/stl/stl_algobase.h @@ -12,7 +12,7 @@ * purpose. It is provided "as is" without express or implied warranty. * * - * Copyright (c) 1996 + * Copyright (c) 1996-1998 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software @@ -58,381 +58,465 @@ __STL_BEGIN_NAMESPACE -template <class ForwardIterator1, class ForwardIterator2, class T> -inline void __iter_swap(ForwardIterator1 a, ForwardIterator2 b, T*) { - T tmp = *a; - *a = *b; - *b = tmp; +// swap and iter_swap + +template <class _ForwardIter1, class _ForwardIter2, class _Tp> +inline void __iter_swap(_ForwardIter1 __a, _ForwardIter2 __b, _Tp*) { + _Tp __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 _ForwardIter1, class _ForwardIter2> +inline void iter_swap(_ForwardIter1 __a, _ForwardIter2 __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; +template <class _Tp> +inline void swap(_Tp& __a, _Tp& __b) { + _Tp __tmp = __a; + __a = __b; + __b = __tmp; } +//-------------------------------------------------- +// min and max + #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 _Tp> +inline const _Tp& min(const _Tp& __a, const _Tp& __b) { + return __b < __a ? __b : __a; } -template <class T> -inline const T& max(const T& a, const T& b) { - return a < b ? b : a; +template <class _Tp> +inline const _Tp& max(const _Tp& __a, const _Tp& __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 _Tp, class _Compare> +inline const _Tp& min(const _Tp& __a, const _Tp& __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 _Tp, class _Compare> +inline const _Tp& max(const _Tp& __a, const _Tp& __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; -} +//-------------------------------------------------- +// copy -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; -} +// All of these auxiliary functions serve two purposes. (1) Replace +// calls to copy with memmove whenever possible. (Memmove, not memcpy, +// because the input and output ranges are permitted to overlap.) +// (2) If we're using random access iterators, then write the loop as +// a for loop with an explicit count. The auxiliary class __copy_dispatch +// is a workaround for compilers that don't support partial ordering of +// function templates. -template <class RandomAccessIterator, class OutputIterator> -inline OutputIterator -__copy(RandomAccessIterator first, RandomAccessIterator last, - OutputIterator result, random_access_iterator_tag) +template <class _InputIter, class _OutputIter, class _Distance> +inline _OutputIter __copy(_InputIter __first, _InputIter __last, + _OutputIter __result, + input_iterator_tag, _Distance*) { - return __copy_d(first, last, result, distance_type(first)); + for ( ; __first != __last; ++__result, ++__first) + *__result = *__first; + return __result; } -template <class InputIterator, class OutputIterator> -struct __copy_dispatch +template <class _RandomAccessIter, class _OutputIter, class _Distance> +inline _OutputIter +__copy(_RandomAccessIter __first, _RandomAccessIter __last, + _OutputIter __result, random_access_iterator_tag, _Distance*) { - OutputIterator operator()(InputIterator first, InputIterator last, - OutputIterator result) { - return __copy(first, last, result, iterator_category(first)); + for (_Distance __n = __last - __first; __n > 0; --__n) { + *__result = *__first; + ++__first; + ++__result; } -}; - -#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION - -template <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); + return __result; } -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 _Tp> +inline _Tp* +__copy_trivial(const _Tp* __first, const _Tp* __last, _Tp* __result) { + memmove(__result, __first, sizeof(_Tp) * (__last - __first)); + return __result + (__last - __first); } -template <class T> -struct __copy_dispatch<T*, T*> +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + +template <class _InputIter, class _OutputIter, class _BoolType> +struct __copy_dispatch { + static _OutputIter copy(_InputIter __first, _InputIter __last, + _OutputIter __result) { + typedef typename iterator_traits<_InputIter>::iterator_category _Category; + typedef typename iterator_traits<_InputIter>::difference_type _Distance; + return __copy(__first, __last, __result, _Category(), (_Distance*) 0); + } +}; + +template <class _Tp> +struct __copy_dispatch<_Tp*, _Tp*, __true_type> { - 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()); + static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) { + return __copy_trivial(__first, __last, __result); } }; -template <class T> -struct __copy_dispatch<const T*, T*> +template <class _Tp> +struct __copy_dispatch<const _Tp*, _Tp*, __true_type> { - 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()); + static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) { + return __copy_trivial(__first, __last, __result); } }; -#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ +template <class _InputIter, class _OutputIter> +inline _OutputIter copy(_InputIter __first, _InputIter __last, + _OutputIter __result) { + typedef typename iterator_traits<_InputIter>::value_type _Tp; + typedef typename __type_traits<_Tp>::has_trivial_assignment_operator + _Trivial; + return __copy_dispatch<_InputIter, _OutputIter, _Trivial> + ::copy(__first, __last, __result); +} + +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ -template <class InputIterator, class OutputIterator> -inline OutputIterator copy(InputIterator first, InputIterator last, - OutputIterator result) +template <class _InputIter, class _OutputIter> +inline _OutputIter copy(_InputIter __first, _InputIter __last, + _OutputIter __result) { - return __copy_dispatch<InputIterator,OutputIterator>()(first, last, result); + return __copy(__first, __last, __result, + __ITERATOR_CATEGORY(__first), + __DISTANCE_TYPE(__first)); } -inline char* copy(const char* first, const char* last, char* result) { - memmove(result, first, last - first); - return result + (last - first); +inline char* copy(const char* __first, const char* __last, char* __result) { + memmove(__result, __first, __last - __first); + return __result + (__last - __first); } -inline wchar_t* copy(const wchar_t* first, const wchar_t* last, - wchar_t* result) { - memmove(result, first, sizeof(wchar_t) * (last - first)); - return result + (last - first); +inline wchar_t* copy(const wchar_t* __first, const wchar_t* __last, + wchar_t* __result) { + memmove(__result, __first, sizeof(wchar_t) * (__last - __first)); + return __result + (__last - __first); } -template <class BidirectionalIterator1, class BidirectionalIterator2> -inline BidirectionalIterator2 __copy_backward(BidirectionalIterator1 first, - BidirectionalIterator1 last, - BidirectionalIterator2 result) { - while (first != last) *--result = *--last; - return result; -} +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ +//-------------------------------------------------- +// copy_backward -template <class BidirectionalIterator1, class BidirectionalIterator2> -struct __copy_backward_dispatch +template <class _BidirectionalIter1, class _BidirectionalIter2, + class _Distance> +inline _BidirectionalIter2 __copy_backward(_BidirectionalIter1 __first, + _BidirectionalIter1 __last, + _BidirectionalIter2 __result, + bidirectional_iterator_tag, + _Distance*) { - BidirectionalIterator2 operator()(BidirectionalIterator1 first, - BidirectionalIterator1 last, - BidirectionalIterator2 result) { - return __copy_backward(first, last, result); - } -}; + while (__first != __last) + *--__result = *--__last; + return __result; +} + +template <class _RandomAccessIter, class _BidirectionalIter, class _Distance> +inline _BidirectionalIter __copy_backward(_RandomAccessIter __first, + _RandomAccessIter __last, + _BidirectionalIter __result, + random_access_iterator_tag, + _Distance*) +{ + for (_Distance __n = __last - __first; __n > 0; --__n) + *--__result = *--__last; + return __result; +} #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION -template <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; -} +// This dispatch class is a workaround for compilers that do not +// have partial ordering of function templates. All we're doing is +// creating a specialization so that we can turn a call to copy_backward +// into a memmove whenever possible. -template <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 _BidirectionalIter1, class _BidirectionalIter2, + class _BoolType> +struct __copy_backward_dispatch +{ + typedef typename iterator_traits<_BidirectionalIter1>::iterator_category + _Cat; + typedef typename iterator_traits<_BidirectionalIter1>::difference_type + _Distance; + + static _BidirectionalIter2 copy(_BidirectionalIter1 __first, + _BidirectionalIter1 __last, + _BidirectionalIter2 __result) { + return __copy_backward(__first, __last, __result, _Cat(), (_Distance*) 0); + } +}; -template <class T> -struct __copy_backward_dispatch<T*, T*> +template <class _Tp> +struct __copy_backward_dispatch<_Tp*, _Tp*, __true_type> { - 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()); + static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) { + const ptrdiff_t _Num = __last - __first; + memmove(__result - _Num, __first, sizeof(_Tp) * _Num); + return __result - _Num; } }; -template <class T> -struct __copy_backward_dispatch<const T*, T*> +template <class _Tp> +struct __copy_backward_dispatch<const _Tp*, _Tp*, __true_type> { - 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()); + static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) { + return __copy_backward_dispatch<_Tp*, _Tp*, __true_type> + ::copy(__first, __last, __result); } }; -#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ +template <class _BI1, class _BI2> +inline _BI2 copy_backward(_BI1 __first, _BI1 __last, _BI2 __result) { + typedef typename __type_traits<typename iterator_traits<_BI2>::value_type> + ::has_trivial_assignment_operator + _Trivial; + return __copy_backward_dispatch<_BI1, _BI2, _Trivial> + ::copy(__first, __last, __result); +} + +#else /* __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 _BI1, class _BI2> +inline _BI2 copy_backward(_BI1 __first, _BI1 __last, _BI2 __result) { + return __copy_backward(__first, __last, __result, + __ITERATOR_CATEGORY(__first), + __DISTANCE_TYPE(__first)); } -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); +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +//-------------------------------------------------- +// copy_n (not part of the C++ standard) + +template <class _InputIter, class _Size, class _OutputIter> +pair<_InputIter, _OutputIter> __copy_n(_InputIter __first, _Size __count, + _OutputIter __result, + input_iterator_tag) { + for ( ; __count > 0; --__count) { + *__result = *__first; + ++__first; + ++__result; + } + return pair<_InputIter, _OutputIter>(__first, __result); } -template <class RandomAccessIterator, class Size, class OutputIterator> -inline pair<RandomAccessIterator, OutputIterator> -__copy_n(RandomAccessIterator first, Size count, - OutputIterator result, +template <class _RAIter, class _Size, class _OutputIter> +inline pair<_RAIter, _OutputIter> +__copy_n(_RAIter __first, _Size __count, + _OutputIter __result, random_access_iterator_tag) { - RandomAccessIterator last = first + count; - return pair<RandomAccessIterator, OutputIterator>(last, - copy(first, last, result)); + _RAIter __last = __first + __count; + return pair<_RAIter, _OutputIter>(__last, copy(__first, __last, __result)); +} + +template <class _InputIter, class _Size, class _OutputIter> +inline pair<_InputIter, _OutputIter> +__copy_n(_InputIter __first, _Size __count, _OutputIter __result) { + return __copy_n(__first, __count, __result, + __ITERATOR_CATEGORY(__first)); } -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 _InputIter, class _Size, class _OutputIter> +inline pair<_InputIter, _OutputIter> +copy_n(_InputIter __first, _Size __count, _OutputIter __result) { + return __copy_n(__first, __count, __result); } -template <class ForwardIterator, class T> -void fill(ForwardIterator first, ForwardIterator last, const T& value) { - for ( ; first != last; ++first) - *first = value; +//-------------------------------------------------- +// fill and fill_n + + +template <class _ForwardIter, class _Tp> +void fill(_ForwardIter __first, _ForwardIter __last, const _Tp& __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 _OutputIter, class _Size, class _Tp> +_OutputIter fill_n(_OutputIter __first, _Size __n, const _Tp& __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; +//-------------------------------------------------- +// equal and mismatch + +template <class _InputIter1, class _InputIter2> +pair<_InputIter1, _InputIter2> mismatch(_InputIter1 __first1, + _InputIter1 __last1, + _InputIter2 __first2) { + while (__first1 != __last1 && *__first1 == *__first2) { + ++__first1; + ++__first2; } - return pair<InputIterator1, InputIterator2>(first1, first2); + return pair<_InputIter1, _InputIter2>(__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; +template <class _InputIter1, class _InputIter2, class _BinaryPredicate> +pair<_InputIter1, _InputIter2> mismatch(_InputIter1 __first1, + _InputIter1 __last1, + _InputIter2 __first2, + _BinaryPredicate __binary_pred) { + while (__first1 != __last1 && __binary_pred(*__first1, *__first2)) { + ++__first1; + ++__first2; } - return pair<InputIterator1, InputIterator2>(first1, first2); + return pair<_InputIter1, _InputIter2>(__first1, __first2); } -template <class InputIterator1, class InputIterator2> -inline bool equal(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2) { - for ( ; first1 != last1; ++first1, ++first2) - if (*first1 != *first2) +template <class _InputIter1, class _InputIter2> +inline bool equal(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __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)) +template <class _InputIter1, class _InputIter2, class _BinaryPredicate> +inline bool equal(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _BinaryPredicate __binary_pred) { + for ( ; __first1 != __last1; ++__first1, ++__first2) + if (!__binary_pred(*__first1, *__first2)) return false; return true; } -template <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) +//-------------------------------------------------- +// lexicographical_compare and lexicographical_compare_3way. +// (the latter is not part of the C++ standard.) + +template <class _InputIter1, class _InputIter2> +bool lexicographical_compare(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2) { + for ( ; __first1 != __last1 && __first2 != __last2 + ; ++__first1, ++__first2) { + if (*__first1 < *__first2) return true; - if (*first2 < *first1) + if (*__first2 < *__first1) return false; } - return first1 == last1 && first2 != last2; + return __first1 == __last1 && __first2 != __last2; } -template <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)) +template <class _InputIter1, class _InputIter2, class _Compare> +bool lexicographical_compare(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _Compare __comp) { + for ( ; __first1 != __last1 && __first2 != __last2 + ; ++__first1, ++__first2) { + if (__comp(*__first1, *__first2)) return true; - if (comp(*first2, *first1)) + if (__comp(*__first2, *__first1)) return false; } - return first1 == last1 && first2 != last2; + return __first1 == __last1 && __first2 != __last2; } inline bool -lexicographical_compare(const unsigned char* first1, - const unsigned char* last1, - const unsigned char* first2, - const unsigned char* last2) +lexicographical_compare(const unsigned char* __first1, + const unsigned char* __last1, + const unsigned char* __first2, + const unsigned char* __last2) { - const size_t len1 = last1 - first1; - const size_t len2 = last2 - first2; - const int result = memcmp(first1, first2, min(len1, len2)); - return result != 0 ? result < 0 : len1 < len2; + const size_t __len1 = __last1 - __first1; + const size_t __len2 = __last2 - __first2; + const int __result = memcmp(__first1, __first2, min(__len1, __len2)); + return __result != 0 ? __result < 0 : __len1 < __len2; } -inline bool lexicographical_compare(const char* first1, const char* last1, - const char* first2, const char* last2) +inline bool lexicographical_compare(const char* __first1, const char* __last1, + const char* __first2, const char* __last2) { #if CHAR_MAX == SCHAR_MAX - return lexicographical_compare((const signed char*) first1, - (const signed char*) last1, - (const signed char*) first2, - (const signed char*) last2); -#else - return lexicographical_compare((const unsigned char*) first1, - (const unsigned char*) last1, - (const unsigned char*) first2, - (const unsigned char*) last2); -#endif -} - -template <class InputIterator1, class InputIterator2> -int lexicographical_compare_3way(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2) + return lexicographical_compare((const signed char*) __first1, + (const signed char*) __last1, + (const signed char*) __first2, + (const signed char*) __last2); +#else /* CHAR_MAX == SCHAR_MAX */ + return lexicographical_compare((const unsigned char*) __first1, + (const unsigned char*) __last1, + (const unsigned char*) __first2, + (const unsigned char*) __last2); +#endif /* CHAR_MAX == SCHAR_MAX */ +} + +template <class _InputIter1, class _InputIter2> +int __lexicographical_compare_3way(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2) { - while (first1 != last1 && first2 != last2) { - if (*first1 < *first2) return -1; - if (*first2 < *first1) return 1; - ++first1; ++first2; + while (__first1 != __last1 && __first2 != __last2) { + if (*__first1 < *__first2) + return -1; + if (*__first2 < *__first1) + return 1; + ++__first1; + ++__first2; + } + if (__first2 == __last2) { + return !(__first1 == __last1); } - if (first2 == last2) { - return !(first1 == last1); - } else { + else { return -1; } } inline int -lexicographical_compare_3way(const unsigned char* first1, - const unsigned char* last1, - const unsigned char* first2, - const unsigned char* last2) +__lexicographical_compare_3way(const unsigned char* __first1, + const unsigned char* __last1, + const unsigned char* __first2, + const unsigned char* __last2) { - const ptrdiff_t len1 = last1 - first1; - const ptrdiff_t len2 = last2 - first2; - const int result = memcmp(first1, first2, min(len1, len2)); - return result != 0 ? result : (len1 == len2 ? 0 : (len1 < len2 ? -1 : 1)); + const ptrdiff_t __len1 = __last1 - __first1; + const ptrdiff_t __len2 = __last2 - __first2; + const int __result = memcmp(__first1, __first2, min(__len1, __len2)); + return __result != 0 ? __result + : (__len1 == __len2 ? 0 : (__len1 < __len2 ? -1 : 1)); } -inline int lexicographical_compare_3way(const char* first1, const char* last1, - const char* first2, const char* last2) +inline int +__lexicographical_compare_3way(const char* __first1, const char* __last1, + const char* __first2, const char* __last2) { #if CHAR_MAX == SCHAR_MAX - return lexicographical_compare_3way( - (const signed char*) first1, - (const signed char*) last1, - (const signed char*) first2, - (const signed char*) last2); + return __lexicographical_compare_3way( + (const signed char*) __first1, + (const signed char*) __last1, + (const signed char*) __first2, + (const signed char*) __last2); #else - return lexicographical_compare_3way((const unsigned char*) first1, - (const unsigned char*) last1, - (const unsigned char*) first2, - (const unsigned char*) last2); + return __lexicographical_compare_3way((const unsigned char*) __first1, + (const unsigned char*) __last1, + (const unsigned char*) __first2, + (const unsigned char*) __last2); #endif } +template <class _InputIter1, class _InputIter2> +int lexicographical_compare_3way(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2) +{ + return __lexicographical_compare_3way(__first1, __last1, __first2, __last2); +} + __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_ALGOBASE_H */ diff --git a/contrib/libstdc++/stl/stl_alloc.h b/contrib/libstdc++/stl/stl_alloc.h index 2c3de40..208309a 100644 --- a/contrib/libstdc++/stl/stl_alloc.h +++ b/contrib/libstdc++/stl/stl_alloc.h @@ -40,15 +40,12 @@ #if 0 # include <new> -# define __THROW_BAD_ALLOC throw bad_alloc +# 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 @@ -61,7 +58,8 @@ # define __RESTRICT #endif -#if !defined(__STL_PTHREADS) && !defined(_NOTHREADS) \ +#if !defined(__STL_PTHREADS) && !defined(__STL_SOLTHREADS) \ + && !defined(_NOTHREADS) \ && !defined(__STL_SGI_THREADS) && !defined(__STL_WIN32THREADS) # define _NOTHREADS #endif @@ -72,19 +70,28 @@ // lock. Performance may not be adequate. # include <pthread.h> # define __NODE_ALLOCATOR_LOCK \ - if (threads) pthread_mutex_lock(&__node_allocator_lock) + if (threads) pthread_mutex_lock(&_S_node_allocator_lock) # define __NODE_ALLOCATOR_UNLOCK \ - if (threads) pthread_mutex_unlock(&__node_allocator_lock) + if (threads) pthread_mutex_unlock(&_S_node_allocator_lock) # define __NODE_ALLOCATOR_THREADS true # define __VOLATILE volatile // Needed at -O3 on SGI # endif +# ifdef __STL_SOLTHREADS +# include <thread.h> +# define __NODE_ALLOCATOR_LOCK \ + if (threads) mutex_lock(&_S_node_allocator_lock) +# define __NODE_ALLOCATOR_UNLOCK \ + if (threads) mutex_unlock(&_S_node_allocator_lock) +# define __NODE_ALLOCATOR_THREADS true +# define __VOLATILE +# endif # ifdef __STL_WIN32THREADS // The lock needs to be initialized by constructing an allocator // objects of the right type. We do that here explicitly for alloc. # define __NODE_ALLOCATOR_LOCK \ - EnterCriticalSection(&__node_allocator_lock) + EnterCriticalSection(&_S_node_allocator_lock) # define __NODE_ALLOCATOR_UNLOCK \ - LeaveCriticalSection(&__node_allocator_lock) + LeaveCriticalSection(&_S_node_allocator_lock) # define __NODE_ALLOCATOR_THREADS true # define __VOLATILE volatile // may not be needed # endif /* WIN32THREADS */ @@ -100,9 +107,9 @@ // would be cleaner but fails with certain levels of standard // conformance. # define __NODE_ALLOCATOR_LOCK if (threads && __us_rsthread_malloc) \ - { __lock(&__node_allocator_lock); } + { _S_lock(&_S_node_allocator_lock); } # define __NODE_ALLOCATOR_UNLOCK if (threads && __us_rsthread_malloc) \ - { __unlock(&__node_allocator_lock); } + { _S_unlock(&_S_node_allocator_lock); } # define __NODE_ALLOCATOR_THREADS true # define __VOLATILE volatile // Needed at -O3 on SGI # endif @@ -131,100 +138,100 @@ __STL_BEGIN_NAMESPACE # endif #endif -template <int inst> +template <int __inst> class __malloc_alloc_template { private: -static void *oom_malloc(size_t); - -static void *oom_realloc(void *, size_t); + static void* _S_oom_malloc(size_t); + static void* _S_oom_realloc(void*, size_t); #ifndef __STL_STATIC_TEMPLATE_MEMBER_BUG - static void (* __malloc_alloc_oom_handler)(); + static void (* __malloc_alloc_oom_handler)(); #endif public: -static void * allocate(size_t n) -{ - void *result = malloc(n); - if (0 == result) result = oom_malloc(n); - return result; -} + static void* allocate(size_t __n) + { + void* __result = malloc(__n); + if (0 == __result) __result = _S_oom_malloc(__n); + return __result; + } -static void deallocate(void *p, size_t /* n */) -{ - free(p); -} + static void deallocate(void* __p, size_t /* __n */) + { + free(__p); + } -static void * reallocate(void *p, size_t /* old_sz */, size_t new_sz) -{ - void * result = realloc(p, new_sz); - if (0 == result) result = oom_realloc(p, new_sz); - return result; -} + static void* reallocate(void* __p, size_t /* old_sz */, size_t __new_sz) + { + void* __result = realloc(__p, __new_sz); + if (0 == __result) __result = _S_oom_realloc(__p, __new_sz); + return __result; + } -static void (* set_malloc_handler(void (*f)()))() -{ - void (* old)() = __malloc_alloc_oom_handler; - __malloc_alloc_oom_handler = f; - return(old); -} + static void (* __set_malloc_handler(void (*__f)()))() + { + void (* __old)() = __malloc_alloc_oom_handler; + __malloc_alloc_oom_handler = __f; + return(__old); + } }; // malloc_alloc out-of-memory handling #ifndef __STL_STATIC_TEMPLATE_MEMBER_BUG -template <int inst> -void (* __malloc_alloc_template<inst>::__malloc_alloc_oom_handler)() = 0; +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) +template <int __inst> +void* +__malloc_alloc_template<__inst>::_S_oom_malloc(size_t __n) { - void (* my_malloc_handler)(); - void *result; + void (* __my_malloc_handler)(); + void* __result; for (;;) { - my_malloc_handler = __malloc_alloc_oom_handler; - if (0 == my_malloc_handler) { __THROW_BAD_ALLOC; } - (*my_malloc_handler)(); - result = malloc(n); - if (result) return(result); + __my_malloc_handler = __malloc_alloc_oom_handler; + if (0 == __my_malloc_handler) { __THROW_BAD_ALLOC; } + (*__my_malloc_handler)(); + __result = malloc(__n); + if (__result) return(__result); } } -template <int inst> -void * __malloc_alloc_template<inst>::oom_realloc(void *p, size_t n) +template <int __inst> +void* __malloc_alloc_template<__inst>::_S_oom_realloc(void* __p, size_t __n) { - void (* my_malloc_handler)(); - void *result; + void (* __my_malloc_handler)(); + void* __result; for (;;) { - my_malloc_handler = __malloc_alloc_oom_handler; - if (0 == my_malloc_handler) { __THROW_BAD_ALLOC; } - (*my_malloc_handler)(); - result = realloc(p, n); - if (result) return(result); + __my_malloc_handler = __malloc_alloc_oom_handler; + if (0 == __my_malloc_handler) { __THROW_BAD_ALLOC; } + (*__my_malloc_handler)(); + __result = realloc(__p, __n); + if (__result) return(__result); } } typedef __malloc_alloc_template<0> malloc_alloc; -template<class T, class Alloc> +template<class _Tp, 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)); } + static _Tp* allocate(size_t __n) + { return 0 == __n ? 0 : (_Tp*) _Alloc::allocate(__n * sizeof (_Tp)); } + static _Tp* allocate(void) + { return (_Tp*) _Alloc::allocate(sizeof (_Tp)); } + static void deallocate(_Tp* __p, size_t __n) + { if (0 != __n) _Alloc::deallocate(__p, __n * sizeof (_Tp)); } + static void deallocate(_Tp* __p) + { _Alloc::deallocate(__p, sizeof (_Tp)); } }; // Allocator adaptor to check size arguments for debugging. @@ -232,41 +239,40 @@ public: // NDEBUG, but it's far better to just use the underlying allocator // instead when no checking is desired. // There is some evidence that this can confuse Purify. -template <class Alloc> +template <class _Alloc> class debug_alloc { private: -enum {extra = 8}; // Size of space used to store size. Note + enum {_S_extra = 8}; // Size of space used to store size. Note // that this must be large enough to preserve // alignment. public: -static void * allocate(size_t n) -{ - char *result = (char *)Alloc::allocate(n + extra); - *(size_t *)result = n; - return result + extra; -} - -static void deallocate(void *p, size_t n) -{ - char * real_p = (char *)p - extra; - assert(*(size_t *)real_p == n); - Alloc::deallocate(real_p, n + extra); -} + static void* allocate(size_t __n) + { + char* __result = (char*)_Alloc::allocate(__n + _S_extra); + *(size_t*)__result = __n; + return __result + _S_extra; + } -static void * reallocate(void *p, size_t old_sz, size_t new_sz) -{ - char * real_p = (char *)p - extra; - assert(*(size_t *)real_p == old_sz); - char * result = (char *) - Alloc::reallocate(real_p, old_sz + extra, new_sz + extra); - *(size_t *)result = new_sz; - return result + extra; -} + static void deallocate(void* __p, size_t __n) + { + char* __real_p = (char*)__p - _S_extra; + assert(*(size_t*)__real_p == __n); + _Alloc::deallocate(__real_p, __n + _S_extra); + } + static void* reallocate(void* __p, size_t __old_sz, size_t __new_sz) + { + char* __real_p = (char*)__p - _S_extra; + assert(*(size_t*)__real_p == __old_sz); + char* __result = (char*) + _Alloc::reallocate(__real_p, __old_sz + _S_extra, __new_sz + _S_extra); + *(size_t*)__result = __new_sz; + return __result + _S_extra; + } }; @@ -286,10 +292,10 @@ typedef malloc_alloc single_client_alloc; // DISAPPEAR in the future. Clients should just use alloc for now. // // Important implementation properties: -// 1. If the client request an object of size > __MAX_BYTES, the resulting +// 1. If the client request an object of size > _MAX_BYTES, the resulting // object will be obtained directly from malloc. // 2. In all other cases, we allocate an object of size exactly -// ROUND_UP(requested_size). Thus the client has enough size +// _S_round_up(requested_size). Thus the client has enough size // information that we can return the object to the proper free list // without permanently losing part of the object. // @@ -305,9 +311,9 @@ typedef malloc_alloc single_client_alloc; // different types, limiting the utility of this approach. #ifdef __SUNPRO_CC // breaks if we make these template class members: - enum {__ALIGN = 8}; - enum {__MAX_BYTES = 128}; - enum {__NFREELISTS = __MAX_BYTES/__ALIGN}; + enum {_ALIGN = 8}; + enum {_MAX_BYTES = 128}; + enum {_NFREELISTS = _MAX_BYTES/_ALIGN}; #endif template <bool threads, int inst> @@ -317,123 +323,128 @@ private: // Really we should use static const int x = N // instead of enum { x = N }, but few compilers accept the former. # ifndef __SUNPRO_CC - enum {__ALIGN = 8}; - enum {__MAX_BYTES = 128}; - enum {__NFREELISTS = __MAX_BYTES/__ALIGN}; + enum {_ALIGN = 8}; + enum {_MAX_BYTES = 128}; + enum {_NFREELISTS = _MAX_BYTES/_ALIGN}; # endif - static size_t ROUND_UP(size_t bytes) { - return (((bytes) + __ALIGN-1) & ~(__ALIGN - 1)); - } + static size_t + _S_round_up(size_t __bytes) + { return (((__bytes) + _ALIGN-1) & ~(_ALIGN - 1)); } + __PRIVATE: - union obj { - union obj * free_list_link; - char client_data[1]; /* The client sees this. */ + union _Obj { + union _Obj* _M_free_list_link; + char _M_client_data[1]; /* The client sees this. */ }; private: # ifdef __SUNPRO_CC - static obj * __VOLATILE free_list[]; + static _Obj* __VOLATILE _S_free_list[]; // Specifying a size results in duplicate def for 4.1 # else - static obj * __VOLATILE free_list[__NFREELISTS]; + static _Obj* __VOLATILE _S_free_list[_NFREELISTS]; # endif - static size_t FREELIST_INDEX(size_t bytes) { - return (((bytes) + __ALIGN-1)/__ALIGN - 1); + static size_t _S_freelist_index(size_t __bytes) { + return (((__bytes) + _ALIGN-1)/_ALIGN - 1); } - // Returns an object of size n, and optionally adds to size n free list. - static void *refill(size_t n); + // Returns an object of size __n, and optionally adds to size __n free list. + static void* _S_refill(size_t __n); // Allocates a chunk for nobjs of size "size". nobjs may be reduced // if it is inconvenient to allocate the requested number. - static char *chunk_alloc(size_t size, int &nobjs); + static char* _S_chunk_alloc(size_t __size, int& __nobjs); // Chunk allocation state. - static char *start_free; - static char *end_free; - static size_t heap_size; + static char* _S_start_free; + static char* _S_end_free; + static size_t _S_heap_size; # ifdef __STL_SGI_THREADS - static volatile unsigned long __node_allocator_lock; - static void __lock(volatile unsigned long *); - static inline void __unlock(volatile unsigned long *); + static volatile unsigned long _S_node_allocator_lock; + static void _S_lock(volatile unsigned long*); + static inline void _S_unlock(volatile unsigned long*); # endif # ifdef __STL_PTHREADS - static pthread_mutex_t __node_allocator_lock; + static pthread_mutex_t _S_node_allocator_lock; +# endif + +# ifdef __STL_SOLTHREADS + static mutex_t _S_node_allocator_lock; # endif # ifdef __STL_WIN32THREADS - static CRITICAL_SECTION __node_allocator_lock; - static bool __node_allocator_lock_initialized; + static CRITICAL_SECTION _S_node_allocator_lock; + static bool _S_node_allocator_lock_initialized; public: __default_alloc_template() { // This assumes the first constructor is called before threads // are started. - if (!__node_allocator_lock_initialized) { - InitializeCriticalSection(&__node_allocator_lock); - __node_allocator_lock_initialized = true; + if (!_S_node_allocator_lock_initialized) { + InitializeCriticalSection(&_S_node_allocator_lock); + _S_node_allocator_lock_initialized = true; } } private: # endif - class lock { + class _Lock { public: - lock() { __NODE_ALLOCATOR_LOCK; } - ~lock() { __NODE_ALLOCATOR_UNLOCK; } + _Lock() { __NODE_ALLOCATOR_LOCK; } + ~_Lock() { __NODE_ALLOCATOR_UNLOCK; } }; - friend class lock; + friend class _Lock; public: - /* n must be > 0 */ - static void * allocate(size_t n) + /* __n must be > 0 */ + static void* allocate(size_t __n) { - obj * __VOLATILE * my_free_list; - obj * __RESTRICT result; + _Obj* __VOLATILE* __my_free_list; + _Obj* __RESTRICT __result; - if (n > (size_t) __MAX_BYTES) { - return(malloc_alloc::allocate(n)); + if (__n > (size_t) _MAX_BYTES) { + return(malloc_alloc::allocate(__n)); } - my_free_list = free_list + FREELIST_INDEX(n); + __my_free_list = _S_free_list + _S_freelist_index(__n); // Acquire the lock here with a constructor call. // This ensures that it is released in exit or during stack // unwinding. # ifndef _NOTHREADS /*REFERENCED*/ - lock lock_instance; + _Lock __lock_instance; # endif - result = *my_free_list; - if (result == 0) { - void *r = refill(ROUND_UP(n)); - return r; + __result = *__my_free_list; + if (__result == 0) { + void* __r = _S_refill(_S_round_up(__n)); + return __r; } - *my_free_list = result -> free_list_link; - return (result); + *__my_free_list = __result -> _M_free_list_link; + return (__result); }; - /* p may not be 0 */ - static void deallocate(void *p, size_t n) + /* __p may not be 0 */ + static void deallocate(void* __p, size_t __n) { - obj *q = (obj *)p; - obj * __VOLATILE * my_free_list; + _Obj* __q = (_Obj*)__p; + _Obj* __VOLATILE* __my_free_list; - if (n > (size_t) __MAX_BYTES) { - malloc_alloc::deallocate(p, n); + if (__n > (size_t) _MAX_BYTES) { + malloc_alloc::deallocate(__p, __n); return; } - my_free_list = free_list + FREELIST_INDEX(n); + __my_free_list = _S_free_list + _S_freelist_index(__n); // acquire lock # ifndef _NOTHREADS /*REFERENCED*/ - lock lock_instance; + _Lock __lock_instance; # endif /* _NOTHREADS */ - q -> free_list_link = *my_free_list; - *my_free_list = q; + __q -> _M_free_list_link = *__my_free_list; + *__my_free_list = __q; // lock is released here } - static void * reallocate(void *p, size_t old_sz, size_t new_sz); + static void* reallocate(void* __p, size_t __old_sz, size_t __new_sz); } ; @@ -446,229 +457,250 @@ typedef __default_alloc_template<false, 0> single_client_alloc; /* the malloc heap too much. */ /* We assume that size is properly aligned. */ /* We hold the allocation lock. */ -template <bool threads, int inst> +template <bool __threads, int __inst> char* -__default_alloc_template<threads, inst>::chunk_alloc(size_t size, int& nobjs) +__default_alloc_template<__threads, __inst>::_S_chunk_alloc(size_t __size, + int& __nobjs) { - char * result; - size_t total_bytes = size * nobjs; - size_t bytes_left = end_free - start_free; - - if (bytes_left >= total_bytes) { - result = start_free; - start_free += total_bytes; - return(result); - } else if (bytes_left >= size) { - nobjs = bytes_left/size; - total_bytes = size * nobjs; - result = start_free; - start_free += total_bytes; - return(result); + char* __result; + size_t __total_bytes = __size * __nobjs; + size_t __bytes_left = _S_end_free - _S_start_free; + + if (__bytes_left >= __total_bytes) { + __result = _S_start_free; + _S_start_free += __total_bytes; + return(__result); + } else if (__bytes_left >= __size) { + __nobjs = (int)(__bytes_left/__size); + __total_bytes = __size * __nobjs; + __result = _S_start_free; + _S_start_free += __total_bytes; + return(__result); } else { - size_t bytes_to_get = 2 * total_bytes + ROUND_UP(heap_size >> 4); + size_t __bytes_to_get = + 2 * __total_bytes + _S_round_up(_S_heap_size >> 4); // Try to make use of the left-over piece. - if (bytes_left > 0) { - obj * __VOLATILE * my_free_list = - free_list + FREELIST_INDEX(bytes_left); + if (__bytes_left > 0) { + _Obj* __VOLATILE* __my_free_list = + _S_free_list + _S_freelist_index(__bytes_left); - ((obj *)start_free) -> free_list_link = *my_free_list; - *my_free_list = (obj *)start_free; + ((_Obj*)_S_start_free) -> _M_free_list_link = *__my_free_list; + *__my_free_list = (_Obj*)_S_start_free; } - start_free = (char *)malloc(bytes_to_get); - if (0 == start_free) { - int i; - obj * __VOLATILE * my_free_list, *p; + _S_start_free = (char*)malloc(__bytes_to_get); + if (0 == _S_start_free) { + size_t __i; + _Obj* __VOLATILE* __my_free_list; + _Obj* __p; // Try to make do with what we have. That can't // hurt. We do not try smaller requests, since that tends // to result in disaster on multi-process machines. - for (i = size; i <= __MAX_BYTES; i += __ALIGN) { - my_free_list = free_list + FREELIST_INDEX(i); - p = *my_free_list; - if (0 != p) { - *my_free_list = p -> free_list_link; - start_free = (char *)p; - end_free = start_free + i; - return(chunk_alloc(size, nobjs)); + for (__i = __size; __i <= _MAX_BYTES; __i += _ALIGN) { + __my_free_list = _S_free_list + _S_freelist_index(__i); + __p = *__my_free_list; + if (0 != __p) { + *__my_free_list = __p -> _M_free_list_link; + _S_start_free = (char*)__p; + _S_end_free = _S_start_free + __i; + return(_S_chunk_alloc(__size, __nobjs)); // Any leftover piece will eventually make it to the // right free list. } } - end_free = 0; // In case of exception. - start_free = (char *)malloc_alloc::allocate(bytes_to_get); + _S_end_free = 0; // In case of exception. + _S_start_free = (char*)malloc_alloc::allocate(__bytes_to_get); // This should either throw an // exception or remedy the situation. Thus we assume it // succeeded. } - heap_size += bytes_to_get; - end_free = start_free + bytes_to_get; - return(chunk_alloc(size, nobjs)); + _S_heap_size += __bytes_to_get; + _S_end_free = _S_start_free + __bytes_to_get; + return(_S_chunk_alloc(__size, __nobjs)); } } -/* Returns an object of size n, and optionally adds to size n free list.*/ -/* We assume that n is properly aligned. */ +/* Returns an object of size __n, and optionally adds to size __n free list.*/ +/* We assume that __n is properly aligned. */ /* We hold the allocation lock. */ -template <bool threads, int inst> -void* __default_alloc_template<threads, inst>::refill(size_t n) +template <bool __threads, int __inst> +void* +__default_alloc_template<__threads, __inst>::_S_refill(size_t __n) { - int nobjs = 20; - char * chunk = chunk_alloc(n, nobjs); - obj * __VOLATILE * my_free_list; - obj * result; - obj * current_obj, * next_obj; - int i; + int __nobjs = 20; + char* __chunk = _S_chunk_alloc(__n, __nobjs); + _Obj* __VOLATILE* __my_free_list; + _Obj* __result; + _Obj* __current_obj; + _Obj* __next_obj; + int __i; - if (1 == nobjs) return(chunk); - my_free_list = free_list + FREELIST_INDEX(n); + if (1 == __nobjs) return(__chunk); + __my_free_list = _S_free_list + _S_freelist_index(__n); /* Build free list in chunk */ - result = (obj *)chunk; - *my_free_list = next_obj = (obj *)(chunk + n); - for (i = 1; ; i++) { - current_obj = next_obj; - next_obj = (obj *)((char *)next_obj + n); - if (nobjs - 1 == i) { - current_obj -> free_list_link = 0; + __result = (_Obj*)__chunk; + *__my_free_list = __next_obj = (_Obj*)(__chunk + __n); + for (__i = 1; ; __i++) { + __current_obj = __next_obj; + __next_obj = (_Obj*)((char*)__next_obj + __n); + if (__nobjs - 1 == __i) { + __current_obj -> _M_free_list_link = 0; break; } else { - current_obj -> free_list_link = next_obj; + __current_obj -> _M_free_list_link = __next_obj; } } - return(result); + return(__result); } template <bool threads, int inst> void* -__default_alloc_template<threads, inst>::reallocate(void *p, - size_t old_sz, - size_t new_sz) +__default_alloc_template<threads, inst>::reallocate(void* __p, + size_t __old_sz, + size_t __new_sz) { - void * result; - size_t copy_sz; + void* __result; + size_t __copy_sz; - if (old_sz > (size_t) __MAX_BYTES && new_sz > (size_t) __MAX_BYTES) { - return(realloc(p, new_sz)); + if (__old_sz > (size_t) _MAX_BYTES && __new_sz > (size_t) _MAX_BYTES) { + return(realloc(__p, __new_sz)); } - if (ROUND_UP(old_sz) == ROUND_UP(new_sz)) return(p); - result = allocate(new_sz); - copy_sz = new_sz > old_sz? old_sz : new_sz; - memcpy(result, p, copy_sz); - deallocate(p, old_sz); - return(result); + if (_S_round_up(__old_sz) == _S_round_up(__new_sz)) return(__p); + __result = allocate(__new_sz); + __copy_sz = __new_sz > __old_sz? __old_sz : __new_sz; + memcpy(__result, __p, __copy_sz); + deallocate(__p, __old_sz); + return(__result); } #ifdef __STL_PTHREADS - template <bool threads, int inst> + template <bool __threads, int __inst> pthread_mutex_t - __default_alloc_template<threads, inst>::__node_allocator_lock + __default_alloc_template<__threads, __inst>::_S_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; +#ifdef __STL_SOLTHREADS + template <bool __threads, int __inst> + mutex_t + __default_alloc_template<__threads, __inst>::_S_node_allocator_lock + = DEFAULTMUTEX; +#endif - template <bool threads, int inst> bool - __default_alloc_template<threads, inst>::__node_allocator_lock_initialized +#ifdef __STL_WIN32THREADS + template <bool __threads, int __inst> + CRITICAL_SECTION + __default_alloc_template<__threads, __inst>:: + _S_node_allocator_lock; + + template <bool __threads, int __inst> + bool + __default_alloc_template<__threads, __inst>:: + _S_node_allocator_lock_initialized = false; #endif #ifdef __STL_SGI_THREADS __STL_END_NAMESPACE #include <mutex.h> -#include <time.h> +#include <time.h> /* XXX should use <ctime> */ __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> +template <bool __threads, int __inst> volatile unsigned long -__default_alloc_template<threads, inst>::__node_allocator_lock = 0; +__default_alloc_template<__threads, __inst>::_S_node_allocator_lock = 0; #if __mips < 3 || !(defined (_ABIN32) || defined(_ABI64)) || defined(__GNUC__) # define __test_and_set(l,v) test_and_set(l,v) #endif -template <bool threads, int inst> -void -__default_alloc_template<threads, inst>::__lock(volatile unsigned long *lock) +template <bool __threads, int __inst> +void +__default_alloc_template<__threads, __inst>:: + _S_lock(volatile unsigned long* __lock) { - const unsigned low_spin_max = 30; // spin cycles if we suspect uniprocessor - const unsigned high_spin_max = 1000; // spin cycles for multiprocessor - static unsigned spin_max = low_spin_max; - unsigned my_spin_max; - static unsigned last_spins = 0; - unsigned my_last_spins; - static struct timespec ts = {0, 1000}; - unsigned junk; -# define __ALLOC_PAUSE junk *= junk; junk *= junk; junk *= junk; junk *= junk - int i; - - if (!__test_and_set((unsigned long *)lock, 1)) { + const unsigned __low_spin_max = 30; // spins if we suspect uniprocessor + const unsigned __high_spin_max = 1000; // spins for multiprocessor + static unsigned __spin_max = __low_spin_max; + unsigned __my_spin_max; + static unsigned __last_spins = 0; + unsigned __my_last_spins; + unsigned __junk; +# define __ALLOC_PAUSE \ + __junk *= __junk; __junk *= __junk; __junk *= __junk; __junk *= __junk + int __i; + + if (!__test_and_set((unsigned long*)__lock, 1)) { return; } - my_spin_max = spin_max; - my_last_spins = last_spins; - for (i = 0; i < my_spin_max; i++) { - if (i < my_last_spins/2 || *lock) { + __my_spin_max = __spin_max; + __my_last_spins = __last_spins; + for (__i = 0; __i < __my_spin_max; __i++) { + if (__i < __my_last_spins/2 || *__lock) { __ALLOC_PAUSE; continue; } - if (!__test_and_set((unsigned long *)lock, 1)) { + if (!__test_and_set((unsigned long*)__lock, 1)) { // got it! // Spinning worked. Thus we're probably not being scheduled // against the other process with which we were contending. // Thus it makes sense to spin longer the next time. - last_spins = i; - spin_max = high_spin_max; + __last_spins = __i; + __spin_max = __high_spin_max; return; } } // We are probably being scheduled against the other process. Sleep. - spin_max = low_spin_max; - for (;;) { - if (!__test_and_set((unsigned long *)lock, 1)) { + __spin_max = __low_spin_max; + for (__i = 0 ;; ++__i) { + struct timespec __ts; + int __log_nsec = __i + 6; + + if (!__test_and_set((unsigned long *)__lock, 1)) { return; } - nanosleep(&ts, 0); + if (__log_nsec > 27) __log_nsec = 27; + /* Max sleep is 2**27nsec ~ 60msec */ + __ts.tv_sec = 0; + __ts.tv_nsec = 1 << __log_nsec; + nanosleep(&__ts, 0); } } -template <bool threads, int inst> +template <bool __threads, int __inst> inline void -__default_alloc_template<threads, inst>::__unlock(volatile unsigned long *lock) +__default_alloc_template<__threads, __inst>::_S_unlock( + volatile unsigned long* __lock) { # if defined(__GNUC__) && __mips >= 3 asm("sync"); - *lock = 0; + *__lock = 0; # elif __mips >= 3 && (defined (_ABIN32) || defined(_ABI64)) - __lock_release(lock); -# else - *lock = 0; + __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>::_S_start_free = 0; -template <bool threads, int inst> -char *__default_alloc_template<threads, inst>::end_free = 0; +template <bool __threads, int __inst> +char* __default_alloc_template<__threads, __inst>::_S_end_free = 0; -template <bool threads, int inst> -size_t __default_alloc_template<threads, inst>::heap_size = 0; +template <bool __threads, int __inst> +size_t __default_alloc_template<__threads, __inst>::_S_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 +template <bool __threads, int __inst> +__default_alloc_template<__threads, __inst>::_Obj* __VOLATILE +__default_alloc_template<__threads, __inst> ::_S_free_list[ + _NFREELISTS ] = {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 @@ -683,6 +715,333 @@ __default_alloc_template<threads, inst> ::free_list[ #endif /* ! __USE_MALLOC */ +// This implements allocators as specified in the C++ standard. +// +// Note that standard-conforming allocators use many language features +// that are not yet widely implemented. In particular, they rely on +// member templates, partial specialization, partial ordering of function +// templates, the typename keyword, and the use of the template keyword +// to refer to a template member of a dependent type. + +#ifdef __STL_USE_STD_ALLOCATORS + +template <class _Tp> +class allocator { + typedef alloc _Alloc; // The underlying allocator. +public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef _Tp value_type; + + template <class _Tp1> struct rebind { + typedef allocator<_Tp1> other; + }; + + allocator() __STL_NOTHROW {} + allocator(const allocator&) __STL_NOTHROW {} + template <class _Tp1> allocator(const allocator<_Tp1>&) __STL_NOTHROW {} + ~allocator() __STL_NOTHROW {} + + pointer address(reference __x) const { return &__x; } + const_pointer address(const_reference __x) const { return &__x; } + + // __n is permitted to be 0. The C++ standard says nothing about what + // the return value is when __n == 0. + _Tp* allocate(size_type __n, const void* = 0) { + return __n != 0 ? static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp))) + : 0; + } + + // __p is not permitted to be a null pointer. + void deallocate(pointer __p, size_type __n) + { _Alloc::deallocate(__p, __n * sizeof(_Tp)); } + + size_type max_size() const __STL_NOTHROW + { return size_t(-1) / sizeof(_Tp); } + + void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); } + void destroy(pointer __p) { __p->~_Tp(); } +}; + +template<> +class allocator<void> { + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef void* pointer; + typedef const void* const_pointer; + typedef void value_type; + + template <class _Tp1> struct rebind { + typedef allocator<_Tp1> other; + }; +}; + + +template <class _T1, class _T2> +inline bool operator==(const allocator<_T1>&, const allocator<_T2>&) +{ + return true; +} + +template <class _T1, class _T2> +inline bool operator!=(const allocator<_T1>&, const allocator<_T2>&) +{ + return false; +} + +// Allocator adaptor to turn an SGI-style allocator (e.g. alloc, malloc_alloc) +// into a standard-conforming allocator. Note that this adaptor does +// *not* assume that all objects of the underlying alloc class are +// identical, nor does it assume that all of the underlying alloc's +// member functions are static member functions. Note, also, that +// __allocator<_Tp, alloc> is essentially the same thing as allocator<_Tp>. + +template <class _Tp, class _Alloc> +struct __allocator { + _Alloc __underlying_alloc; + + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef _Tp value_type; + + template <class _Tp1> struct rebind { + typedef __allocator<_Tp1, _Alloc> other; + }; + + __allocator() __STL_NOTHROW {} + __allocator(const __allocator& __a) __STL_NOTHROW + : __underlying_alloc(__a.__underlying_alloc) {} + template <class _Tp1> + __allocator(const __allocator<_Tp1, _Alloc>& __a) __STL_NOTHROW + : __underlying_alloc(__a.__underlying_alloc) {} + ~__allocator() __STL_NOTHROW {} + + pointer address(reference __x) const { return &__x; } + const_pointer address(const_reference __x) const { return &__x; } + + // __n is permitted to be 0. + _Tp* allocate(size_type __n, const void* = 0) { + return __n != 0 + ? static_cast<_Tp*>(__underlying_alloc.allocate(__n * sizeof(_Tp))) + : 0; + } + + // __p is not permitted to be a null pointer. + void deallocate(pointer __p, size_type __n) + { __underlying_alloc.deallocate(__p, __n * sizeof(_Tp)); } + + size_type max_size() const __STL_NOTHROW + { return size_t(-1) / sizeof(_Tp); } + + void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); } + void destroy(pointer __p) { __p->~_Tp(); } +}; + +template <class _Alloc> +class __allocator<void, _Alloc> { + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef void* pointer; + typedef const void* const_pointer; + typedef void value_type; + + template <class _Tp1> struct rebind { + typedef __allocator<_Tp1, _Alloc> other; + }; +}; + +template <class _Tp, class _Alloc> +inline bool operator==(const __allocator<_Tp, _Alloc>& __a1, + const __allocator<_Tp, _Alloc>& __a2) +{ + return __a1.__underlying_alloc == __a2.__underlying_alloc; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER +template <class _Tp, class _Alloc> +inline bool operator!=(const __allocator<_Tp, _Alloc>& __a1, + const __allocator<_Tp, _Alloc>& __a2) +{ + return __a1.__underlying_alloc != __a2.__underlying_alloc; +} +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +// Comparison operators for all of the predifined SGI-style allocators. +// This ensures that __allocator<malloc_alloc> (for example) will +// work correctly. + +template <int inst> +inline bool operator==(const __malloc_alloc_template<inst>&, + const __malloc_alloc_template<inst>&) +{ + return true; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER +template <int __inst> +inline bool operator!=(const __malloc_alloc_template<__inst>&, + const __malloc_alloc_template<__inst>&) +{ + return false; +} +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +#ifndef __USE_MALLOC +template <bool __threads, int __inst> +inline bool operator==(const __default_alloc_template<__threads, __inst>&, + const __default_alloc_template<__threads, __inst>&) +{ + return true; +} + +# ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER +template <bool __threads, int __inst> +inline bool operator!=(const __default_alloc_template<__threads, __inst>&, + const __default_alloc_template<__threads, __inst>&) +{ + return false; +} +# endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ +#endif + +template <class _Alloc> +inline bool operator==(const debug_alloc<_Alloc>&, + const debug_alloc<_Alloc>&) { + return true; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER +template <class _Alloc> +inline bool operator!=(const debug_alloc<_Alloc>&, + const debug_alloc<_Alloc>&) { + return false; +} +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +// Another allocator adaptor: _Alloc_traits. This serves two +// purposes. First, make it possible to write containers that can use +// either SGI-style allocators or standard-conforming allocator. +// Second, provide a mechanism so that containers can query whether or +// not the allocator has distinct instances. If not, the container +// can avoid wasting a word of memory to store an empty object. + +// This adaptor uses partial specialization. The general case of +// _Alloc_traits<_Tp, _Alloc> assumes that _Alloc is a +// standard-conforming allocator, possibly with non-equal instances +// and non-static members. (It still behaves correctly even if _Alloc +// has static member and if all instances are equal. Refinements +// affect performance, not correctness.) + +// There are always two members: allocator_type, which is a standard- +// conforming allocator type for allocating objects of type _Tp, and +// _S_instanceless, a static const member of type bool. If +// _S_instanceless is true, this means that there is no difference +// between any two instances of type allocator_type. Furthermore, if +// _S_instanceless is true, then _Alloc_traits has one additional +// member: _Alloc_type. This type encapsulates allocation and +// deallocation of objects of type _Tp through a static interface; it +// has two member functions, whose signatures are +// static _Tp* allocate(size_t) +// static void deallocate(_Tp*, size_t) + +// The fully general version. + +template <class _Tp, class _Allocator> +struct _Alloc_traits +{ + static const bool _S_instanceless = false; + typedef typename _Allocator::__STL_TEMPLATE rebind<_Tp>::other + allocator_type; +}; + +template <class _Tp, class _Allocator> +const bool _Alloc_traits<_Tp, _Allocator>::_S_instanceless; + +// The version for the default allocator. + +template <class _Tp, class _Tp1> +struct _Alloc_traits<_Tp, allocator<_Tp1> > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, alloc> _Alloc_type; + typedef allocator<_Tp> allocator_type; +}; + +// Versions for the predefined SGI-style allocators. + +template <class _Tp, int __inst> +struct _Alloc_traits<_Tp, __malloc_alloc_template<__inst> > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, __malloc_alloc_template<__inst> > _Alloc_type; + typedef __allocator<_Tp, __malloc_alloc_template<__inst> > allocator_type; +}; + +#ifndef __USE_MALLOC +template <class _Tp, bool __threads, int __inst> +struct _Alloc_traits<_Tp, __default_alloc_template<__threads, __inst> > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, __default_alloc_template<__threads, __inst> > + _Alloc_type; + typedef __allocator<_Tp, __default_alloc_template<__threads, __inst> > + allocator_type; +}; +#endif + +template <class _Tp, class _Alloc> +struct _Alloc_traits<_Tp, debug_alloc<_Alloc> > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, debug_alloc<_Alloc> > _Alloc_type; + typedef __allocator<_Tp, debug_alloc<_Alloc> > allocator_type; +}; + +// Versions for the __allocator adaptor used with the predefined +// SGI-style allocators. + +template <class _Tp, class _Tp1, int __inst> +struct _Alloc_traits<_Tp, + __allocator<_Tp1, __malloc_alloc_template<__inst> > > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, __malloc_alloc_template<__inst> > _Alloc_type; + typedef __allocator<_Tp, __malloc_alloc_template<__inst> > allocator_type; +}; + +#ifndef __USE_MALLOC +template <class _Tp, class _Tp1, bool __thr, int __inst> +struct _Alloc_traits<_Tp, + __allocator<_Tp1, + __default_alloc_template<__thr, __inst> > > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, __default_alloc_template<__thr,__inst> > + _Alloc_type; + typedef __allocator<_Tp, __default_alloc_template<__thr,__inst> > + allocator_type; +}; +#endif + +template <class _Tp, class _Tp1, class _Alloc> +struct _Alloc_traits<_Tp, __allocator<_Tp1, debug_alloc<_Alloc> > > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, debug_alloc<_Alloc> > _Alloc_type; + typedef __allocator<_Tp, debug_alloc<_Alloc> > allocator_type; +}; + + +#endif /* __STL_USE_STD_ALLOCATORS */ + #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 #endif diff --git a/contrib/libstdc++/stl/stl_bvector.h b/contrib/libstdc++/stl/stl_bvector.h index 00fe500..0d0cdb6 100644 --- a/contrib/libstdc++/stl/stl_bvector.h +++ b/contrib/libstdc++/stl/stl_bvector.h @@ -37,212 +37,322 @@ static const int __WORD_BIT = int(CHAR_BIT*sizeof(unsigned int)); #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 +#pragma set woff 1375 #endif -struct __bit_reference { - unsigned int* p; - unsigned int mask; - __bit_reference(unsigned int* x, unsigned int y) : p(x), mask(y) {} +struct _Bit_reference { + unsigned int* _M_p; + unsigned int _M_mask; + _Bit_reference(unsigned int* __x, unsigned int __y) + : _M_p(__x), _M_mask(__y) {} public: - __bit_reference() : p(0), mask(0) {} - operator bool() const { return !(!(*p & mask)); } - __bit_reference& operator=(bool x) { - if (x) - *p |= mask; - else - *p &= ~mask; + _Bit_reference() : _M_p(0), _M_mask(0) {} + operator bool() const { return !(!(*_M_p & _M_mask)); } + _Bit_reference& operator=(bool __x) + { + if (__x) *_M_p |= _M_mask; + else *_M_p &= ~_M_mask; return *this; } - __bit_reference& operator=(const __bit_reference& x) { return *this = bool(x); } - bool operator==(const __bit_reference& x) const { - return bool(*this) == bool(x); + _Bit_reference& operator=(const _Bit_reference& __x) + { return *this = bool(__x); } + bool operator==(const _Bit_reference& __x) const + { return bool(*this) == bool(__x); } + bool operator<(const _Bit_reference& __x) const { + return !bool(*this) && bool(__x); } - bool operator<(const __bit_reference& x) const { - return bool(*this) < bool(x); - } - void flip() { *p ^= mask; } + void flip() { *_M_p ^= _M_mask; } }; -inline void swap(__bit_reference x, __bit_reference y) { - bool tmp = x; - x = y; - y = tmp; +inline void swap(_Bit_reference __x, _Bit_reference __y) +{ + bool __tmp = __x; + __x = __y; + __y = __tmp; } -struct __bit_iterator : public random_access_iterator<bool, ptrdiff_t> { - typedef __bit_reference reference; - typedef __bit_reference* pointer; - typedef __bit_iterator iterator; +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; + unsigned int* _M_p; + unsigned int _M_offset; void bump_up() { - if (offset++ == __WORD_BIT - 1) { - offset = 0; - ++p; + if (_M_offset++ == __WORD_BIT - 1) { + _M_offset = 0; + ++_M_p; } } void bump_down() { - if (offset-- == 0) { - offset = __WORD_BIT - 1; - --p; + if (_M_offset-- == 0) { + _M_offset = __WORD_BIT - 1; + --_M_p; } } - __bit_iterator() : p(0), offset(0) {} - __bit_iterator(unsigned int* x, unsigned int y) : p(x), offset(y) {} - reference operator*() const { return reference(p, 1U << offset); } + _Bit_iterator() : _M_p(0), _M_offset(0) {} + _Bit_iterator(unsigned int* __x, unsigned int __y) + : _M_p(__x), _M_offset(__y) {} + reference operator*() const { return reference(_M_p, 1U << _M_offset); } iterator& operator++() { bump_up(); return *this; } iterator operator++(int) { - iterator tmp = *this; + iterator __tmp = *this; bump_up(); - return tmp; + return __tmp; } iterator& operator--() { bump_down(); return *this; } iterator operator--(int) { - iterator tmp = *this; + iterator __tmp = *this; bump_down(); - return tmp; - } - iterator& operator+=(difference_type i) { - difference_type n = i + offset; - p += n / __WORD_BIT; - n = n % __WORD_BIT; - if (n < 0) { - offset = (unsigned int) n + __WORD_BIT; - --p; + return __tmp; + } + iterator& operator+=(difference_type __i) { + difference_type __n = __i + _M_offset; + _M_p += __n / __WORD_BIT; + __n = __n % __WORD_BIT; + if (__n < 0) { + _M_offset = (unsigned int) __n + __WORD_BIT; + --_M_p; } else - offset = (unsigned int) n; + _M_offset = (unsigned int) __n; return *this; } - iterator& operator-=(difference_type i) { - *this += -i; + iterator& operator-=(difference_type __i) { + *this += -__i; return *this; } - iterator operator+(difference_type i) const { - iterator tmp = *this; - return tmp += i; + iterator operator+(difference_type __i) const { + iterator __tmp = *this; + return __tmp += __i; } - iterator operator-(difference_type i) const { - iterator tmp = *this; - return tmp -= i; + iterator operator-(difference_type __i) const { + iterator __tmp = *this; + return __tmp -= __i; } - difference_type operator-(iterator x) const { - return __WORD_BIT * (p - x.p) + offset - x.offset; + difference_type operator-(iterator __x) const { + return __WORD_BIT * (_M_p - __x._M_p) + _M_offset - __x._M_offset; } - reference operator[](difference_type i) { return *(*this + i); } - bool operator==(const iterator& x) const { - return p == x.p && offset == x.offset; + reference operator[](difference_type __i) { return *(*this + __i); } + bool operator==(const iterator& __x) const { + return _M_p == __x._M_p && _M_offset == __x._M_offset; } - bool operator!=(const iterator& x) const { - return p != x.p || offset != x.offset; + bool operator!=(const iterator& __x) const { + return _M_p != __x._M_p || _M_offset != __x._M_offset; } - bool operator<(iterator x) const { - return p < x.p || (p == x.p && offset < x.offset); + bool operator<(iterator __x) const { + return _M_p < __x._M_p || (_M_p == __x._M_p && _M_offset < __x._M_offset); } }; -struct __bit_const_iterator +struct _Bit_const_iterator : public random_access_iterator<bool, ptrdiff_t> { typedef bool reference; typedef bool const_reference; typedef const bool* pointer; - typedef __bit_const_iterator const_iterator; + typedef _Bit_const_iterator const_iterator; - unsigned int* p; - unsigned int offset; + unsigned int* _M_p; + unsigned int _M_offset; void bump_up() { - if (offset++ == __WORD_BIT - 1) { - offset = 0; - ++p; + if (_M_offset++ == __WORD_BIT - 1) { + _M_offset = 0; + ++_M_p; } } void bump_down() { - if (offset-- == 0) { - offset = __WORD_BIT - 1; - --p; + if (_M_offset-- == 0) { + _M_offset = __WORD_BIT - 1; + --_M_p; } } - __bit_const_iterator() : p(0), offset(0) {} - __bit_const_iterator(unsigned int* x, unsigned int y) : p(x), offset(y) {} - __bit_const_iterator(const __bit_iterator& x) : p(x.p), offset(x.offset) {} + _Bit_const_iterator() : _M_p(0), _M_offset(0) {} + _Bit_const_iterator(unsigned int* __x, unsigned int __y) + : _M_p(__x), _M_offset(__y) {} + _Bit_const_iterator(const _Bit_iterator& __x) + : _M_p(__x._M_p), _M_offset(__x._M_offset) {} const_reference operator*() const { - return __bit_reference(p, 1U << offset); + return _Bit_reference(_M_p, 1U << _M_offset); } const_iterator& operator++() { bump_up(); return *this; } const_iterator operator++(int) { - const_iterator tmp = *this; + const_iterator __tmp = *this; bump_up(); - return tmp; + return __tmp; } const_iterator& operator--() { bump_down(); return *this; } const_iterator operator--(int) { - const_iterator tmp = *this; + const_iterator __tmp = *this; bump_down(); - return tmp; - } - const_iterator& operator+=(difference_type i) { - difference_type n = i + offset; - p += n / __WORD_BIT; - n = n % __WORD_BIT; - if (n < 0) { - offset = (unsigned int) n + __WORD_BIT; - --p; + return __tmp; + } + const_iterator& operator+=(difference_type __i) { + difference_type __n = __i + _M_offset; + _M_p += __n / __WORD_BIT; + __n = __n % __WORD_BIT; + if (__n < 0) { + _M_offset = (unsigned int) __n + __WORD_BIT; + --_M_p; } else - offset = (unsigned int) n; + _M_offset = (unsigned int) __n; return *this; } - const_iterator& operator-=(difference_type i) { - *this += -i; + const_iterator& operator-=(difference_type __i) { + *this += -__i; return *this; } - const_iterator operator+(difference_type i) const { - const_iterator tmp = *this; - return tmp += i; + const_iterator operator+(difference_type __i) const { + const_iterator __tmp = *this; + return __tmp += __i; } - const_iterator operator-(difference_type i) const { - const_iterator tmp = *this; - return tmp -= i; + const_iterator operator-(difference_type __i) const { + const_iterator __tmp = *this; + return __tmp -= __i; } - difference_type operator-(const_iterator x) const { - return __WORD_BIT * (p - x.p) + offset - x.offset; + difference_type operator-(const_iterator __x) const { + return __WORD_BIT * (_M_p - __x._M_p) + _M_offset - __x._M_offset; } - const_reference operator[](difference_type i) { - return *(*this + i); + const_reference operator[](difference_type __i) { + return *(*this + __i); } - bool operator==(const const_iterator& x) const { - return p == x.p && offset == x.offset; + bool operator==(const const_iterator& __x) const { + return _M_p == __x._M_p && _M_offset == __x._M_offset; } - bool operator!=(const const_iterator& x) const { - return p != x.p || offset != x.offset; + bool operator!=(const const_iterator& __x) const { + return _M_p != __x._M_p || _M_offset != __x._M_offset; } - bool operator<(const_iterator x) const { - return p < x.p || (p == x.p && offset < x.offset); + bool operator<(const_iterator __x) const { + return _M_p < __x._M_p || (_M_p == __x._M_p && _M_offset < __x._M_offset); } }; +// Bit-vector base class, which encapsulates the difference between +// old SGI-style allocators and standard-conforming allocators. + +#ifdef __STL_USE_STD_ALLOCATORS + +// Base class for ordinary allocators. +template <class _Allocator, bool __is_static> +class _Bvector_alloc_base { +public: + typedef typename _Alloc_traits<bool, _Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return _M_data_allocator; } + + _Bvector_alloc_base(const allocator_type& __a) + : _M_data_allocator(__a), _M_start(), _M_finish(), _M_end_of_storage(0) {} + +protected: + unsigned int* _M_bit_alloc(size_t __n) + { return _M_data_allocator.allocate((__n + __WORD_BIT - 1)/__WORD_BIT); } + void _M_deallocate() { + if (_M_start._M_p) + _M_data_allocator.deallocate(_M_start._M_p, + _M_end_of_storage - _M_start._M_p); + } + + typename _Alloc_traits<unsigned int, _Allocator>::allocator_type + _M_data_allocator; + _Bit_iterator _M_start; + _Bit_iterator _M_finish; + unsigned int* _M_end_of_storage; +}; + +// Specialization for instanceless allocators. +template <class _Allocator> +class _Bvector_alloc_base<_Allocator, true> { +public: + typedef typename _Alloc_traits<bool, _Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Bvector_alloc_base(const allocator_type&) + : _M_start(), _M_finish(), _M_end_of_storage(0) {} + +protected: + typedef typename _Alloc_traits<unsigned int, _Allocator>::_Alloc_type + _Alloc_type; + + unsigned int* _M_bit_alloc(size_t __n) + { return _Alloc_type::allocate((__n + __WORD_BIT - 1)/__WORD_BIT); } + void _M_deallocate() { + if (_M_start._M_p) + _Alloc_type::deallocate(_M_start._M_p, + _M_end_of_storage - _M_start._M_p); + } + + _Bit_iterator _M_start; + _Bit_iterator _M_finish; + unsigned int* _M_end_of_storage; +}; + +template <class _Alloc> +class _Bvector_base + : public _Bvector_alloc_base<_Alloc, + _Alloc_traits<bool, _Alloc>::_S_instanceless> +{ + typedef _Bvector_alloc_base<_Alloc, + _Alloc_traits<bool, _Alloc>::_S_instanceless> + _Base; +public: + typedef typename _Base::allocator_type allocator_type; + + _Bvector_base(const allocator_type& __a) : _Base(__a) {} + ~_Bvector_base() { _Base::_M_deallocate(); } +}; + +#else /* __STL_USE_STD_ALLOCATORS */ + +template <class _Alloc> +class _Bvector_base +{ +public: + typedef _Alloc allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Bvector_base(const allocator_type&) + : _M_start(), _M_finish(), _M_end_of_storage(0) {} + ~_Bvector_base() { _M_deallocate(); } + +protected: + typedef simple_alloc<unsigned int, _Alloc> _Alloc_type; + + unsigned int* _M_bit_alloc(size_t __n) + { return _Alloc_type::allocate((__n + __WORD_BIT - 1)/__WORD_BIT); } + void _M_deallocate() { + if (_M_start._M_p) + _Alloc_type::deallocate(_M_start._M_p, + _M_end_of_storage - _M_start._M_p); + } + + _Bit_iterator _M_start; + _Bit_iterator _M_finish; + unsigned int* _M_end_of_storage; +}; + +#endif /* __STL_USE_STD_ALLOCATORS */ + // The next few lines are confusing. What we're doing is declaring a // partial specialization of vector<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. +// the default allocator. -#if defined(__STL_CLASS_PARTIAL_SPECIALIZATION) && !defined(__STL_NEED_BOOL) +#if defined(__STL_CLASS_PARTIAL_SPECIALIZATION) && !defined(__STL_NO_BOOL) #define __SGI_STL_VECBOOL_TEMPLATE #define __BVECTOR vector #else @@ -254,27 +364,29 @@ struct __bit_const_iterator __STL_END_NAMESPACE # include <stl_vector.h> __STL_BEGIN_NAMESPACE -template<class Alloc> class vector<bool, Alloc> +template<class _Alloc> class vector<bool,_Alloc> + : public _Bvector_base<_Alloc> # else /* __SGI_STL_VECBOOL_TEMPLATE */ class bit_vector + : public _Bvector_base<__STL_DEFAULT_ALLOCATOR(bool) > # endif /* __SGI_STL_VECBOOL_TEMPLATE */ { # ifdef __SGI_STL_VECBOOL_TEMPLATE - typedef simple_alloc<unsigned int, Alloc> data_allocator; + typedef _Bvector_base<_Alloc> _Base; # else /* __SGI_STL_VECBOOL_TEMPLATE */ - typedef simple_alloc<unsigned int, alloc> data_allocator; + typedef _Bvector_base<__STL_DEFAULT_ALLOCATOR(bool) > _Base; # endif /* __SGI_STL_VECBOOL_TEMPLATE */ public: typedef bool value_type; typedef size_t size_type; typedef ptrdiff_t difference_type; - typedef __bit_reference reference; + typedef _Bit_reference reference; typedef bool const_reference; - typedef __bit_reference* pointer; + typedef _Bit_reference* pointer; typedef const bool* const_pointer; - typedef __bit_iterator iterator; - typedef __bit_const_iterator const_iterator; + typedef _Bit_iterator iterator; + typedef _Bit_const_iterator const_iterator; #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION typedef reverse_iterator<const_iterator> const_reverse_iterator; @@ -286,92 +398,94 @@ public: reverse_iterator; #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + typedef typename _Base::allocator_type allocator_type; + allocator_type get_allocator() const { return _Base::get_allocator(); } + +protected: +#ifdef __STL_USE_NAMESPACES + using _Base::_M_bit_alloc; + using _Base::_M_deallocate; + using _Base::_M_start; + using _Base::_M_finish; + using _Base::_M_end_of_storage; +#endif /* __STL_USE_NAMESPACES */ + protected: - iterator start; - iterator finish; - unsigned int* end_of_storage; - unsigned int* bit_alloc(size_type n) { - return data_allocator::allocate((n + __WORD_BIT - 1)/__WORD_BIT); - } - void deallocate() { - if (start.p) - data_allocator::deallocate(start.p, end_of_storage - start.p); - } - void initialize(size_type n) { - unsigned int* q = bit_alloc(n); - end_of_storage = q + (n + __WORD_BIT - 1)/__WORD_BIT; - start = iterator(q, 0); - finish = start + difference_type(n); - } - void insert_aux(iterator position, bool x) { - if (finish.p != end_of_storage) { - copy_backward(position, finish, finish + 1); - *position = x; - ++finish; + void _M_initialize(size_type __n) { + unsigned int* __q = _M_bit_alloc(__n); + _M_end_of_storage = __q + (__n + __WORD_BIT - 1)/__WORD_BIT; + _M_start = iterator(__q, 0); + _M_finish = _M_start + difference_type(__n); + } + void _M_insert_aux(iterator __position, bool __x) { + if (_M_finish._M_p != _M_end_of_storage) { + copy_backward(__position, _M_finish, _M_finish + 1); + *__position = __x; + ++_M_finish; } else { - size_type len = size() ? 2 * size() : __WORD_BIT; - unsigned int* q = bit_alloc(len); - iterator i = copy(begin(), position, iterator(q, 0)); - *i++ = x; - finish = copy(position, end(), i); - deallocate(); - end_of_storage = q + (len + __WORD_BIT - 1)/__WORD_BIT; - start = iterator(q, 0); + size_type __len = size() ? 2 * size() : __WORD_BIT; + unsigned int* __q = _M_bit_alloc(__len); + iterator __i = copy(begin(), __position, iterator(__q, 0)); + *__i++ = __x; + _M_finish = copy(__position, end(), __i); + _M_deallocate(); + _M_end_of_storage = __q + (__len + __WORD_BIT - 1)/__WORD_BIT; + _M_start = iterator(__q, 0); } } #ifdef __STL_MEMBER_TEMPLATES - template <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 _InputIterator> + void _M_initialize_range(_InputIterator __first, _InputIterator __last, + input_iterator_tag) { + _M_start = iterator(); + _M_finish = iterator(); + _M_end_of_storage = 0; + for ( ; __first != __last; ++__first) + push_back(*__first); + } + + template <class _ForwardIterator> + void _M_initialize_range(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag) { + size_type __n = 0; + distance(__first, __last, __n); + _M_initialize(__n); + copy(__first, __last, _M_start); + } + + template <class _InputIterator> + void _M_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); + template <class _ForwardIterator> + void _M_insert_range(iterator __position, + _ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag) { + if (__first != __last) { + size_type __n = 0; + distance(__first, __last, __n); + if (capacity() - size() >= __n) { + copy_backward(__position, end(), _M_finish + difference_type(__n)); + copy(__first, __last, __position); + _M_finish += difference_type(__n); } else { - size_type len = size() + max(size(), n); - unsigned int* q = bit_alloc(len); - iterator i = copy(begin(), position, iterator(q, 0)); - i = copy(first, last, i); - finish = copy(position, end(), i); - deallocate(); - end_of_storage = q + (len + __WORD_BIT - 1)/__WORD_BIT; - start = iterator(q, 0); + size_type __len = size() + max(size(), __n); + unsigned int* __q = _M_bit_alloc(__len); + iterator __i = copy(begin(), __position, iterator(__q, 0)); + __i = copy(__first, __last, __i); + _M_finish = copy(__position, end(), __i); + _M_deallocate(); + _M_end_of_storage = __q + (__len + __WORD_BIT - 1)/__WORD_BIT; + _M_start = iterator(__q, 0); } } } @@ -379,10 +493,10 @@ protected: #endif /* __STL_MEMBER_TEMPLATES */ public: - iterator begin() { return start; } - const_iterator begin() const { return start; } - iterator end() { return finish; } - const_iterator end() const { return finish; } + iterator begin() { return _M_start; } + const_iterator begin() const { return _M_start; } + iterator end() { return _M_finish; } + const_iterator end() const { return _M_finish; } reverse_iterator rbegin() { return reverse_iterator(end()); } const_reverse_iterator rbegin() const { @@ -396,190 +510,291 @@ public: size_type size() const { return size_type(end() - begin()); } size_type max_size() const { return size_type(-1); } size_type capacity() const { - return size_type(const_iterator(end_of_storage, 0) - begin()); + return size_type(const_iterator(_M_end_of_storage, 0) - begin()); } bool empty() const { return begin() == end(); } - reference operator[](size_type n) { - return *(begin() + difference_type(n)); - } - const_reference operator[](size_type n) const { - return *(begin() + difference_type(n)); + reference operator[](size_type __n) { + return *(begin() + difference_type(__n)); } - __BVECTOR() : start(iterator()), finish(iterator()), end_of_storage(0) {} - __BVECTOR(size_type n, bool value) { - initialize(n); - fill(start.p, end_of_storage, value ? ~0 : 0); + const_reference operator[](size_type __n) const { + return *(begin() + difference_type(__n)); } - __BVECTOR(int n, bool value) { - initialize(n); - fill(start.p, end_of_storage, value ? ~0 : 0); - } - __BVECTOR(long n, bool value) { - initialize(n); - fill(start.p, end_of_storage, value ? ~0 : 0); + + explicit __BVECTOR(const allocator_type& __a = allocator_type()) + : _Base(__a) {} + + __BVECTOR(size_type __n, bool __value, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { + _M_initialize(__n); + fill(_M_start._M_p, _M_end_of_storage, __value ? ~0 : 0); } - explicit __BVECTOR(size_type n) { - initialize(n); - fill(start.p, end_of_storage, 0); + + explicit __BVECTOR(size_type __n) + : _Base(allocator_type()) + { + _M_initialize(__n); + fill(_M_start._M_p, _M_end_of_storage, 0); } - __BVECTOR(const __BVECTOR& x) { - initialize(x.size()); - copy(x.begin(), x.end(), start); + + __BVECTOR(const __BVECTOR& __x) : _Base(__x.get_allocator()) { + _M_initialize(__x.size()); + copy(__x.begin(), __x.end(), _M_start); } #ifdef __STL_MEMBER_TEMPLATES - template <class InputIterator> - __BVECTOR(InputIterator first, InputIterator last) { - initialize_range(first, last, iterator_category(first)); + // Check whether it's an integral type. If so, it's not an iterator. + template <class _InputIterator> + __BVECTOR(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_initialize_dispatch(__first, __last, _Integral()); + } + + template <class _Integer> + void _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) { + _M_initialize(__n); + fill(_M_start._M_p, _M_end_of_storage, __x ? ~0 : 0); + } + + template <class _InputIterator> + void _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) { + _M_initialize_range(__first, __last, __ITERATOR_CATEGORY(__first)); } #else /* __STL_MEMBER_TEMPLATES */ - __BVECTOR(const_iterator first, const_iterator last) { - size_type n = 0; - distance(first, last, n); - initialize(n); - copy(first, last, start); - } - __BVECTOR(const bool* first, const bool* last) { - size_type n = 0; - distance(first, last, n); - initialize(n); - copy(first, last, start); + __BVECTOR(const_iterator __first, const_iterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { + size_type __n = 0; + distance(__first, __last, __n); + _M_initialize(__n); + copy(__first, __last, _M_start); + } + __BVECTOR(const bool* __first, const bool* __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { + size_type __n = 0; + distance(__first, __last, __n); + _M_initialize(__n); + copy(__first, __last, _M_start); } #endif /* __STL_MEMBER_TEMPLATES */ - ~__BVECTOR() { deallocate(); } - __BVECTOR& operator=(const __BVECTOR& x) { - if (&x == this) return *this; - if (x.size() > capacity()) { - deallocate(); - initialize(x.size()); + ~__BVECTOR() { } + + __BVECTOR& operator=(const __BVECTOR& __x) { + if (&__x == this) return *this; + if (__x.size() > capacity()) { + _M_deallocate(); + _M_initialize(__x.size()); } - copy(x.begin(), x.end(), begin()); - finish = begin() + difference_type(x.size()); + copy(__x.begin(), __x.end(), begin()); + _M_finish = begin() + difference_type(__x.size()); return *this; } - void reserve(size_type n) { - if (capacity() < n) { - unsigned int* q = bit_alloc(n); - finish = copy(begin(), end(), iterator(q, 0)); - deallocate(); - start = iterator(q, 0); - end_of_storage = q + (n + __WORD_BIT - 1)/__WORD_BIT; + + // assign(), a generalized assignment member function. Two + // versions: one that takes a count, and one that takes a range. + // The range version is a member template, so we dispatch on whether + // or not the type is an integer. + + void assign(size_t __n, bool __x) { + if (__n > size()) { + fill(_M_start._M_p, _M_end_of_storage, __x ? ~0 : 0); + insert(end(), __n - size(), __x); + } + else { + erase(begin() + __n, end()); + fill(_M_start._M_p, _M_end_of_storage, __x ? ~0 : 0); } } + +#ifdef __STL_MEMBER_TEMPLATES + + template <class _InputIterator> + void assign(_InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } + + template <class _Integer> + void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { assign((size_t) __n, (bool) __val); } + + template <class _InputIter> + void _M_assign_dispatch(_InputIter __first, _InputIter __last, __false_type) + { _M_assign_aux(__first, __last, __ITERATOR_CATEGORY(__first)); } + + template <class _InputIterator> + void _M_assign_aux(_InputIterator __first, _InputIterator __last, + input_iterator_tag) { + iterator __cur = begin(); + for ( ; __first != __last && __cur != end(); ++__cur, ++__first) + *__cur = *__first; + if (__first == __last) + erase(__cur, end()); + else + insert(end(), __first, __last); + } + + template <class _ForwardIterator> + void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag) { + size_type __len = 0; + distance(__first, __last, __len); + if (__len < size()) + erase(copy(__first, __last, begin()), end()); + else { + _ForwardIterator __mid = __first; + advance(__mid, size()); + copy(__first, __mid, begin()); + insert(end(), __mid, __last); + } + } + +#endif /* __STL_MEMBER_TEMPLATES */ + + void reserve(size_type __n) { + if (capacity() < __n) { + unsigned int* __q = _M_bit_alloc(__n); + _M_finish = copy(begin(), end(), iterator(__q, 0)); + _M_deallocate(); + _M_start = iterator(__q, 0); + _M_end_of_storage = __q + (__n + __WORD_BIT - 1)/__WORD_BIT; + } + } + reference front() { return *begin(); } const_reference front() const { return *begin(); } reference back() { return *(end() - 1); } const_reference back() const { return *(end() - 1); } - void push_back(bool x) { - if (finish.p != end_of_storage) - *finish++ = x; + void push_back(bool __x) { + if (_M_finish._M_p != _M_end_of_storage) + *_M_finish++ = __x; else - insert_aux(end(), x); + _M_insert_aux(end(), __x); } - void swap(__BVECTOR& x) { - __STD::swap(start, x.start); - __STD::swap(finish, x.finish); - __STD::swap(end_of_storage, x.end_of_storage); + void swap(__BVECTOR& __x) { + __STD::swap(_M_start, __x._M_start); + __STD::swap(_M_finish, __x._M_finish); + __STD::swap(_M_end_of_storage, __x._M_end_of_storage); } - iterator insert(iterator position, bool x = bool()) { - difference_type n = position - begin(); - if (finish.p != end_of_storage && position == end()) - *finish++ = x; + iterator insert(iterator __position, bool __x = bool()) { + difference_type __n = __position - begin(); + if (_M_finish._M_p != _M_end_of_storage && __position == end()) + *_M_finish++ = __x; else - insert_aux(position, x); - return begin() + n; + _M_insert_aux(__position, __x); + return begin() + __n; } #ifdef __STL_MEMBER_TEMPLATES - template <class InputIterator> void insert(iterator position, - InputIterator first, - InputIterator last) { - insert_range(position, first, last, iterator_category(first)); + // Check whether it's an integral type. If so, it's not an iterator. + template <class _InputIterator> + void insert(iterator __position, + _InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_insert_dispatch(__position, __first, __last, _Integral()); + } + + template <class _Integer> + void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, + __true_type) { + insert(__pos, (size_type) __n, (bool) __x); + } + + template <class _InputIterator> + void _M_insert_dispatch(iterator __pos, + _InputIterator __first, _InputIterator __last, + __false_type) { + _M_insert_range(__pos, __first, __last, __ITERATOR_CATEGORY(__first)); } #else /* __STL_MEMBER_TEMPLATES */ - void insert(iterator position, const_iterator first, - const_iterator last) { - if (first == last) return; - size_type n = 0; - distance(first, last, n); - if (capacity() - size() >= n) { - copy_backward(position, end(), finish + n); - copy(first, last, position); - finish += n; + void insert(iterator __position, + const_iterator __first, const_iterator __last) { + if (__first == __last) return; + size_type __n = 0; + distance(__first, __last, __n); + if (capacity() - size() >= __n) { + copy_backward(__position, end(), _M_finish + __n); + copy(__first, __last, __position); + _M_finish += __n; } else { - size_type len = size() + max(size(), n); - unsigned int* q = bit_alloc(len); - iterator i = copy(begin(), position, iterator(q, 0)); - i = copy(first, last, i); - finish = copy(position, end(), i); - deallocate(); - end_of_storage = q + (len + __WORD_BIT - 1)/__WORD_BIT; - start = iterator(q, 0); + size_type __len = size() + max(size(), __n); + unsigned int* __q = _M_bit_alloc(__len); + iterator __i = copy(begin(), __position, iterator(__q, 0)); + __i = copy(__first, __last, __i); + _M_finish = copy(__position, end(), __i); + _M_deallocate(); + _M_end_of_storage = __q + (__len + __WORD_BIT - 1)/__WORD_BIT; + _M_start = iterator(__q, 0); } } - void insert(iterator position, const bool* first, const bool* last) { - if (first == last) return; - size_type n = 0; - distance(first, last, n); - if (capacity() - size() >= n) { - copy_backward(position, end(), finish + n); - copy(first, last, position); - finish += n; + void insert(iterator __position, const bool* __first, const bool* __last) { + if (__first == __last) return; + size_type __n = 0; + distance(__first, __last, __n); + if (capacity() - size() >= __n) { + copy_backward(__position, end(), _M_finish + __n); + copy(__first, __last, __position); + _M_finish += __n; } else { - size_type len = size() + max(size(), n); - unsigned int* q = bit_alloc(len); - iterator i = copy(begin(), position, iterator(q, 0)); - i = copy(first, last, i); - finish = copy(position, end(), i); - deallocate(); - end_of_storage = q + (len + __WORD_BIT - 1)/__WORD_BIT; - start = iterator(q, 0); + size_type __len = size() + max(size(), __n); + unsigned int* __q = _M_bit_alloc(__len); + iterator __i = copy(begin(), __position, iterator(__q, 0)); + __i = copy(__first, __last, __i); + _M_finish = copy(__position, end(), __i); + _M_deallocate(); + _M_end_of_storage = __q + (__len + __WORD_BIT - 1)/__WORD_BIT; + _M_start = iterator(__q, 0); } } #endif /* __STL_MEMBER_TEMPLATES */ - void insert(iterator position, size_type n, bool x) { - if (n == 0) return; - if (capacity() - size() >= n) { - copy_backward(position, end(), finish + difference_type(n)); - fill(position, position + difference_type(n), x); - finish += difference_type(n); + void insert(iterator __position, size_type __n, bool __x) { + if (__n == 0) return; + if (capacity() - size() >= __n) { + copy_backward(__position, end(), _M_finish + difference_type(__n)); + fill(__position, __position + difference_type(__n), __x); + _M_finish += difference_type(__n); } else { - size_type len = size() + max(size(), n); - unsigned int* q = bit_alloc(len); - iterator i = copy(begin(), position, iterator(q, 0)); - fill_n(i, n, x); - finish = copy(position, end(), i + difference_type(n)); - deallocate(); - end_of_storage = q + (len + __WORD_BIT - 1)/__WORD_BIT; - start = iterator(q, 0); + size_type __len = size() + max(size(), __n); + unsigned int* __q = _M_bit_alloc(__len); + iterator __i = copy(begin(), __position, iterator(__q, 0)); + fill_n(__i, __n, __x); + _M_finish = copy(__position, end(), __i + difference_type(__n)); + _M_deallocate(); + _M_end_of_storage = __q + (__len + __WORD_BIT - 1)/__WORD_BIT; + _M_start = iterator(__q, 0); } } - void insert(iterator pos, int n, bool x) { insert(pos, (size_type)n, x); } - void insert(iterator pos, long n, bool x) { insert(pos, (size_type)n, x); } - - void pop_back() { --finish; } - iterator erase(iterator position) { - if (position + 1 != end()) - copy(position + 1, end(), position); - --finish; - return position; + void pop_back() { --_M_finish; } + iterator erase(iterator __position) { + if (__position + 1 != end()) + copy(__position + 1, end(), __position); + --_M_finish; + return __position; } - iterator erase(iterator first, iterator last) { - finish = copy(last, end(), first); - return first; + iterator erase(iterator __first, iterator __last) { + _M_finish = copy(__last, end(), __first); + return __first; } - void resize(size_type new_size, bool x = bool()) { - if (new_size < size()) - erase(begin() + difference_type(new_size), end()); + void resize(size_type __new_size, bool __x = bool()) { + if (__new_size < size()) + erase(begin() + difference_type(__new_size), end()); else - insert(end(), new_size - size(), x); + insert(end(), __new_size - size(), __x); } void clear() { erase(begin(), end()); } }; @@ -590,12 +805,18 @@ typedef vector<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 (__x.size() == __y.size() && + equal(__x.begin(), __x.end(), __y.begin())); } -inline bool operator<(const bit_vector& x, const bit_vector& y) { - return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); +inline bool +operator<(const bit_vector& __x, const bit_vector& __y) +{ + return lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); } #endif /* __SGI_STL_VECBOOL_TEMPLATE */ @@ -605,6 +826,7 @@ inline bool operator<(const bit_vector& x, const bit_vector& y) { #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 +#pragma reset woff 1375 #endif __STL_END_NAMESPACE diff --git a/contrib/libstdc++/stl/stl_config.h b/contrib/libstdc++/stl/stl_config.h index 02a1f88..d72f9e1 100644 --- a/contrib/libstdc++/stl/stl_config.h +++ b/contrib/libstdc++/stl/stl_config.h @@ -27,57 +27,89 @@ #ifndef __STL_CONFIG_H # define __STL_CONFIG_H -// What this file does. -// (1) Defines bool, true, and false if the compiler doesn't do so already. -// (2) Defines __STL_NO_DRAND48 if the compiler's standard library does -// not support the drand48() function. -// (3) Defines __STL_STATIC_TEMPLATE_MEMBER_BUG if the compiler can't -// handle static members of template classes. -// (4) Defines 'typename' as a null macro if the compiler does not support -// the typename keyword. -// (5) Defines __STL_CLASS_PARTIAL_SPECIALIZATION if the compiler -// supports partial specialization of class templates. -// (6) Defines __STL_FUNCTION_TMPL_PARTIAL_ORDER if the compiler supports -// partial ordering of function templates (a.k.a partial specialization -// of function templates. -// (7) Defines __STL_EXPLICIT_FUNCTION_TMPL_ARGS if the compiler -// supports calling a function template by providing its template -// arguments explicitly. -// (8) Defines __STL_MEMBER_TEMPLATES if the compiler supports -// template members of classes. -// (9) Defines 'explicit' as a null macro if the compiler does not support -// the explicit keyword. -// (10) Defines __STL_LIMITED_DEFAULT_TEMPLATES if the compiler is -// unable to handle default template parameters that depend on -// previous template parameters. -// (11) Defines __STL_NON_TYPE_TMPL_PARAM_BUG if the compiler has -// trouble performing function template argument deduction for -// non-type template parameters. -// (12) Defines __SGI_STL_NO_ARROW_OPERATOR if the compiler is unable -// to support the -> operator for iterators. -// (13) Defines __STL_USE_EXCEPTIONS if the compiler (in the current -// compilation mode) supports exceptions. -// (14) Define __STL_USE_NAMESPACES if we're putting the STL into a -// namespace. -// (15) Defines __STL_SGI_THREADS if this is being compiled on an SGI -// compiler, and if the user hasn't selected pthreads or no threads -// instead. -// (16) Defines __STL_WIN32THREADS if this is being compiled on a -// WIN32 compiler in multithreaded mode. -// (17) Define namespace-related macros (__STD, __STL_BEGIN_NAMESPACE, etc.) -// apropriately. -// (18) Define exception-related macros (__STL_TRY, __STL_UNWIND, etc.) -// appropriately. -// (19) Defines __stl_assert either as a test or as a null macro, -// depending on whether or not __STL_ASSERTIONS is defined. +// Flags: +// * __STL_NO_BOOL: defined if the compiler doesn't have bool as a builtin +// type. +// * __STL_HAS_WCHAR_T: defined if the compier has wchar_t as a builtin type. +// * __STL_NO_DRAND48: defined if the compiler doesn't have the drand48 +// function. +// * __STL_STATIC_TEMPLATE_MEMBER_BUG: defined if the compiler can't handle +// static members of template classes. +// * __STL_CLASS_PARTIAL_SPECIALIZATION: defined if the compiler supports +// partial specialization of template classes. +// * __STL_PARTIAL_SPECIALIZATION_SYNTAX: defined if the compiler +// supports partial specialization syntax for full specialization of +// class templates. (Even if it doesn't actually support partial +// specialization itself.) +// * __STL_FUNCTION_TMPL_PARTIAL_ORDER: defined if the compiler supports +// partial ordering of function templates. (a.k.a partial specialization +// of function templates.) +// * __STL_MEMBER_TEMPLATES: defined if the compiler supports template +// member functions of classes. +// * __STL_MEMBER_TEMPLATE_CLASSES: defined if the compiler supports +// nested classes that are member templates of other classes. +// * __STL_EXPLICIT_FUNCTION_TMPL_ARGS: defined if the compiler +// supports calling a function template by providing its template +// arguments explicitly. +// * __STL_LIMITED_DEFAULT_TEMPLATES: defined if the compiler is unable +// to handle default template parameters that depend on previous template +// parameters. +// * __STL_NON_TYPE_TMPL_PARAM_BUG: defined if the compiler has trouble with +// function template argument deduction for non-type template parameters. +// * __SGI_STL_NO_ARROW_OPERATOR: defined if the compiler is unable +// to support the -> operator for iterators. +// * __STL_USE_EXCEPTIONS: defined if the compiler (in the current compilation +// mode) supports exceptions. +// * __STL_USE_NAMESPACES: defined if the compiler has the necessary +// support for namespaces. +// * __STL_NO_EXCEPTION_HEADER: defined if the compiler does not have a +// standard-conforming header <exception>. +// * __STL_SGI_THREADS: defined if this is being compiled for an SGI IRIX +// system in multithreaded mode, using native SGI threads instead of +// pthreads. +// * __STL_WIN32THREADS: defined if this is being compiled on a WIN32 +// compiler in multithreaded mode. +// * __STL_LONG_LONG if the compiler has long long and unsigned long long +// types. (They're not in the C++ standard, but they are expected to be +// included in the forthcoming C9X standard.) + + +// User-settable macros that control compilation: +// * __STL_USE_SGI_ALLOCATORS: if defined, then the STL will use older +// SGI-style allocators, instead of standard-conforming allocators, +// even if the compiler supports all of the language features needed +// for standard-conforming allocators. +// * __STL_NO_NAMESPACES: if defined, don't put the library in namespace +// std, even if the compiler supports namespaces. +// * __STL_ASSERTIONS: if defined, then enable runtime checking through the +// __stl_assert macro. +// * _PTHREADS: if defined, use Posix threads for multithreading support. +// * _NOTHREADS: if defined, don't use any multithreading support. + + +// Other macros defined by this file: + +// * bool, true, and false, if __STL_NO_BOOL is defined. +// * typename, as a null macro if it's not already a keyword. +// * explicit, as a null macro if it's not already a keyword. +// * namespace-related macros (__STD, __STL_BEGIN_NAMESPACE, etc.) +// * exception-related macros (__STL_TRY, __STL_UNWIND, etc.) +// * __stl_assert, either as a test or as a null macro, depending on +// whether or not __STL_ASSERTIONS is defined. #ifdef _PTHREADS # define __STL_PTHREADS #endif +#ifdef _SOLTHREADS +# define __STL_SOLTHREADS +#endif # if defined(__sgi) && !defined(__GNUC__) # if !defined(_BOOL) -# define __STL_NEED_BOOL +# define __STL_NO_BOOL +# endif +# if defined(_WCHAR_T_IS_KEYWORD) +# define __STL_HAS_WCHAR_T # endif # if !defined(_TYPENAME_IS_KEYWORD) # define __STL_NEED_TYPENAME @@ -87,6 +119,13 @@ # endif # ifdef _MEMBER_TEMPLATES # define __STL_MEMBER_TEMPLATES +# define __STL_MEMBER_TEMPLATE_CLASSES +# endif +# if defined(_MEMBER_TEMPLATE_KEYWORD) +# define __STL_MEMBER_TEMPLATE_KEYWORD +# endif +# if (_COMPILER_VERSION >= 730) && defined(_MIPS_SIM) && _MIPS_SIM != _ABIO32 +# define __STL_MEMBER_TEMPLATE_KEYWORD # endif # if !defined(_EXPLICIT_IS_KEYWORD) # define __STL_NEED_EXPLICIT @@ -95,15 +134,22 @@ # define __STL_USE_EXCEPTIONS # endif # if (_COMPILER_VERSION >= 721) && defined(_NAMESPACES) -# define __STL_USE_NAMESPACES -# endif +# define __STL_HAS_NAMESPACES +# endif +# if (_COMPILER_VERSION < 721) +# define __STL_NO_EXCEPTION_HEADER +# endif # if !defined(_NOTHREADS) && !defined(__STL_PTHREADS) # define __STL_SGI_THREADS # endif +# if defined(_LONGLONG) && defined(_SGIAPI) && _SGIAPI +# define __STL_LONG_LONG +# endif # endif # ifdef __GNUC__ # include <_G_config.h> +# define __STL_HAS_WCHAR_T # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) # define __STL_STATIC_TEMPLATE_MEMBER_BUG # define __STL_NEED_TYPENAME @@ -111,21 +157,35 @@ # else # define __STL_CLASS_PARTIAL_SPECIALIZATION # define __STL_FUNCTION_TMPL_PARTIAL_ORDER -# define __STL_EXPLICIT_FUNCTION_TMPL_ARGS # define __STL_MEMBER_TEMPLATES +# define __STL_MEMBER_TEMPLATE_CLASSES +# define __STL_EXPLICIT_FUNCTION_TMPL_ARGS +# define __STL_HAS_NAMESPACES +# define __STL_NO_NAMESPACES +# define __SGI_STL_USE_AUTO_PTR_CONVERSIONS +# define __STL_USE_NAMESPACES # endif - /* 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 +# if defined(__linux__) + /* glibc pre 2.0 is very buggy. We have to disable thread for it. + It should be upgraded to glibc 2.0 or later. */ +# if !defined(_NOTHREADS) && __GLIBC__ >= 2 && defined(_G_USING_THUNKS) +# define __STL_PTHREADS +# ifdef __STRICT_ANSI__ + /* Work around a bug in the glibc 2.0.x pthread.h. */ +# define sigset_t __sigset_t +# endif +# endif # endif # ifdef __EXCEPTIONS # define __STL_USE_EXCEPTIONS # endif +# ifndef __STRICT_ANSI__ +# define __STL_LONG_LONG +# endif # endif -# if defined(__SUNPRO_CC) -# define __STL_NEED_BOOL +# if defined(__SUNPRO_CC) +# define __STL_NO_BOOL # define __STL_NEED_TYPENAME # define __STL_NEED_EXPLICIT # define __STL_USE_EXCEPTIONS @@ -133,21 +193,30 @@ # if defined(__COMO__) # define __STL_MEMBER_TEMPLATES +# define __STL_MEMBER_TEMPLATE_CLASSES # define __STL_CLASS_PARTIAL_SPECIALIZATION # define __STL_USE_EXCEPTIONS -# define __STL_USE_NAMESPACES +# define __STL_HAS_NAMESPACES +# endif + +# if defined(__MINGW32__) +# define __STL_NO_DRAND48 +# endif + +# if defined(__CYGWIN__) +# define __STL_NO_DRAND48 # 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 +# if _MSC_VER < 1100 /* 1000 is version 4.0, 1100 is 5.0, 1200 is 6.0. */ # define __STL_NEED_EXPLICIT +# define __STL_NO_BOOL +# if _MSC_VER > 1000 +# include <yvals.h> +# define __STL_DONT_USE_BOOL_TYPEDEF +# endif # endif # define __STL_NON_TYPE_TMPL_PARAM_BUG # define __SGI_STL_NO_ARROW_OPERATOR @@ -157,6 +226,11 @@ # ifdef _MT # define __STL_WIN32THREADS # endif +# if _MSC_VER >= 1200 +# define __STL_PARTIAL_SPECIALIZATION_SYNTAX +# define __STL_HAS_NAMESPACES +# define __STL_NO_NAMESPACES +# endif # endif # if defined(__BORLANDC__) @@ -173,8 +247,7 @@ # endif # endif - -# if defined(__STL_NEED_BOOL) +# if defined(__STL_NO_BOOL) && !defined(__STL_DONT_USE_BOOL_TYPEDEF) typedef int bool; # define true 1 # define false 0 @@ -184,6 +257,12 @@ # define typename # endif +# ifdef __STL_MEMBER_TEMPLATE_KEYWORD +# define __STL_TEMPLATE template +# else +# define __STL_TEMPLATE +# endif + # ifdef __STL_NEED_EXPLICIT # define explicit # endif @@ -194,44 +273,71 @@ # define __STL_NULL_TMPL_ARGS # endif -# ifdef __STL_CLASS_PARTIAL_SPECIALIZATION +# if defined(__STL_CLASS_PARTIAL_SPECIALIZATION) \ + || defined (__STL_PARTIAL_SPECIALIZATION_SYNTAX) # define __STL_TEMPLATE_NULL template<> # else # define __STL_TEMPLATE_NULL # endif +// Use standard-conforming allocators if we have the necessary language +// features. __STL_USE_SGI_ALLOCATORS is a hook so that users can +// disable new-style allocators, and continue to use the same kind of +// allocators as before, without having to edit library headers. +# if defined(__STL_CLASS_PARTIAL_SPECIALIZATION) && \ + defined(__STL_MEMBER_TEMPLATES) && \ + defined(__STL_MEMBER_TEMPLATE_CLASSES) && \ + !defined(__STL_NO_BOOL) && \ + !defined(__STL_NON_TYPE_TMPL_PARAM_BUG) && \ + !defined(__STL_LIMITED_DEFAULT_TEMPLATES) && \ + !defined(__STL_USE_SGI_ALLOCATORS) +# define __STL_USE_STD_ALLOCATORS +# endif + +# ifndef __STL_DEFAULT_ALLOCATOR +# ifdef __STL_USE_STD_ALLOCATORS +# define __STL_DEFAULT_ALLOCATOR(T) allocator<T> +# else +# define __STL_DEFAULT_ALLOCATOR(T) alloc +# endif +# endif + // __STL_NO_NAMESPACES is a hook so that users can disable namespaces // without having to edit library headers. -# if defined(__STL_USE_NAMESPACES) && !defined(__STL_NO_NAMESPACES) +# if defined(__STL_HAS_NAMESPACES) && !defined(__STL_NO_NAMESPACES) # define __STD std # define __STL_BEGIN_NAMESPACE namespace std { # define __STL_END_NAMESPACE } -# define __STL_USE_NAMESPACE_FOR_RELOPS +# define __STL_USE_NAMESPACE_FOR_RELOPS # define __STL_BEGIN_RELOPS_NAMESPACE namespace std { # define __STL_END_RELOPS_NAMESPACE } # define __STD_RELOPS std +# define __STL_USE_NAMESPACES # else -# define __STD -# define __STL_BEGIN_NAMESPACE -# define __STL_END_NAMESPACE +# 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 +# define __STL_BEGIN_RELOPS_NAMESPACE +# define __STL_END_RELOPS_NAMESPACE +# define __STD_RELOPS +# undef __STL_USE_NAMESPACES # endif # ifdef __STL_USE_EXCEPTIONS # define __STL_TRY try # define __STL_CATCH_ALL catch(...) +# define __STL_THROW(x) throw x # define __STL_RETHROW throw # define __STL_NOTHROW throw() # define __STL_UNWIND(action) catch(...) { action; throw; } # else -# define __STL_TRY +# define __STL_TRY # define __STL_CATCH_ALL if (false) -# define __STL_RETHROW -# define __STL_NOTHROW -# define __STL_UNWIND(action) +# define __STL_THROW(x) +# define __STL_RETHROW +# define __STL_NOTHROW +# define __STL_UNWIND(action) # endif #ifdef __STL_ASSERTIONS diff --git a/contrib/libstdc++/stl/stl_construct.h b/contrib/libstdc++/stl/stl_construct.h index 4687635..761784d 100644 --- a/contrib/libstdc++/stl/stl_construct.h +++ b/contrib/libstdc++/stl/stl_construct.h @@ -35,35 +35,47 @@ __STL_BEGIN_NAMESPACE -template <class T> -inline void destroy(T* pointer) { - pointer->~T(); +// construct and destroy. These functions are not part of the C++ standard, +// and are provided for backward compatibility with the HP STL. + +template <class _Tp> +inline void destroy(_Tp* __pointer) { + __pointer->~_Tp(); +} + +template <class _T1, class _T2> +inline void construct(_T1* __p, const _T2& __value) { + new (__p) _T1(__value); } -template <class T1, class T2> -inline void construct(T1* p, const T2& value) { - new (p) T1(value); +template <class _T1> +inline void construct(_T1* __p) { + new (__p) _T1(); } -template <class ForwardIterator> +template <class _ForwardIterator> inline void -__destroy_aux(ForwardIterator first, ForwardIterator last, __false_type) { - for ( ; first < last; ++first) - destroy(&*first); +__destroy_aux(_ForwardIterator __first, _ForwardIterator __last, __false_type) +{ + for ( ; __first != __last; ++__first) + destroy(&*__first); } -template <class ForwardIterator> -inline void __destroy_aux(ForwardIterator, ForwardIterator, __true_type) {} +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, class _Tp> +inline void +__destroy(_ForwardIterator __first, _ForwardIterator __last, _Tp*) +{ + typedef typename __type_traits<_Tp>::has_trivial_destructor + _Trivial_destructor; + __destroy_aux(__first, __last, _Trivial_destructor()); } -template <class ForwardIterator> -inline void destroy(ForwardIterator first, ForwardIterator last) { - __destroy(first, last, value_type(first)); +template <class _ForwardIterator> +inline void destroy(_ForwardIterator __first, _ForwardIterator __last) { + __destroy(__first, __last, __VALUE_TYPE(__first)); } inline void destroy(char*, char*) {} diff --git a/contrib/libstdc++/stl/stl_deque.h b/contrib/libstdc++/stl/stl_deque.h index 72325d5..48a4c76 100644 --- a/contrib/libstdc++/stl/stl_deque.h +++ b/contrib/libstdc++/stl/stl_deque.h @@ -53,8 +53,8 @@ * [map, map + map_size) is a valid, non-empty range. * [start.node, finish.node] is a valid range contained within * [map, map + map_size). - * A pointer in the range [map, map + map_size) points to an allocated - * node if and only if the pointer is in the range [start.node, finish.node]. + * A pointer in the range [map, map + map_size) points to an allocated node + * if and only if the pointer is in the range [start.node, finish.node]. */ @@ -83,126 +83,136 @@ __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 +#pragma set woff 1375 #endif // Note: this function is simply a kludge to work around several compilers' // bugs in handling constant expressions. -inline size_t __deque_buf_size(size_t n, size_t sz) +inline size_t +__deque_buf_size(size_t __n, size_t __size) { - return n != 0 ? n : (sz < 512 ? size_t(512 / sz) : size_t(1)); + return __n != 0 ? __n : (__size < 512 ? size_t(512 / __size) : size_t(1)); } #ifndef __STL_NON_TYPE_TMPL_PARAM_BUG -template <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)); } +template <class _Tp, class _Ref, class _Ptr, size_t __bufsiz> +struct _Deque_iterator { + typedef _Deque_iterator<_Tp,_Tp&,_Tp*,__bufsiz> iterator; + typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*,__bufsiz> const_iterator; + static size_t + _S_buffer_size() { return __deque_buf_size(__bufsiz, sizeof(_Tp)); } #else /* __STL_NON_TYPE_TMPL_PARAM_BUG */ -template <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)); } +template <class _Tp, class _Ref, class _Ptr> +struct _Deque_iterator { + typedef _Deque_iterator<_Tp, _Tp&, _Tp*> iterator; + typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator; + static size_t + _S_buffer_size() { return __deque_buf_size(0, sizeof(_Tp)); } #endif typedef random_access_iterator_tag iterator_category; - typedef T value_type; - typedef Ptr pointer; - typedef Ref reference; + typedef _Tp value_type; + typedef _Ptr pointer; + typedef _Ref reference; typedef size_t size_type; typedef ptrdiff_t difference_type; - typedef T** map_pointer; + typedef _Tp** _Map_pointer; - typedef __deque_iterator self; + typedef _Deque_iterator _Self; - T* cur; - T* first; - T* last; - map_pointer node; + _Tp* _M_cur; + _Tp* _M_first; + _Tp* _M_last; + _Map_pointer _M_node; - __deque_iterator(T* x, map_pointer y) - : cur(x), first(*y), last(*y + buffer_size()), node(y) {} - __deque_iterator() : cur(0), first(0), last(0), node(0) {} - __deque_iterator(const iterator& x) - : cur(x.cur), first(x.first), last(x.last), node(x.node) {} + _Deque_iterator(_Tp* __x, _Map_pointer __y) + : _M_cur(__x), _M_first(*__y), + _M_last(*__y + _S_buffer_size()), _M_node(__y) {} + _Deque_iterator() : _M_cur(0), _M_first(0), _M_last(0), _M_node(0) {} + _Deque_iterator(const iterator& __x) + : _M_cur(__x._M_cur), _M_first(__x._M_first), + _M_last(__x._M_last), _M_node(__x._M_node) {} - reference operator*() const { return *cur; } + reference operator*() const { return *_M_cur; } #ifndef __SGI_STL_NO_ARROW_OPERATOR - pointer operator->() const { return &(operator*()); } + pointer operator->() const { return _M_cur; } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ - difference_type operator-(const self& x) const { - return difference_type(buffer_size()) * (node - x.node - 1) + - (cur - first) + (x.last - x.cur); + difference_type operator-(const _Self& __x) const { + return difference_type(_S_buffer_size()) * (_M_node - __x._M_node - 1) + + (_M_cur - _M_first) + (__x._M_last - __x._M_cur); } - self& operator++() { - ++cur; - if (cur == last) { - set_node(node + 1); - cur = first; + _Self& operator++() { + ++_M_cur; + if (_M_cur == _M_last) { + _M_set_node(_M_node + 1); + _M_cur = _M_first; } return *this; } - self operator++(int) { - self tmp = *this; + _Self operator++(int) { + _Self __tmp = *this; ++*this; - return tmp; + return __tmp; } - self& operator--() { - if (cur == first) { - set_node(node - 1); - cur = last; + _Self& operator--() { + if (_M_cur == _M_first) { + _M_set_node(_M_node - 1); + _M_cur = _M_last; } - --cur; + --_M_cur; return *this; } - self operator--(int) { - self tmp = *this; + _Self operator--(int) { + _Self __tmp = *this; --*this; - return tmp; + return __tmp; } - self& operator+=(difference_type n) { - difference_type offset = n + (cur - first); - if (offset >= 0 && offset < difference_type(buffer_size())) - cur += n; + _Self& operator+=(difference_type __n) + { + difference_type __offset = __n + (_M_cur - _M_first); + if (__offset >= 0 && __offset < difference_type(_S_buffer_size())) + _M_cur += __n; else { - difference_type node_offset = - offset > 0 ? offset / difference_type(buffer_size()) - : -difference_type((-offset - 1) / buffer_size()) - 1; - set_node(node + node_offset); - cur = first + (offset - node_offset * difference_type(buffer_size())); + difference_type __node_offset = + __offset > 0 ? __offset / difference_type(_S_buffer_size()) + : -difference_type((-__offset - 1) / _S_buffer_size()) - 1; + _M_set_node(_M_node + __node_offset); + _M_cur = _M_first + + (__offset - __node_offset * difference_type(_S_buffer_size())); } return *this; } - self operator+(difference_type n) const { - self tmp = *this; - return tmp += n; + _Self operator+(difference_type __n) const + { + _Self __tmp = *this; + return __tmp += __n; } - self& operator-=(difference_type n) { return *this += -n; } + _Self& operator-=(difference_type __n) { return *this += -__n; } - self operator-(difference_type n) const { - self tmp = *this; - return tmp -= n; + _Self operator-(difference_type __n) const { + _Self __tmp = *this; + return __tmp -= __n; } - reference operator[](difference_type n) const { return *(*this + n); } + reference operator[](difference_type __n) const { return *(*this + __n); } - bool operator==(const self& x) const { return cur == x.cur; } - bool operator!=(const self& x) const { return !(*this == x); } - bool operator<(const self& x) const { - return (node == x.node) ? (cur < x.cur) : (node < x.node); + bool operator==(const _Self& __x) const { return _M_cur == __x._M_cur; } + bool operator!=(const _Self& __x) const { return !(*this == __x); } + bool operator<(const _Self& __x) const { + return (_M_node == __x._M_node) ? + (_M_cur < __x._M_cur) : (_M_node < __x._M_node); } - void set_node(map_pointer new_node) { - node = new_node; - first = *new_node; - last = first + difference_type(buffer_size()); + void _M_set_node(_Map_pointer __new_node) { + _M_node = __new_node; + _M_first = *__new_node; + _M_last = _M_first + difference_type(_S_buffer_size()); } }; @@ -210,35 +220,40 @@ struct __deque_iterator { #ifndef __STL_NON_TYPE_TMPL_PARAM_BUG -template <class T, class Ref, class Ptr, size_t BufSiz> +template <class _Tp, class _Ref, class _Ptr, size_t __bufsiz> inline random_access_iterator_tag -iterator_category(const __deque_iterator<T, Ref, Ptr, BufSiz>&) { +iterator_category(const _Deque_iterator<_Tp,_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>&) { +template <class _Tp, class _Ref, class _Ptr, size_t __bufsiz> +inline _Tp* +value_type(const _Deque_iterator<_Tp,_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>&) { +template <class _Tp, class _Ref, class _Ptr, size_t __bufsiz> +inline ptrdiff_t* +distance_type(const _Deque_iterator<_Tp,_Ref,_Ptr,__bufsiz>&) { return 0; } #else /* __STL_NON_TYPE_TMPL_PARAM_BUG */ -template <class T, class Ref, class Ptr> +template <class _Tp, class _Ref, class _Ptr> inline random_access_iterator_tag -iterator_category(const __deque_iterator<T, Ref, Ptr>&) { +iterator_category(const _Deque_iterator<_Tp,_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 _Tp, class _Ref, class _Ptr> +inline _Tp* +value_type(const _Deque_iterator<_Tp,_Ref,_Ptr>&) { return 0; } -template <class T, class Ref, class Ptr> -inline ptrdiff_t* distance_type(const __deque_iterator<T, Ref, Ptr>&) { +template <class _Tp, class _Ref, class _Ptr> +inline ptrdiff_t* +distance_type(const _Deque_iterator<_Tp,_Ref,_Ptr>&) { return 0; } @@ -246,13 +261,226 @@ inline ptrdiff_t* distance_type(const __deque_iterator<T, Ref, Ptr>&) { #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ +// Deque base class. It has two purposes. First, its constructor +// and destructor allocate (but don't initialize) storage. This makes +// exception safety easier. Second, the base class encapsulates all of +// the differences between SGI-style allocators and standard-conforming +// allocators. + +#ifdef __STL_USE_STD_ALLOCATORS + +// Base class for ordinary allocators. +template <class _Tp, class _Alloc, size_t __bufsiz, bool __is_static> +class _Deque_alloc_base { +public: + typedef typename _Alloc_traits<_Tp,_Alloc>::allocator_type allocator_type; + allocator_type get_allocator() const { return node_allocator; } + + _Deque_alloc_base(const allocator_type& __a) + : node_allocator(__a), map_allocator(__a), _M_map(0), _M_map_size(0) + {} + +protected: + typedef typename _Alloc_traits<_Tp*, _Alloc>::allocator_type + map_allocator_type; + + allocator_type node_allocator; + map_allocator_type map_allocator; + + _Tp* _M_allocate_node() { + return node_allocator.allocate(__deque_buf_size(__bufsiz,sizeof(_Tp))); + } + void _M_deallocate_node(_Tp* __p) { + node_allocator.deallocate(__p, __deque_buf_size(__bufsiz,sizeof(_Tp))); + } + _Tp** _M_allocate_map(size_t __n) + { return map_allocator.allocate(__n); } + void _M_deallocate_map(_Tp** __p, size_t __n) + { map_allocator.deallocate(__p, __n); } + + _Tp** _M_map; + size_t _M_map_size; +}; + +// Specialization for instanceless allocators. +template <class _Tp, class _Alloc, size_t __bufsiz> +class _Deque_alloc_base<_Tp, _Alloc, __bufsiz, true> +{ +public: + typedef typename _Alloc_traits<_Tp,_Alloc>::allocator_type allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Deque_alloc_base(const allocator_type&) : _M_map(0), _M_map_size(0) {} + +protected: + typedef typename _Alloc_traits<_Tp, _Alloc>::_Alloc_type _Node_alloc_type; + typedef typename _Alloc_traits<_Tp*, _Alloc>::_Alloc_type _Map_alloc_type; + + _Tp* _M_allocate_node() + { return _Node_alloc_type::allocate(__deque_buf_size(__bufsiz, + sizeof(_Tp))); } + void _M_deallocate_node(_Tp* __p) + { _Node_alloc_type::deallocate(__p, __deque_buf_size(__bufsiz, + sizeof(_Tp))); } + _Tp** _M_allocate_map(size_t __n) + { return _Map_alloc_type::allocate(__n); } + void _M_deallocate_map(_Tp** __p, size_t __n) + { _Map_alloc_type::deallocate(__p, __n); } + + _Tp** _M_map; + size_t _M_map_size; +}; + +template <class _Tp, class _Alloc, size_t __bufsiz> +class _Deque_base + : public _Deque_alloc_base<_Tp,_Alloc,__bufsiz, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> +{ +public: + typedef _Deque_alloc_base<_Tp,_Alloc,__bufsiz, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> + _Base; + typedef typename _Base::allocator_type allocator_type; + typedef _Deque_iterator<_Tp,_Tp&,_Tp*,__bufsiz> iterator; + typedef _Deque_iterator<_Tp,const _Tp&,const _Tp&, __bufsiz> const_iterator; + + _Deque_base(const allocator_type& __a, size_t __num_elements) + : _Base(__a), _M_start(), _M_finish() + { _M_initialize_map(__num_elements); } + _Deque_base(const allocator_type& __a) + : _Base(__a), _M_start(), _M_finish() {} + ~_Deque_base(); + +protected: + void _M_initialize_map(size_t); + void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish); + void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish); + enum { _S_initial_map_size = 8 }; + +protected: + iterator _M_start; + iterator _M_finish; +}; + +#else /* __STL_USE_STD_ALLOCATORS */ + +template <class _Tp, class _Alloc, size_t __bufsiz> +class _Deque_base { +public: +#ifndef __STL_NON_TYPE_TMPL_PARAM_BUG + typedef _Deque_iterator<_Tp,_Tp&,_Tp*,__bufsiz> iterator; + typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*, __bufsiz> const_iterator; +#else /* __STL_NON_TYPE_TMPL_PARAM_BUG */ + typedef _Deque_iterator<_Tp,_Tp&,_Tp*> iterator; + typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*> const_iterator; +#endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */ + + typedef _Alloc allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Deque_base(const allocator_type&, size_t __num_elements) + : _M_map(0), _M_map_size(0), _M_start(), _M_finish() { + _M_initialize_map(__num_elements); + } + _Deque_base(const allocator_type&) + : _M_map(0), _M_map_size(0), _M_start(), _M_finish() {} + ~_Deque_base(); + +protected: + void _M_initialize_map(size_t); + void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish); + void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish); + enum { _S_initial_map_size = 8 }; + +protected: + _Tp** _M_map; + size_t _M_map_size; + iterator _M_start; + iterator _M_finish; + + typedef simple_alloc<_Tp, _Alloc> _Node_alloc_type; + typedef simple_alloc<_Tp*, _Alloc> _Map_alloc_type; + + _Tp* _M_allocate_node() + { return _Node_alloc_type::allocate(__deque_buf_size(__bufsiz, + sizeof(_Tp))); } + void _M_deallocate_node(_Tp* __p) + { _Node_alloc_type::deallocate(__p, __deque_buf_size(__bufsiz, + sizeof(_Tp))); } + _Tp** _M_allocate_map(size_t __n) + { return _Map_alloc_type::allocate(__n); } + void _M_deallocate_map(_Tp** __p, size_t __n) + { _Map_alloc_type::deallocate(__p, __n); } +}; + +#endif /* __STL_USE_STD_ALLOCATORS */ + +// Non-inline member functions from _Deque_base. + +template <class _Tp, class _Alloc, size_t __bufsiz> +_Deque_base<_Tp,_Alloc,__bufsiz>::~_Deque_base() { + if (_M_map) { + _M_destroy_nodes(_M_start._M_node, _M_finish._M_node + 1); + _M_deallocate_map(_M_map, _M_map_size); + } +} + +template <class _Tp, class _Alloc, size_t __bufsiz> +void +_Deque_base<_Tp,_Alloc,__bufsiz>::_M_initialize_map(size_t __num_elements) +{ + size_t __num_nodes = + __num_elements / __deque_buf_size(__bufsiz, sizeof(_Tp)) + 1; + + _M_map_size = max((size_t) _S_initial_map_size, __num_nodes + 2); + _M_map = _M_allocate_map(_M_map_size); + + _Tp** __nstart = _M_map + (_M_map_size - __num_nodes) / 2; + _Tp** __nfinish = __nstart + __num_nodes; + + __STL_TRY { + _M_create_nodes(__nstart, __nfinish); + } + __STL_UNWIND((_M_deallocate_map(_M_map, _M_map_size), + _M_map = 0, _M_map_size = 0)); + _M_start._M_set_node(__nstart); + _M_finish._M_set_node(__nfinish - 1); + _M_start._M_cur = _M_start._M_first; + _M_finish._M_cur = _M_finish._M_first + + __num_elements % __deque_buf_size(__bufsiz, sizeof(_Tp)); +} + +template <class _Tp, class _Alloc, size_t __bufsiz> +void +_Deque_base<_Tp,_Alloc,__bufsiz>::_M_create_nodes(_Tp** __nstart, + _Tp** __nfinish) +{ + _Tp** __cur; + __STL_TRY { + for (__cur = __nstart; __cur < __nfinish; ++__cur) + *__cur = _M_allocate_node(); + } + __STL_UNWIND(_M_destroy_nodes(__nstart, __cur)); +} + +template <class _Tp, class _Alloc, size_t __bufsiz> +void +_Deque_base<_Tp,_Alloc,__bufsiz>::_M_destroy_nodes(_Tp** __nstart, + _Tp** __nfinish) +{ + for (_Tp** __n = __nstart; __n < __nfinish; ++__n) + _M_deallocate_node(*__n); +} + // See __deque_buf_size(). The only reason that the default value is 0 // is as a workaround for bugs in the way that some compilers handle // constant expressions. -template <class T, class Alloc = alloc, size_t BufSiz = 0> -class deque { +template <class _Tp, class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp), + size_t __bufsiz = 0> +class deque : protected _Deque_base<_Tp, _Alloc, __bufsiz> { + typedef _Deque_base<_Tp, _Alloc, __bufsiz> _Base; public: // Basic types - typedef T value_type; + typedef _Tp value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type& reference; @@ -260,14 +488,12 @@ public: // Basic types typedef size_t size_type; typedef ptrdiff_t difference_type; + typedef typename _Base::allocator_type allocator_type; + allocator_type get_allocator() const { return _Base::get_allocator(); } + public: // Iterators -#ifndef __STL_NON_TYPE_TMPL_PARAM_BUG - typedef __deque_iterator<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 */ + typedef typename _Base::iterator iterator; + typedef typename _Base::const_iterator const_iterator; #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION typedef reverse_iterator<const_iterator> const_reverse_iterator; @@ -281,1016 +507,1146 @@ public: // Iterators #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ protected: // Internal typedefs - typedef pointer* map_pointer; - typedef simple_alloc<value_type, Alloc> data_allocator; - typedef simple_alloc<pointer, Alloc> map_allocator; + typedef pointer* _Map_pointer; + static size_t _S_buffer_size() + { return __deque_buf_size(__bufsiz, sizeof(_Tp)); } + +protected: +#ifdef __STL_USE_NAMESPACES + using _Base::_M_initialize_map; + using _Base::_M_create_nodes; + using _Base::_M_destroy_nodes; + using _Base::_M_allocate_node; + using _Base::_M_deallocate_node; + using _Base::_M_allocate_map; + using _Base::_M_deallocate_map; + + using _Base::_M_map; + using _Base::_M_map_size; + using _Base::_M_start; + using _Base::_M_finish; +#endif /* __STL_USE_NAMESPACES */ - static size_type buffer_size() { - return __deque_buf_size(BufSiz, sizeof(value_type)); +public: // Basic accessors + iterator begin() { return _M_start; } + iterator end() { return _M_finish; } + const_iterator begin() const { return _M_start; } + const_iterator end() const { return _M_finish; } + + reverse_iterator rbegin() { return reverse_iterator(_M_finish); } + reverse_iterator rend() { return reverse_iterator(_M_start); } + const_reverse_iterator rbegin() const + { return const_reverse_iterator(_M_finish); } + const_reverse_iterator rend() const + { return const_reverse_iterator(_M_start); } + + reference operator[](size_type __n) + { return _M_start[difference_type(__n)]; } + const_reference operator[](size_type __n) const + { return _M_start[difference_type(__n)]; } + + reference front() { return *_M_start; } + reference back() { + iterator __tmp = _M_finish; + --__tmp; + return *__tmp; + } + const_reference front() const { return *_M_start; } + const_reference back() const { + const_iterator __tmp = _M_finish; + --__tmp; + return *__tmp; } - static size_type initial_map_size() { return 8; } -protected: // Data members - iterator start; - iterator finish; + size_type size() const { return _M_finish - _M_start;; } + size_type max_size() const { return size_type(-1); } + bool empty() const { return _M_finish == _M_start; } - map_pointer map; - size_type map_size; +public: // Constructor, destructor. + explicit deque(const allocator_type& __a = allocator_type()) + : _Base(__a, 0) {} + deque(const deque& __x) : _Base(__x.get_allocator(), __x.size()) + { uninitialized_copy(__x.begin(), __x.end(), _M_start); } + deque(size_type __n, const value_type& __value, + const allocator_type& __a = allocator_type()) : _Base(__a, __n) + { _M_fill_initialize(__value); } + explicit deque(size_type __n) : _Base(allocator_type(), __n) + { _M_fill_initialize(value_type()); } -public: // Basic accessors - iterator begin() { return start; } - iterator end() { return finish; } - const_iterator begin() const { return start; } - const_iterator end() const { return finish; } +#ifdef __STL_MEMBER_TEMPLATES - reverse_iterator rbegin() { return reverse_iterator(finish); } - reverse_iterator rend() { return reverse_iterator(start); } - const_reverse_iterator rbegin() const { - return const_reverse_iterator(finish); - } - const_reverse_iterator rend() const { - return const_reverse_iterator(start); + // Check whether it's an integral type. If so, it's not an iterator. + template <class _InputIterator> + deque(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) : _Base(__a) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_initialize_dispatch(__first, __last, _Integral()); } - reference operator[](size_type n) { return start[difference_type(n)]; } - const_reference operator[](size_type n) const { - return start[difference_type(n)]; + template <class _Integer> + void _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) { + _M_initialize_map(__n); + _M_fill_initialize(__x); } - reference front() { return *start; } - reference back() { - iterator tmp = finish; - --tmp; - return *tmp; - } - const_reference front() const { return *start; } - const_reference back() const { - const_iterator tmp = finish; - --tmp; - return *tmp; + template <class _InputIter> + void _M_initialize_dispatch(_InputIter __first, _InputIter __last, + __false_type) { + _M_range_initialize(__first, __last, __ITERATOR_CATEGORY(__first)); } - size_type size() const { return finish - start;; } - size_type max_size() const { return size_type(-1); } - bool empty() const { return finish == start; } +#else /* __STL_MEMBER_TEMPLATES */ -public: // Constructor, destructor. - deque() - : start(), finish(), map(0), map_size(0) - { - create_map_and_nodes(0); - } + deque(const value_type* __first, const value_type* __last, + const allocator_type& __a = allocator_type()) + : _Base(__a, __last - __first) + { uninitialized_copy(__first, __last, _M_start); } + deque(const_iterator __first, const_iterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a, __last - __first) + { uninitialized_copy(__first, __last, _M_start); } - deque(const deque& x) - : start(), finish(), map(0), map_size(0) - { - create_map_and_nodes(x.size()); - __STL_TRY { - uninitialized_copy(x.begin(), x.end(), start); +#endif /* __STL_MEMBER_TEMPLATES */ + + ~deque() { destroy(_M_start, _M_finish); } + + deque& operator= (const deque& __x) { + const size_type __len = size(); + if (&__x != this) { + if (__len >= __x.size()) + erase(copy(__x.begin(), __x.end(), _M_start), _M_finish); + else { + const_iterator __mid = __x.begin() + difference_type(__len); + copy(__x.begin(), __mid, _M_start); + insert(_M_finish, __mid, __x.end()); + } } - __STL_UNWIND(destroy_map_and_nodes()); - } + return *this; + } - deque(size_type n, const value_type& value) - : start(), finish(), map(0), map_size(0) - { - fill_initialize(n, value); + void swap(deque& __x) { + __STD::swap(_M_start, __x._M_start); + __STD::swap(_M_finish, __x._M_finish); + __STD::swap(_M_map, __x._M_map); + __STD::swap(_M_map_size, __x._M_map_size); } - deque(int n, const value_type& value) - : start(), finish(), map(0), map_size(0) - { - fill_initialize(n, value); - } - - deque(long n, const value_type& value) - : start(), finish(), map(0), map_size(0) - { - fill_initialize(n, value); - } +public: + // assign(), a generalized assignment member function. Two + // versions: one that takes a count, and one that takes a range. + // The range version is a member template, so we dispatch on whether + // or not the type is an integer. - explicit deque(size_type n) - : start(), finish(), map(0), map_size(0) - { - fill_initialize(n, value_type()); + void assign(size_type __n, const _Tp& __val) { + if (__n > size()) { + fill(begin(), end(), __val); + insert(end(), __n - size(), __val); + } + else { + erase(begin() + __n, end()); + fill(begin(), end(), __val); + } } #ifdef __STL_MEMBER_TEMPLATES - template <class InputIterator> - deque(InputIterator first, InputIterator last) - : start(), finish(), map(0), map_size(0) - { - range_initialize(first, last, iterator_category(first)); + template <class _InputIterator> + void assign(_InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_assign_dispatch(__first, __last, _Integral()); } -#else /* __STL_MEMBER_TEMPLATES */ +private: // helper functions for assign() - deque(const value_type* first, const value_type* last) - : start(), finish(), map(0), map_size(0) - { - create_map_and_nodes(last - first); - __STL_TRY { - uninitialized_copy(first, last, start); - } - __STL_UNWIND(destroy_map_and_nodes()); + template <class _Integer> + void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { assign((size_type) __n, (_Tp) __val); } + + template <class _InputIterator> + void _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) { + _M_assign_aux(__first, __last, __ITERATOR_CATEGORY(__first)); } - deque(const_iterator first, const_iterator last) - : start(), finish(), map(0), map_size(0) - { - create_map_and_nodes(last - first); - __STL_TRY { - uninitialized_copy(first, last, start); + template <class _InputIterator> + void _M_assign_aux(_InputIterator __first, _InputIterator __last, + input_iterator_tag); + + template <class _ForwardIterator> + void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag) { + size_type __len = 0; + distance(__first, __last, __len); + if (__len > size()) { + _ForwardIterator __mid = __first; + advance(__mid, size()); + copy(__first, __mid, begin()); + insert(end(), __mid, __last); } - __STL_UNWIND(destroy_map_and_nodes()); + else + erase(copy(__first, __last, begin()), end()); } #endif /* __STL_MEMBER_TEMPLATES */ - ~deque() { - destroy(start, finish); - destroy_map_and_nodes(); +public: // push_* and pop_* + + void push_back(const value_type& __t) { + if (_M_finish._M_cur != _M_finish._M_last - 1) { + construct(_M_finish._M_cur, __t); + ++_M_finish._M_cur; + } + else + _M_push_back_aux(__t); } - deque& operator= (const deque& x) { - const size_type len = size(); - if (&x != this) { - if (len >= x.size()) - erase(copy(x.begin(), x.end(), start), finish); - else { - const_iterator mid = x.begin() + difference_type(len); - copy(x.begin(), mid, start); - insert(finish, mid, x.end()); - } + void push_back() { + if (_M_finish._M_cur != _M_finish._M_last - 1) { + construct(_M_finish._M_cur); + ++_M_finish._M_cur; } - return *this; - } - - void swap(deque& x) { - __STD::swap(start, x.start); - __STD::swap(finish, x.finish); - __STD::swap(map, x.map); - __STD::swap(map_size, x.map_size); + else + _M_push_back_aux(); } -public: // push_* and pop_* - - void push_back(const value_type& t) { - if (finish.cur != finish.last - 1) { - construct(finish.cur, t); - ++finish.cur; + void push_front(const value_type& __t) { + if (_M_start._M_cur != _M_start._M_first) { + construct(_M_start._M_cur - 1, __t); + --_M_start._M_cur; } else - push_back_aux(t); + _M_push_front_aux(__t); } - void push_front(const value_type& t) { - if (start.cur != start.first) { - construct(start.cur - 1, t); - --start.cur; + void push_front() { + if (_M_start._M_cur != _M_start._M_first) { + construct(_M_start._M_cur - 1); + --_M_start._M_cur; } else - push_front_aux(t); + _M_push_front_aux(); } + void pop_back() { - if (finish.cur != finish.first) { - --finish.cur; - destroy(finish.cur); + if (_M_finish._M_cur != _M_finish._M_first) { + --_M_finish._M_cur; + destroy(_M_finish._M_cur); } else - pop_back_aux(); + _M_pop_back_aux(); } void pop_front() { - if (start.cur != start.last - 1) { - destroy(start.cur); - ++start.cur; + if (_M_start._M_cur != _M_start._M_last - 1) { + destroy(_M_start._M_cur); + ++_M_start._M_cur; } else - pop_front_aux(); + _M_pop_front_aux(); } public: // Insert - iterator insert(iterator position, const value_type& x) { - if (position.cur == start.cur) { - push_front(x); - return start; + iterator insert(iterator position, const value_type& __x) { + if (position._M_cur == _M_start._M_cur) { + push_front(__x); + return _M_start; } - else if (position.cur == finish.cur) { - push_back(x); - iterator tmp = finish; - --tmp; - return tmp; + else if (position._M_cur == _M_finish._M_cur) { + push_back(__x); + iterator __tmp = _M_finish; + --__tmp; + return __tmp; } else { - return insert_aux(position, x); + return _M_insert_aux(position, __x); } } - iterator insert(iterator position) { return insert(position, value_type()); } + iterator insert(iterator __position) + { return insert(__position, value_type()); } - void insert(iterator pos, size_type n, const value_type& x); + void insert(iterator __pos, size_type __n, const value_type& __x); - void insert(iterator pos, int n, const value_type& x) { - insert(pos, (size_type) n, x); - } - void insert(iterator pos, long n, const value_type& x) { - insert(pos, (size_type) n, x); +#ifdef __STL_MEMBER_TEMPLATES + + // Check whether it's an integral type. If so, it's not an iterator. + template <class _InputIterator> + void insert(iterator __pos, _InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_insert_dispatch(__pos, __first, __last, _Integral()); } -#ifdef __STL_MEMBER_TEMPLATES + template <class _Integer> + void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, + __true_type) { + insert(__pos, (size_type) __n, (value_type) __x); + } - template <class InputIterator> - void insert(iterator pos, InputIterator first, InputIterator last) { - insert(pos, first, last, iterator_category(first)); + template <class _InputIterator> + void _M_insert_dispatch(iterator __pos, + _InputIterator __first, _InputIterator __last, + __false_type) { + insert(__pos, __first, __last, __ITERATOR_CATEGORY(__first)); } #else /* __STL_MEMBER_TEMPLATES */ - void insert(iterator pos, const value_type* first, const value_type* last); - void insert(iterator pos, const_iterator first, const_iterator last); + void insert(iterator __pos, + const value_type* __first, const value_type* __last); + void insert(iterator __pos, + const_iterator __first, const_iterator __last); #endif /* __STL_MEMBER_TEMPLATES */ - void resize(size_type new_size, const value_type& x) { - const size_type len = size(); - if (new_size < len) - erase(start + new_size, finish); + void resize(size_type __new_size, const value_type& __x) { + const size_type __len = size(); + if (__new_size < __len) + erase(_M_start + __new_size, _M_finish); else - insert(finish, new_size - len, x); + insert(_M_finish, __new_size - __len, __x); } void resize(size_type new_size) { resize(new_size, value_type()); } public: // Erase - iterator erase(iterator pos) { - iterator next = pos; - ++next; - difference_type index = pos - start; - if (index < (size() >> 1)) { - copy_backward(start, pos, next); + iterator erase(iterator __pos) { + iterator __next = __pos; + ++__next; + difference_type __index = __pos - _M_start; + if (__index < (size() >> 1)) { + copy_backward(_M_start, __pos, __next); pop_front(); } else { - copy(next, finish, pos); + copy(__next, _M_finish, __pos); pop_back(); } - return start + index; + return _M_start + __index; } - iterator erase(iterator first, iterator last); + iterator erase(iterator __first, iterator __last); void clear(); protected: // Internal construction/destruction - void create_map_and_nodes(size_type num_elements); - void destroy_map_and_nodes(); - void fill_initialize(size_type n, const value_type& value); + void _M_fill_initialize(const value_type& __value); #ifdef __STL_MEMBER_TEMPLATES - template <class InputIterator> - void range_initialize(InputIterator first, InputIterator last, + template <class _InputIterator> + void _M_range_initialize(_InputIterator __first, _InputIterator __last, input_iterator_tag); - template <class ForwardIterator> - void range_initialize(ForwardIterator first, ForwardIterator last, + template <class _ForwardIterator> + void _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last, forward_iterator_tag); #endif /* __STL_MEMBER_TEMPLATES */ protected: // Internal push_* and pop_* - void push_back_aux(const value_type& t); - void push_front_aux(const value_type& t); - void pop_back_aux(); - void pop_front_aux(); + void _M_push_back_aux(const value_type&); + void _M_push_back_aux(); + void _M_push_front_aux(const value_type&); + void _M_push_front_aux(); + void _M_pop_back_aux(); + void _M_pop_front_aux(); protected: // Internal insert functions #ifdef __STL_MEMBER_TEMPLATES - template <class InputIterator> - void insert(iterator pos, InputIterator first, InputIterator last, + 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, + 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); + iterator _M_insert_aux(iterator __pos, const value_type& __x); + iterator _M_insert_aux(iterator __pos); + void _M_insert_aux(iterator __pos, size_type __n, const value_type& __x); #ifdef __STL_MEMBER_TEMPLATES - template <class ForwardIterator> - void insert_aux(iterator pos, ForwardIterator first, ForwardIterator last, - size_type n); + template <class _ForwardIterator> + void _M_insert_aux(iterator __pos, + _ForwardIterator __first, _ForwardIterator __last, + size_type __n); #else /* __STL_MEMBER_TEMPLATES */ - void insert_aux(iterator pos, - const value_type* first, const value_type* last, - size_type n); + void _M_insert_aux(iterator __pos, + const value_type* __first, const value_type* __last, + size_type __n); - void insert_aux(iterator pos, const_iterator first, const_iterator last, - size_type n); + void _M_insert_aux(iterator __pos, + const_iterator __first, const_iterator __last, + size_type __n); #endif /* __STL_MEMBER_TEMPLATES */ - iterator reserve_elements_at_front(size_type n) { - size_type vacancies = start.cur - start.first; - if (n > vacancies) - new_elements_at_front(n - vacancies); - return start - difference_type(n); + iterator _M_reserve_elements_at_front(size_type __n) { + size_type __vacancies = _M_start._M_cur - _M_start._M_first; + if (__n > __vacancies) + _M_new_elements_at_front(__n - __vacancies); + return _M_start - difference_type(__n); } - iterator reserve_elements_at_back(size_type n) { - size_type vacancies = (finish.last - finish.cur) - 1; - if (n > vacancies) - new_elements_at_back(n - vacancies); - return finish + difference_type(n); + iterator _M_reserve_elements_at_back(size_type __n) { + size_type __vacancies = (_M_finish._M_last - _M_finish._M_cur) - 1; + if (__n > __vacancies) + _M_new_elements_at_back(__n - __vacancies); + return _M_finish + difference_type(__n); } - void new_elements_at_front(size_type new_elements); - void new_elements_at_back(size_type new_elements); + void _M_new_elements_at_front(size_type __new_elements); + void _M_new_elements_at_back(size_type __new_elements); - void destroy_nodes_at_front(iterator before_start); - void destroy_nodes_at_back(iterator after_finish); +protected: // Allocation of _M_map and nodes -protected: // Allocation of map and nodes - - // Makes sure the map has space for new nodes. Does not actually - // add the nodes. Can invalidate map pointers. (And consequently, + // Makes sure the _M_map has space for new nodes. Does not actually + // add the nodes. Can invalidate _M_map pointers. (And consequently, // deque iterators.) - void reserve_map_at_back (size_type nodes_to_add = 1) { - if (nodes_to_add + 1 > map_size - (finish.node - map)) - reallocate_map(nodes_to_add, false); - } - - void reserve_map_at_front (size_type nodes_to_add = 1) { - if (nodes_to_add > start.node - map) - reallocate_map(nodes_to_add, true); + void _M_reserve_map_at_back (size_type __nodes_to_add = 1) { + if (__nodes_to_add + 1 > _M_map_size - (_M_finish._M_node - _M_map)) + _M_reallocate_map(__nodes_to_add, false); } - void reallocate_map(size_type nodes_to_add, bool add_at_front); - - pointer allocate_node() { return data_allocator::allocate(buffer_size()); } - void deallocate_node(pointer n) { - data_allocator::deallocate(n, buffer_size()); + void _M_reserve_map_at_front (size_type __nodes_to_add = 1) { + if (__nodes_to_add > size_type(_M_start._M_node - _M_map)) + _M_reallocate_map(__nodes_to_add, true); } + void _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front); + #ifdef __STL_NON_TYPE_TMPL_PARAM_BUG public: - bool operator==(const deque<T, Alloc, 0>& x) const { - return size() == x.size() && equal(begin(), end(), x.begin()); + bool operator==(const deque<_Tp,_Alloc,0>& __x) const { + return size() == __x.size() && equal(begin(), end(), __x.begin()); } - bool operator!=(const deque<T, Alloc, 0>& x) const { - return size() != x.size() || !equal(begin(), end(), x.begin()); + bool operator!=(const deque<_Tp,_Alloc,0>& __x) const { + return size() != __x.size() || !equal(begin(), end(), __x.begin()); } - bool operator<(const deque<T, Alloc, 0>& x) const { - return lexicographical_compare(begin(), end(), x.begin(), x.end()); + bool operator<(const deque<_Tp,_Alloc,0>& __x) const { + return lexicographical_compare(begin(), end(), __x.begin(), __x.end()); } #endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */ }; // Non-inline member functions -template <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; +#ifdef __STL_MEMBER_TEMPLATES + +template <class _Tp, class _Alloc, size_t __bufsize> +template <class _InputIter> +void deque<_Tp, _Alloc, __bufsize> + ::_M_assign_aux(_InputIter __first, _InputIter __last, input_iterator_tag) +{ + iterator __cur = begin(); + for ( ; __first != __last && __cur != end(); ++__cur, ++__first) + *__cur = *__first; + if (__first == __last) + erase(__cur, end()); + else + insert(end(), __first, __last); +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +template <class _Tp, class _Alloc, size_t __bufsize> +void +deque<_Tp, _Alloc, __bufsize>::insert(iterator __pos, + size_type __n, const value_type& __x) +{ + if (__pos._M_cur == _M_start._M_cur) { + iterator __new_start = _M_reserve_elements_at_front(__n); + uninitialized_fill(__new_start, _M_start, __x); + _M_start = __new_start; } - else if (pos.cur == finish.cur) { - iterator new_finish = reserve_elements_at_back(n); - uninitialized_fill(finish, new_finish, x); - finish = new_finish; + else if (__pos._M_cur == _M_finish._M_cur) { + iterator __new_finish = _M_reserve_elements_at_back(__n); + uninitialized_fill(_M_finish, __new_finish, __x); + _M_finish = __new_finish; } else - insert_aux(pos, n, x); + _M_insert_aux(__pos, __n, __x); } #ifndef __STL_MEMBER_TEMPLATES -template <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); +template <class _Tp, class _Alloc, size_t __bufsize> +void deque<_Tp, _Alloc, __bufsize>::insert(iterator __pos, + const value_type* __first, + const value_type* __last) { + size_type __n = __last - __first; + if (__pos._M_cur == _M_start._M_cur) { + iterator __new_start = _M_reserve_elements_at_front(__n); __STL_TRY { - uninitialized_copy(first, last, new_start); - start = new_start; + uninitialized_copy(__first, __last, __new_start); + _M_start = __new_start; } - __STL_UNWIND(destroy_nodes_at_front(new_start)); + __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node)); } - else if (pos.cur == finish.cur) { - iterator new_finish = reserve_elements_at_back(n); + else if (__pos._M_cur == _M_finish._M_cur) { + iterator __new_finish = _M_reserve_elements_at_back(__n); __STL_TRY { - uninitialized_copy(first, last, finish); - finish = new_finish; + uninitialized_copy(__first, __last, _M_finish); + _M_finish = __new_finish; } - __STL_UNWIND(destroy_nodes_at_back(new_finish)); + __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, + __new_finish._M_node + 1)); } else - insert_aux(pos, first, last, n); + _M_insert_aux(__pos, __first, __last, __n); } -template <class T, class Alloc, size_t BufSize> -void deque<T, Alloc, BufSize>::insert(iterator pos, - const_iterator first, - const_iterator last) +template <class _Tp, class _Alloc, size_t __bufsize> +void deque<_Tp,_Alloc,__bufsize>::insert(iterator __pos, + const_iterator __first, + const_iterator __last) { - size_type n = last - first; - if (pos.cur == start.cur) { - iterator new_start = reserve_elements_at_front(n); + size_type __n = __last - __first; + if (__pos._M_cur == _M_start._M_cur) { + iterator __new_start = _M_reserve_elements_at_front(__n); __STL_TRY { - uninitialized_copy(first, last, new_start); - start = new_start; + uninitialized_copy(__first, __last, __new_start); + _M_start = __new_start; } - __STL_UNWIND(destroy_nodes_at_front(new_start)); + __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node)); } - else if (pos.cur == finish.cur) { - iterator new_finish = reserve_elements_at_back(n); + else if (__pos._M_cur == _M_finish._M_cur) { + iterator __new_finish = _M_reserve_elements_at_back(__n); __STL_TRY { - uninitialized_copy(first, last, finish); - finish = new_finish; + uninitialized_copy(__first, __last, _M_finish); + _M_finish = __new_finish; } - __STL_UNWIND(destroy_nodes_at_back(new_finish)); + __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, + __new_finish._M_node + 1)); } else - insert_aux(pos, first, last, n); + _M_insert_aux(__pos, __first, __last, __n); } #endif /* __STL_MEMBER_TEMPLATES */ -template <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) { +template <class _Tp, class _Alloc, size_t __bufsize> +deque<_Tp,_Alloc,__bufsize>::iterator +deque<_Tp,_Alloc,__bufsize>::erase(iterator __first, iterator __last) +{ + if (__first == _M_start && __last == _M_finish) { clear(); - return finish; + return _M_finish; } else { - difference_type n = last - first; - difference_type elems_before = first - start; - if (elems_before < (size() - n) / 2) { - copy_backward(start, first, last); - iterator new_start = start + n; - destroy(start, new_start); - for (map_pointer cur = start.node; cur < new_start.node; ++cur) - data_allocator::deallocate(*cur, buffer_size()); - start = new_start; + difference_type __n = __last - __first; + difference_type __elems_before = __first - _M_start; + if (__elems_before < (size() - __n) / 2) { + copy_backward(_M_start, __first, __last); + iterator __new_start = _M_start + __n; + destroy(_M_start, __new_start); + _M_destroy_nodes(__new_start._M_node, _M_start._M_node); + _M_start = __new_start; } else { - copy(last, finish, first); - iterator new_finish = finish - n; - destroy(new_finish, finish); - for (map_pointer cur = new_finish.node + 1; cur <= finish.node; ++cur) - data_allocator::deallocate(*cur, buffer_size()); - finish = new_finish; + copy(__last, _M_finish, __first); + iterator __new_finish = _M_finish - __n; + destroy(__new_finish, _M_finish); + _M_destroy_nodes(__new_finish._M_node + 1, _M_finish._M_node + 1); + _M_finish = __new_finish; } - return start + elems_before; + return _M_start + __elems_before; } } -template <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()); +template <class _Tp, class _Alloc, size_t __bufsize> +void deque<_Tp,_Alloc,__bufsize>::clear() +{ + for (_Map_pointer __node = _M_start._M_node + 1; + __node < _M_finish._M_node; + ++__node) { + destroy(*__node, *__node + _S_buffer_size()); + _M_deallocate_node(*__node); } - if (start.node != finish.node) { - destroy(start.cur, start.last); - destroy(finish.first, finish.cur); - data_allocator::deallocate(finish.first, buffer_size()); + if (_M_start._M_node != _M_finish._M_node) { + destroy(_M_start._M_cur, _M_start._M_last); + destroy(_M_finish._M_first, _M_finish._M_cur); + _M_deallocate_node(_M_finish._M_first); } else - destroy(start.cur, finish.cur); + destroy(_M_start._M_cur, _M_finish._M_cur); - finish = start; + _M_finish = _M_start; } -template <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; +// Precondition: _M_start and _M_finish have already been initialized, +// but none of the deque's elements have yet been constructed. +template <class _Tp, class _Alloc, size_t __bufsize> +void +deque<_Tp,_Alloc,__bufsize>::_M_fill_initialize(const value_type& __value) { + _Map_pointer __cur; __STL_TRY { - for (cur = nstart; cur <= nfinish; ++cur) - *cur = allocate_node(); - } -# ifdef __STL_USE_EXCEPTIONS - catch(...) { - for (map_pointer n = nstart; n < cur; ++n) - deallocate_node(*n); - map_allocator::deallocate(map, map_size); - throw; + for (__cur = _M_start._M_node; __cur < _M_finish._M_node; ++__cur) + uninitialized_fill(*__cur, *__cur + _S_buffer_size(), __value); + uninitialized_fill(_M_finish._M_first, _M_finish._M_cur, __value); } -# endif /* __STL_USE_EXCEPTIONS */ - - start.set_node(nstart); - finish.set_node(nfinish); - start.cur = start.first; - finish.cur = finish.first + num_elements % buffer_size(); + __STL_UNWIND(destroy(_M_start, iterator(*__cur, __cur))); } -// This is only used as a cleanup function in catch clauses. -template <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); +#ifdef __STL_MEMBER_TEMPLATES + +template <class _Tp, class _Alloc, size_t __bufsize> +template <class _InputIterator> +void +deque<_Tp,_Alloc,__bufsize>::_M_range_initialize(_InputIterator __first, + _InputIterator __last, + input_iterator_tag) +{ + _M_initialize_map(0); + for ( ; __first != __last; ++__first) + push_back(*__first); } - -template <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; +template <class _Tp, class _Alloc, size_t __bufsize> +template <class _ForwardIterator> +void +deque<_Tp,_Alloc,__bufsize>::_M_range_initialize(_ForwardIterator __first, + _ForwardIterator __last, + forward_iterator_tag) +{ + size_type __n = 0; + distance(__first, __last, __n); + _M_initialize_map(__n); + + _Map_pointer __cur_node; __STL_TRY { - for (cur = start.node; cur < finish.node; ++cur) - uninitialized_fill(*cur, *cur + buffer_size(), value); - uninitialized_fill(finish.first, finish.cur, value); - } -# ifdef __STL_USE_EXCEPTIONS - catch(...) { - for (map_pointer n = start.node; n < cur; ++n) - destroy(*n, *n + buffer_size()); - destroy_map_and_nodes(); - throw; + for (__cur_node = _M_start._M_node; + __cur_node < _M_finish._M_node; + ++__cur_node) { + _ForwardIterator __mid = __first; + advance(__mid, _S_buffer_size()); + uninitialized_copy(__first, __mid, *__cur_node); + __first = __mid; + } + uninitialized_copy(__first, __last, _M_finish._M_first); } -# endif /* __STL_USE_EXCEPTIONS */ + __STL_UNWIND(destroy(_M_start, iterator(*__cur_node, __cur_node))); } -#ifdef __STL_MEMBER_TEMPLATES - -template <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); -} +#endif /* __STL_MEMBER_TEMPLATES */ -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); +// Called only if _M_finish._M_cur == _M_finish._M_last - 1. +template <class _Tp, class _Alloc, size_t __bufsize> +void +deque<_Tp,_Alloc,__bufsize>::_M_push_back_aux(const value_type& __t) +{ + value_type __t_copy = __t; + _M_reserve_map_at_back(); + *(_M_finish._M_node + 1) = _M_allocate_node(); __STL_TRY { - uninitialized_copy(first, last, start); + construct(_M_finish._M_cur, __t_copy); + _M_finish._M_set_node(_M_finish._M_node + 1); + _M_finish._M_cur = _M_finish._M_first; } - __STL_UNWIND(destroy_map_and_nodes()); + __STL_UNWIND(_M_deallocate_node(*(_M_finish._M_node + 1))); } -#endif /* __STL_MEMBER_TEMPLATES */ - -// Called only if finish.cur == finish.last - 1. -template <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(); +// Called only if _M_finish._M_cur == _M_finish._M_last - 1. +template <class _Tp, class _Alloc, size_t __bufsize> +void +deque<_Tp,_Alloc,__bufsize>::_M_push_back_aux() +{ + _M_reserve_map_at_back(); + *(_M_finish._M_node + 1) = _M_allocate_node(); __STL_TRY { - construct(finish.cur, t_copy); - finish.set_node(finish.node + 1); - finish.cur = finish.first; + construct(_M_finish._M_cur); + _M_finish._M_set_node(_M_finish._M_node + 1); + _M_finish._M_cur = _M_finish._M_first; } - __STL_UNWIND(deallocate_node(*(finish.node + 1))); + __STL_UNWIND(_M_deallocate_node(*(_M_finish._M_node + 1))); } -// Called only if start.cur == start.first. -template <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(); +// Called only if _M_start._M_cur == _M_start._M_first. +template <class _Tp, class _Alloc, size_t __bufsize> +void +deque<_Tp,_Alloc,__bufsize>::_M_push_front_aux(const value_type& __t) +{ + value_type __t_copy = __t; + _M_reserve_map_at_front(); + *(_M_start._M_node - 1) = _M_allocate_node(); __STL_TRY { - start.set_node(start.node - 1); - start.cur = start.last - 1; - construct(start.cur, t_copy); + _M_start._M_set_node(_M_start._M_node - 1); + _M_start._M_cur = _M_start._M_last - 1; + construct(_M_start._M_cur, __t_copy); } -# ifdef __STL_USE_EXCEPTIONS - catch(...) { - start.set_node(start.node + 1); - start.cur = start.first; - deallocate_node(*(start.node - 1)); - throw; + __STL_UNWIND((++_M_start, _M_deallocate_node(*(_M_start._M_node - 1)))); +} + +// Called only if _M_start._M_cur == _M_start._M_first. +template <class _Tp, class _Alloc, size_t __bufsize> +void +deque<_Tp,_Alloc,__bufsize>::_M_push_front_aux() +{ + _M_reserve_map_at_front(); + *(_M_start._M_node - 1) = _M_allocate_node(); + __STL_TRY { + _M_start._M_set_node(_M_start._M_node - 1); + _M_start._M_cur = _M_start._M_last - 1; + construct(_M_start._M_cur); } -# endif /* __STL_USE_EXCEPTIONS */ + __STL_UNWIND((++_M_start, _M_deallocate_node(*(_M_start._M_node - 1)))); } -// Called only if finish.cur == finish.first. -template <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 _M_finish._M_cur == _M_finish._M_first. +template <class _Tp, class _Alloc, size_t __bufsize> +void +deque<_Tp,_Alloc,__bufsize>::_M_pop_back_aux() +{ + _M_deallocate_node(_M_finish._M_first); + _M_finish._M_set_node(_M_finish._M_node - 1); + _M_finish._M_cur = _M_finish._M_last - 1; + destroy(_M_finish._M_cur); } -// Called only if start.cur == start.last - 1. Note that if the deque -// has at least one element (a necessary precondition for this member -// function), and if start.cur == start.last, then the deque must have -// at least two nodes. -template <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; +// Called only if _M_start._M_cur == _M_start._M_last - 1. Note that +// if the deque has at least one element (a precondition for this member +// function), and if _M_start._M_cur == _M_start._M_last, then the deque +// must have at least two nodes. +template <class _Tp, class _Alloc, size_t __bufsize> +void +deque<_Tp,_Alloc,__bufsize>::_M_pop_front_aux() +{ + destroy(_M_start._M_cur); + _M_deallocate_node(_M_start._M_first); + _M_start._M_set_node(_M_start._M_node + 1); + _M_start._M_cur = _M_start._M_first; } #ifdef __STL_MEMBER_TEMPLATES -template <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 _Tp, class _Alloc, size_t __bufsize> +template <class _InputIterator> +void +deque<_Tp,_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); +template <class _Tp, class _Alloc, size_t __bufsize> +template <class _ForwardIterator> +void +deque<_Tp,_Alloc,__bufsize>::insert(iterator __pos, + _ForwardIterator __first, + _ForwardIterator __last, + forward_iterator_tag) { + size_type __n = 0; + distance(__first, __last, __n); + if (__pos._M_cur == _M_start._M_cur) { + iterator __new_start = _M_reserve_elements_at_front(__n); __STL_TRY { - uninitialized_copy(first, last, new_start); - start = new_start; + uninitialized_copy(__first, __last, __new_start); + _M_start = __new_start; } - __STL_UNWIND(destroy_nodes_at_front(new_start)); + __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node)); } - else if (pos.cur == finish.cur) { - iterator new_finish = reserve_elements_at_back(n); + else if (__pos._M_cur == _M_finish._M_cur) { + iterator __new_finish = _M_reserve_elements_at_back(__n); __STL_TRY { - uninitialized_copy(first, last, finish); - finish = new_finish; + uninitialized_copy(__first, __last, _M_finish); + _M_finish = __new_finish; } - __STL_UNWIND(destroy_nodes_at_back(new_finish)); + __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, + __new_finish._M_node + 1)); } else - insert_aux(pos, first, last, n); + _M_insert_aux(__pos, __first, __last, __n); } #endif /* __STL_MEMBER_TEMPLATES */ -template <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) { +template <class _Tp, class _Alloc, size_t __bufsize> +typename deque<_Tp, _Alloc, __bufsize>::iterator +deque<_Tp,_Alloc,__bufsize>::_M_insert_aux(iterator __pos, + const value_type& __x) +{ + difference_type __index = __pos - _M_start; + value_type __x_copy = __x; + if (__index < size() / 2) { + push_front(front()); + iterator __front1 = _M_start; + ++__front1; + iterator __front2 = __front1; + ++__front2; + __pos = _M_start + __index; + iterator __pos1 = __pos; + ++__pos1; + copy(__front2, __pos1, __front1); + } + else { + push_back(back()); + iterator __back1 = _M_finish; + --__back1; + iterator __back2 = __back1; + --__back2; + __pos = _M_start + __index; + copy_backward(__pos, __back2, __back1); + } + *__pos = __x_copy; + return __pos; +} + +template <class _Tp, class _Alloc, size_t __bufsize> +typename deque<_Tp,_Alloc,__bufsize>::iterator +deque<_Tp,_Alloc,__bufsize>::_M_insert_aux(iterator __pos) +{ + difference_type __index = __pos - _M_start; + if (__index < size() / 2) { push_front(front()); - iterator front1 = start; - ++front1; - iterator front2 = front1; - ++front2; - pos = start + index; - iterator pos1 = pos; - ++pos1; - copy(front2, pos1, front1); + iterator __front1 = _M_start; + ++__front1; + iterator __front2 = __front1; + ++__front2; + __pos = _M_start + __index; + iterator __pos1 = __pos; + ++__pos1; + copy(__front2, __pos1, __front1); } else { push_back(back()); - iterator back1 = finish; - --back1; - iterator back2 = back1; - --back2; - pos = start + index; - copy_backward(pos, back2, back1); - } - *pos = x_copy; - return pos; + iterator __back1 = _M_finish; + --__back1; + iterator __back2 = __back1; + --__back2; + __pos = _M_start + __index; + copy_backward(__pos, __back2, __back1); + } + *__pos = value_type(); + return __pos; } -template <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; +template <class _Tp, class _Alloc, size_t __bufsize> +void +deque<_Tp,_Alloc,__bufsize>::_M_insert_aux(iterator __pos, + size_type __n, + const value_type& __x) +{ + const difference_type __elems_before = __pos - _M_start; + size_type __length = size(); + value_type __x_copy = __x; + if (__elems_before < __length / 2) { + iterator __new_start = _M_reserve_elements_at_front(__n); + iterator __old_start = _M_start; + __pos = _M_start + __elems_before; __STL_TRY { - if (elems_before >= difference_type(n)) { - iterator start_n = start + difference_type(n); - uninitialized_copy(start, start_n, new_start); - start = new_start; - copy(start_n, pos, old_start); - fill(pos - difference_type(n), pos, x_copy); + if (__elems_before >= difference_type(__n)) { + iterator __start_n = _M_start + difference_type(__n); + uninitialized_copy(_M_start, __start_n, __new_start); + _M_start = __new_start; + copy(__start_n, __pos, __old_start); + fill(__pos - difference_type(__n), __pos, __x_copy); } else { - __uninitialized_copy_fill(start, pos, new_start, start, x_copy); - start = new_start; - fill(old_start, pos, x_copy); + __uninitialized_copy_fill(_M_start, __pos, __new_start, + _M_start, __x_copy); + _M_start = __new_start; + fill(__old_start, __pos, __x_copy); } } - __STL_UNWIND(destroy_nodes_at_front(new_start)); + __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node)); } else { - iterator new_finish = reserve_elements_at_back(n); - iterator old_finish = finish; - const difference_type elems_after = difference_type(length) - elems_before; - pos = finish - elems_after; + iterator __new_finish = _M_reserve_elements_at_back(__n); + iterator __old_finish = _M_finish; + const difference_type __elems_after = + difference_type(__length) - __elems_before; + __pos = _M_finish - __elems_after; __STL_TRY { - if (elems_after > difference_type(n)) { - iterator finish_n = finish - difference_type(n); - uninitialized_copy(finish_n, finish, finish); - finish = new_finish; - copy_backward(pos, finish_n, old_finish); - fill(pos, pos + difference_type(n), x_copy); + if (__elems_after > difference_type(__n)) { + iterator __finish_n = _M_finish - difference_type(__n); + uninitialized_copy(__finish_n, _M_finish, _M_finish); + _M_finish = __new_finish; + copy_backward(__pos, __finish_n, __old_finish); + fill(__pos, __pos + difference_type(__n), __x_copy); } else { - __uninitialized_fill_copy(finish, pos + difference_type(n), - x_copy, - pos, finish); - finish = new_finish; - fill(pos, old_finish, x_copy); + __uninitialized_fill_copy(_M_finish, __pos + difference_type(__n), + __x_copy, __pos, _M_finish); + _M_finish = __new_finish; + fill(__pos, __old_finish, __x_copy); } } - __STL_UNWIND(destroy_nodes_at_back(new_finish)); + __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, + __new_finish._M_node + 1)); } } #ifdef __STL_MEMBER_TEMPLATES -template <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) +template <class _Tp, class _Alloc, size_t __bufsize> +template <class _ForwardIterator> +void +deque<_Tp,_Alloc,__bufsize>::_M_insert_aux(iterator __pos, + _ForwardIterator __first, + _ForwardIterator __last, + size_type __n) { - const difference_type elems_before = pos - start; - size_type length = size(); - if (elems_before < length / 2) { - iterator new_start = reserve_elements_at_front(n); - iterator old_start = start; - pos = start + elems_before; + const difference_type __elemsbefore = __pos - _M_start; + size_type __length = size(); + if (__elemsbefore < __length / 2) { + iterator __new_start = _M_reserve_elements_at_front(__n); + iterator __old_start = _M_start; + __pos = _M_start + __elemsbefore; __STL_TRY { - if (elems_before >= difference_type(n)) { - iterator start_n = start + difference_type(n); - uninitialized_copy(start, start_n, new_start); - start = new_start; - copy(start_n, pos, old_start); - copy(first, last, pos - difference_type(n)); + if (__elemsbefore >= difference_type(__n)) { + iterator __start_n = _M_start + difference_type(__n); + uninitialized_copy(_M_start, __start_n, __new_start); + _M_start = __new_start; + copy(__start_n, __pos, __old_start); + copy(__first, __last, __pos - difference_type(__n)); } else { - ForwardIterator mid = first; - advance(mid, difference_type(n) - elems_before); - __uninitialized_copy_copy(start, pos, first, mid, new_start); - start = new_start; - copy(mid, last, old_start); + _ForwardIterator __mid = __first; + advance(__mid, difference_type(__n) - __elemsbefore); + __uninitialized_copy_copy(_M_start, __pos, __first, __mid, + __new_start); + _M_start = __new_start; + copy(__mid, __last, __old_start); } } - __STL_UNWIND(destroy_nodes_at_front(new_start)); + __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node)); } else { - iterator new_finish = reserve_elements_at_back(n); - iterator old_finish = finish; - const difference_type elems_after = difference_type(length) - elems_before; - pos = finish - elems_after; + iterator __new_finish = _M_reserve_elements_at_back(__n); + iterator __old_finish = _M_finish; + const difference_type __elemsafter = + difference_type(__length) - __elemsbefore; + __pos = _M_finish - __elemsafter; __STL_TRY { - if (elems_after > difference_type(n)) { - iterator finish_n = finish - difference_type(n); - uninitialized_copy(finish_n, finish, finish); - finish = new_finish; - copy_backward(pos, finish_n, old_finish); - copy(first, last, pos); + if (__elemsafter > difference_type(__n)) { + iterator __finish_n = _M_finish - difference_type(__n); + uninitialized_copy(__finish_n, _M_finish, _M_finish); + _M_finish = __new_finish; + copy_backward(__pos, __finish_n, __old_finish); + copy(__first, __last, __pos); } else { - ForwardIterator mid = first; - advance(mid, elems_after); - __uninitialized_copy_copy(mid, last, pos, finish, finish); - finish = new_finish; - copy(first, mid, pos); + _ForwardIterator __mid = __first; + advance(__mid, __elemsafter); + __uninitialized_copy_copy(__mid, __last, __pos, _M_finish, _M_finish); + _M_finish = __new_finish; + copy(__first, __mid, __pos); } } - __STL_UNWIND(destroy_nodes_at_back(new_finish)); + __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, + __new_finish._M_node + 1)); } } #else /* __STL_MEMBER_TEMPLATES */ -template <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) +template <class _Tp, class _Alloc, size_t __bufsize> +void +deque<_Tp,_Alloc,__bufsize>::_M_insert_aux(iterator __pos, + const value_type* __first, + const value_type* __last, + size_type __n) { - const difference_type elems_before = pos - start; - size_type length = size(); - if (elems_before < length / 2) { - iterator new_start = reserve_elements_at_front(n); - iterator old_start = start; - pos = start + elems_before; + const difference_type __elemsbefore = __pos - _M_start; + size_type __length = size(); + if (__elemsbefore < __length / 2) { + iterator __new_start = _M_reserve_elements_at_front(__n); + iterator __old_start = _M_start; + __pos = _M_start + __elemsbefore; __STL_TRY { - if (elems_before >= difference_type(n)) { - iterator start_n = start + difference_type(n); - uninitialized_copy(start, start_n, new_start); - start = new_start; - copy(start_n, pos, old_start); - copy(first, last, pos - difference_type(n)); + if (__elemsbefore >= difference_type(__n)) { + iterator __start_n = _M_start + difference_type(__n); + uninitialized_copy(_M_start, __start_n, __new_start); + _M_start = __new_start; + copy(__start_n, __pos, __old_start); + copy(__first, __last, __pos - difference_type(__n)); } else { - const value_type* mid = first + (difference_type(n) - elems_before); - __uninitialized_copy_copy(start, pos, first, mid, new_start); - start = new_start; - copy(mid, last, old_start); + const value_type* __mid = + __first + (difference_type(__n) - __elemsbefore); + __uninitialized_copy_copy(_M_start, __pos, __first, __mid, + __new_start); + _M_start = __new_start; + copy(__mid, __last, __old_start); } } - __STL_UNWIND(destroy_nodes_at_front(new_start)); + __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node)); } else { - iterator new_finish = reserve_elements_at_back(n); - iterator old_finish = finish; - const difference_type elems_after = difference_type(length) - elems_before; - pos = finish - elems_after; + iterator __new_finish = _M_reserve_elements_at_back(__n); + iterator __old_finish = _M_finish; + const difference_type __elemsafter = + difference_type(__length) - __elemsbefore; + __pos = _M_finish - __elemsafter; __STL_TRY { - if (elems_after > difference_type(n)) { - iterator finish_n = finish - difference_type(n); - uninitialized_copy(finish_n, finish, finish); - finish = new_finish; - copy_backward(pos, finish_n, old_finish); - copy(first, last, pos); + if (__elemsafter > difference_type(__n)) { + iterator __finish_n = _M_finish - difference_type(__n); + uninitialized_copy(__finish_n, _M_finish, _M_finish); + _M_finish = __new_finish; + copy_backward(__pos, __finish_n, __old_finish); + copy(__first, __last, __pos); } else { - const value_type* mid = first + elems_after; - __uninitialized_copy_copy(mid, last, pos, finish, finish); - finish = new_finish; - copy(first, mid, pos); + const value_type* __mid = __first + __elemsafter; + __uninitialized_copy_copy(__mid, __last, __pos, _M_finish, _M_finish); + _M_finish = __new_finish; + copy(__first, __mid, __pos); } } - __STL_UNWIND(destroy_nodes_at_back(new_finish)); + __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, + __new_finish._M_node + 1)); } } -template <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) +template <class _Tp, class _Alloc, size_t __bufsize> +void +deque<_Tp,_Alloc,__bufsize>::_M_insert_aux(iterator __pos, + const_iterator __first, + const_iterator __last, + size_type __n) { - const difference_type elems_before = pos - start; - size_type length = size(); - if (elems_before < length / 2) { - iterator new_start = reserve_elements_at_front(n); - iterator old_start = start; - pos = start + elems_before; + const difference_type __elemsbefore = __pos - _M_start; + size_type __length = size(); + if (__elemsbefore < __length / 2) { + iterator __new_start = _M_reserve_elements_at_front(__n); + iterator __old_start = _M_start; + __pos = _M_start + __elemsbefore; __STL_TRY { - if (elems_before >= n) { - iterator start_n = start + n; - uninitialized_copy(start, start_n, new_start); - start = new_start; - copy(start_n, pos, old_start); - copy(first, last, pos - difference_type(n)); + if (__elemsbefore >= __n) { + iterator __start_n = _M_start + __n; + uninitialized_copy(_M_start, __start_n, __new_start); + _M_start = __new_start; + copy(__start_n, __pos, __old_start); + copy(__first, __last, __pos - difference_type(__n)); } else { - const_iterator mid = first + (n - elems_before); - __uninitialized_copy_copy(start, pos, first, mid, new_start); - start = new_start; - copy(mid, last, old_start); + const_iterator __mid = __first + (__n - __elemsbefore); + __uninitialized_copy_copy(_M_start, __pos, __first, __mid, + __new_start); + _M_start = __new_start; + copy(__mid, __last, __old_start); } } - __STL_UNWIND(destroy_nodes_at_front(new_start)); + __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node)); } else { - iterator new_finish = reserve_elements_at_back(n); - iterator old_finish = finish; - const difference_type elems_after = length - elems_before; - pos = finish - elems_after; + iterator __new_finish = _M_reserve_elements_at_back(__n); + iterator __old_finish = _M_finish; + const difference_type __elemsafter = __length - __elemsbefore; + __pos = _M_finish - __elemsafter; __STL_TRY { - if (elems_after > n) { - iterator finish_n = finish - difference_type(n); - uninitialized_copy(finish_n, finish, finish); - finish = new_finish; - copy_backward(pos, finish_n, old_finish); - copy(first, last, pos); + if (__elemsafter > __n) { + iterator __finish_n = _M_finish - difference_type(__n); + uninitialized_copy(__finish_n, _M_finish, _M_finish); + _M_finish = __new_finish; + copy_backward(__pos, __finish_n, __old_finish); + copy(__first, __last, __pos); } else { - const_iterator mid = first + elems_after; - __uninitialized_copy_copy(mid, last, pos, finish, finish); - finish = new_finish; - copy(first, mid, pos); + const_iterator __mid = __first + __elemsafter; + __uninitialized_copy_copy(__mid, __last, __pos, _M_finish, _M_finish); + _M_finish = __new_finish; + copy(__first, __mid, __pos); } } - __STL_UNWIND(destroy_nodes_at_back(new_finish)); + __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, + __new_finish._M_node + 1)); } } #endif /* __STL_MEMBER_TEMPLATES */ -template <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; +template <class _Tp, class _Alloc, size_t __bufsize> +void +deque<_Tp,_Alloc,__bufsize>::_M_new_elements_at_front(size_type __new_elems) +{ + size_type __new_nodes + = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size(); + _M_reserve_map_at_front(__new_nodes); + size_type __i; __STL_TRY { - for (i = 1; i <= new_nodes; ++i) - *(start.node - i) = allocate_node(); + for (__i = 1; __i <= __new_nodes; ++__i) + *(_M_start._M_node - __i) = _M_allocate_node(); } # ifdef __STL_USE_EXCEPTIONS catch(...) { - for (size_type j = 1; j < i; ++j) - deallocate_node(*(start.node - j)); + for (size_type __j = 1; __j < __i; ++__j) + _M_deallocate_node(*(_M_start._M_node - __j)); throw; } # endif /* __STL_USE_EXCEPTIONS */ } -template <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; +template <class _Tp, class _Alloc, size_t __bufsize> +void +deque<_Tp,_Alloc,__bufsize>::_M_new_elements_at_back(size_type __new_elems) +{ + size_type __new_nodes + = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size(); + _M_reserve_map_at_back(__new_nodes); + size_type __i; __STL_TRY { - for (i = 1; i <= new_nodes; ++i) - *(finish.node + i) = allocate_node(); + for (__i = 1; __i <= __new_nodes; ++__i) + *(_M_finish._M_node + __i) = _M_allocate_node(); } # ifdef __STL_USE_EXCEPTIONS catch(...) { - for (size_type j = 1; j < i; ++j) - deallocate_node(*(finish.node + j)); + for (size_type __j = 1; __j < __i; ++__j) + _M_deallocate_node(*(_M_finish._M_node + __j)); throw; } # endif /* __STL_USE_EXCEPTIONS */ } -template <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); +template <class _Tp, class _Alloc, size_t __bufsize> +void +deque<_Tp,_Alloc,__bufsize>::_M_reallocate_map(size_type __nodes_to_add, + bool __add_at_front) +{ + size_type __old_num_nodes = _M_finish._M_node - _M_start._M_node + 1; + size_type __new_num_nodes = __old_num_nodes + __nodes_to_add; + + _Map_pointer __new_nstart; + if (_M_map_size > 2 * __new_num_nodes) { + __new_nstart = _M_map + (_M_map_size - __new_num_nodes) / 2 + + (__add_at_front ? __nodes_to_add : 0); + if (__new_nstart < _M_start._M_node) + copy(_M_start._M_node, _M_finish._M_node + 1, __new_nstart); else - copy_backward(start.node, finish.node + 1, new_nstart + old_num_nodes); + copy_backward(_M_start._M_node, _M_finish._M_node + 1, + __new_nstart + __old_num_nodes); } else { - size_type new_map_size = map_size + max(map_size, nodes_to_add) + 2; + size_type __new_map_size = + _M_map_size + max(_M_map_size, __nodes_to_add) + 2; - map_pointer new_map = map_allocator::allocate(new_map_size); - new_nstart = new_map + (new_map_size - new_num_nodes) / 2 - + (add_at_front ? nodes_to_add : 0); - copy(start.node, finish.node + 1, new_nstart); - map_allocator::deallocate(map, map_size); + _Map_pointer __new_map = _M_allocate_map(__new_map_size); + __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2 + + (__add_at_front ? __nodes_to_add : 0); + copy(_M_start._M_node, _M_finish._M_node + 1, __new_nstart); + _M_deallocate_map(_M_map, _M_map_size); - map = new_map; - map_size = new_map_size; + _M_map = __new_map; + _M_map_size = __new_map_size; } - start.set_node(new_nstart); - finish.set_node(new_nstart + old_num_nodes - 1); + _M_start._M_set_node(__new_nstart); + _M_finish._M_set_node(__new_nstart + __old_num_nodes - 1); } @@ -1298,16 +1654,20 @@ void deque<T, Alloc, BufSize>::reallocate_map(size_type nodes_to_add, #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 _Tp, class _Alloc, size_t __bufsiz> +bool operator==(const deque<_Tp, _Alloc, __bufsiz>& __x, + const deque<_Tp, _Alloc, __bufsiz>& __y) +{ + return __x.size() == __y.size() && + equal(__x.begin(), __x.end(), __y.begin()); } -template <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()); +template <class _Tp, class _Alloc, size_t __bufsiz> +bool operator<(const deque<_Tp, _Alloc, __bufsiz>& __x, + const deque<_Tp, _Alloc, __bufsiz>& __y) +{ + return lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); } #endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */ @@ -1315,15 +1675,18 @@ bool operator<(const deque<T, Alloc, BufSiz>& x, #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); +template <class _Tp, class _Alloc, size_t __bufsiz> +inline void +swap(deque<_Tp,_Alloc,__bufsiz>& __x, deque<_Tp,_Alloc,__bufsiz>& __y) +{ + __x.swap(__y); } #endif #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 +#pragma reset woff 1375 #endif __STL_END_NAMESPACE diff --git a/contrib/libstdc++/stl/stl_function.h b/contrib/libstdc++/stl/stl_function.h index c0d785d..a5a8486 100644 --- a/contrib/libstdc++/stl/stl_function.h +++ b/contrib/libstdc++/stl/stl_function.h @@ -12,7 +12,7 @@ * purpose. It is provided "as is" without express or implied warranty. * * - * Copyright (c) 1996 + * Copyright (c) 1996-1998 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software @@ -33,372 +33,430 @@ __STL_BEGIN_NAMESPACE -template <class Arg, class Result> +template <class _Arg, class _Result> struct unary_function { - typedef Arg argument_type; - typedef Result result_type; + typedef _Arg argument_type; + typedef _Result result_type; }; -template <class Arg1, class Arg2, class Result> +template <class _Arg1, class _Arg2, class _Result> struct binary_function { - typedef Arg1 first_argument_type; - typedef Arg2 second_argument_type; - typedef Result result_type; + typedef _Arg1 first_argument_type; + typedef _Arg2 second_argument_type; + typedef _Result result_type; }; -template <class T> -struct plus : public binary_function<T, T, T> { - T operator()(const T& x, const T& y) const { return x + y; } +template <class _Tp> +struct plus : public binary_function<_Tp,_Tp,_Tp> { + _Tp operator()(const _Tp& __x, const _Tp& __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 _Tp> +struct minus : public binary_function<_Tp,_Tp,_Tp> { + _Tp operator()(const _Tp& __x, const _Tp& __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 _Tp> +struct multiplies : public binary_function<_Tp,_Tp,_Tp> { + _Tp operator()(const _Tp& __x, const _Tp& __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 _Tp> +struct divides : public binary_function<_Tp,_Tp,_Tp> { + _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x / __y; } }; -template <class T> inline T identity_element(plus<T>) { return T(0); } +// identity_element (not part of the C++ standard). -template <class T> inline T identity_element(multiplies<T>) { return T(1); } +template <class _Tp> inline _Tp identity_element(plus<_Tp>) { + return _Tp(0); +} +template <class _Tp> inline _Tp identity_element(multiplies<_Tp>) { + return _Tp(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 _Tp> +struct modulus : public binary_function<_Tp,_Tp,_Tp> +{ + _Tp operator()(const _Tp& __x, const _Tp& __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 _Tp> +struct negate : public unary_function<_Tp,_Tp> +{ + _Tp operator()(const _Tp& __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 _Tp> +struct equal_to : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __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 _Tp> +struct not_equal_to : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __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 _Tp> +struct greater : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __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 _Tp> +struct less : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __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 _Tp> +struct greater_equal : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __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 _Tp> +struct less_equal : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __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 _Tp> +struct logical_and : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __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 _Tp> +struct logical_or : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __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 _Tp> +struct logical_not : public unary_function<_Tp,bool> +{ + bool operator()(const _Tp& __x) const { return !__x; } }; -template <class Predicate> +template <class _Predicate> class unary_negate - : public unary_function<typename Predicate::argument_type, bool> { + : public unary_function<typename _Predicate::argument_type, bool> { protected: - Predicate pred; + _Predicate _M_pred; public: - explicit unary_negate(const Predicate& x) : pred(x) {} - bool operator()(const typename Predicate::argument_type& x) const { - return !pred(x); + explicit unary_negate(const _Predicate& __x) : _M_pred(__x) {} + bool operator()(const typename _Predicate::argument_type& __x) const { + return !_M_pred(__x); } }; -template <class Predicate> -inline unary_negate<Predicate> not1(const Predicate& pred) { - return unary_negate<Predicate>(pred); +template <class _Predicate> +inline unary_negate<_Predicate> +not1(const _Predicate& __pred) +{ + return unary_negate<_Predicate>(__pred); } -template <class Predicate> +template <class _Predicate> class binary_negate - : public binary_function<typename Predicate::first_argument_type, - typename Predicate::second_argument_type, + : public binary_function<typename _Predicate::first_argument_type, + typename _Predicate::second_argument_type, bool> { protected: - Predicate pred; + _Predicate _M_pred; public: - explicit binary_negate(const Predicate& x) : pred(x) {} - bool operator()(const typename Predicate::first_argument_type& x, - const typename Predicate::second_argument_type& y) const { - return !pred(x, y); + explicit binary_negate(const _Predicate& __x) : _M_pred(__x) {} + bool operator()(const typename _Predicate::first_argument_type& __x, + const typename _Predicate::second_argument_type& __y) const + { + return !_M_pred(__x, __y); } }; -template <class Predicate> -inline binary_negate<Predicate> not2(const Predicate& pred) { - return binary_negate<Predicate>(pred); +template <class _Predicate> +inline binary_negate<_Predicate> +not2(const _Predicate& __pred) +{ + return binary_negate<_Predicate>(__pred); } -template <class Operation> +template <class _Operation> class binder1st - : public unary_function<typename Operation::second_argument_type, - typename Operation::result_type> { + : public unary_function<typename _Operation::second_argument_type, + typename _Operation::result_type> { protected: - Operation op; - typename Operation::first_argument_type value; + _Operation op; + typename _Operation::first_argument_type value; public: - binder1st(const Operation& x, - const typename Operation::first_argument_type& y) - : op(x), value(y) {} - typename Operation::result_type - operator()(const typename Operation::second_argument_type& x) const { - return op(value, x); + binder1st(const _Operation& __x, + const typename _Operation::first_argument_type& __y) + : op(__x), value(__y) {} + typename _Operation::result_type + operator()(const typename _Operation::second_argument_type& __x) const { + return op(value, __x); } }; -template <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 _Tp> +inline binder1st<_Operation> +bind1st(const _Operation& __oper, const _Tp& __x) +{ + typedef typename _Operation::first_argument_type _Arg1_type; + return binder1st<_Operation>(__oper, _Arg1_type(__x)); } -template <class Operation> +template <class _Operation> class binder2nd - : public unary_function<typename Operation::first_argument_type, - typename Operation::result_type> { + : public unary_function<typename _Operation::first_argument_type, + typename _Operation::result_type> { protected: - Operation op; - typename Operation::second_argument_type value; + _Operation op; + typename _Operation::second_argument_type value; public: - binder2nd(const Operation& x, - const typename Operation::second_argument_type& y) - : op(x), value(y) {} - typename Operation::result_type - operator()(const typename Operation::first_argument_type& x) const { - return op(x, value); + binder2nd(const _Operation& __x, + const typename _Operation::second_argument_type& __y) + : op(__x), value(__y) {} + typename _Operation::result_type + operator()(const typename _Operation::first_argument_type& __x) const { + return op(__x, value); } }; -template <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 _Operation, class _Tp> +inline binder2nd<_Operation> +bind2nd(const _Operation& __oper, const _Tp& __x) +{ + typedef typename _Operation::second_argument_type _Arg2_type; + return binder2nd<_Operation>(__oper, _Arg2_type(__x)); } -template <class Operation1, class Operation2> -class unary_compose : public unary_function<typename Operation2::argument_type, - typename Operation1::result_type> { +// unary_compose and binary_compose (extensions, not part of the standard). + +template <class _Operation1, class _Operation2> +class unary_compose + : public unary_function<typename _Operation2::argument_type, + typename _Operation1::result_type> +{ protected: - Operation1 op1; - Operation2 op2; + _Operation1 __op1; + _Operation2 __op2; public: - unary_compose(const Operation1& x, const Operation2& y) : op1(x), op2(y) {} - typename Operation1::result_type - operator()(const typename Operation2::argument_type& x) const { - return op1(op2(x)); + unary_compose(const _Operation1& __x, const _Operation2& __y) + : __op1(__x), __op2(__y) {} + typename _Operation1::result_type + operator()(const typename _Operation2::argument_type& __x) const { + return __op1(__op2(__x)); } }; -template <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> +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> +template <class _Operation1, class _Operation2, class _Operation3> class binary_compose - : public unary_function<typename Operation2::argument_type, - typename Operation1::result_type> { + : public unary_function<typename _Operation2::argument_type, + typename _Operation1::result_type> { protected: - Operation1 op1; - Operation2 op2; - Operation3 op3; + _Operation1 _M_op1; + _Operation2 _M_op2; + _Operation3 _M_op3; public: - binary_compose(const Operation1& x, const Operation2& y, - const Operation3& z) : op1(x), op2(y), op3(z) { } - typename Operation1::result_type - operator()(const typename Operation2::argument_type& x) const { - return op1(op2(x), op3(x)); + binary_compose(const _Operation1& __x, const _Operation2& __y, + const _Operation3& __z) + : _M_op1(__x), _M_op2(__y), _M_op3(__z) { } + typename _Operation1::result_type + operator()(const typename _Operation2::argument_type& __x) const { + return _M_op1(_M_op2(__x), _M_op3(__x)); } }; -template <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 _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> { +template <class _Arg, class _Result> +class pointer_to_unary_function : public unary_function<_Arg, _Result> { protected: - Result (*ptr)(Arg); + _Result (*_M_ptr)(_Arg); public: pointer_to_unary_function() {} - explicit pointer_to_unary_function(Result (*x)(Arg)) : ptr(x) {} - Result operator()(Arg x) const { return ptr(x); } + explicit pointer_to_unary_function(_Result (*__x)(_Arg)) : _M_ptr(__x) {} + _Result operator()(_Arg __x) const { return _M_ptr(__x); } }; -template <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 _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> { +template <class _Arg1, class _Arg2, class _Result> +class pointer_to_binary_function : + public binary_function<_Arg1,_Arg2,_Result> { protected: - Result (*ptr)(Arg1, Arg2); + _Result (*_M_ptr)(_Arg1, _Arg2); public: pointer_to_binary_function() {} - explicit pointer_to_binary_function(Result (*x)(Arg1, Arg2)) : ptr(x) {} - Result operator()(Arg1 x, Arg2 y) const { return ptr(x, y); } + explicit pointer_to_binary_function(_Result (*__x)(_Arg1, _Arg2)) + : _M_ptr(__x) {} + _Result operator()(_Arg1 __x, _Arg2 __y) const { + return _M_ptr(__x, __y); + } }; -template <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 _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; } +// identity is an extensions: it is not part of the standard. +template <class _Tp> +struct _Identity : public unary_function<_Tp,_Tp> { + const _Tp& operator()(const _Tp& __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 _Tp> struct identity : public _Identity<_Tp> {}; + +// select1st and select2nd are extensions: they are not part of the standard. +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 _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 _Pair> struct select1st : public _Select1st<_Pair> {}; +template <class _Pair> struct select2nd : public _Select2nd<_Pair> {}; + +// project1st and project2nd are extensions: they are not part of the standard +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 _Arg1, class _Arg2> +struct _Project2nd : public binary_function<_Arg1, _Arg2, _Arg2> { + _Arg2 operator()(const _Arg1&, const _Arg2& __y) const { return __y; } }; -template <class Result> +template <class _Arg1, class _Arg2> +struct project1st : public _Project1st<_Arg1, _Arg2> {}; + +template <class _Arg1, class _Arg2> +struct project2nd : public _Project2nd<_Arg1, _Arg2> {}; + +// constant_void_fun, constant_unary_fun, and constant_binary_fun are +// extensions: they are not part of the standard. (The same, of course, +// is true of the helper functions constant0, constant1, and constant2.) +template <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; } + 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> +template <class _Result, class _Argument = _Result> #else -template <class Result, class Argument> +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; } +struct constant_unary_fun : public unary_function<_Argument, _Result> { + _Result _M_val; + constant_unary_fun(const _Result& __v) : _M_val(__v) {} + const _Result& operator()(const _Argument&) const { return _M_val; } }; #ifndef __STL_LIMITED_DEFAULT_TEMPLATES -template <class Result, class Arg1 = Result, class Arg2 = Arg1> +template <class _Result, class _Arg1 = _Result, class _Arg2 = _Arg1> #else -template <class Result, class Arg1, class Arg2> +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; +struct constant_binary_fun : public binary_function<_Arg1, _Arg2, _Result> { + _Result _M_val; + constant_binary_fun(const _Result& __v) : _M_val(__v) {} + const _Result& operator()(const _Arg1&, const _Arg2&) const { + return _M_val; } }; -template <class Result> -inline constant_void_fun<Result> constant0(const Result& val) +template <class _Result> +inline constant_void_fun<_Result> constant0(const _Result& __val) { - return constant_void_fun<Result>(val); + return constant_void_fun<_Result>(__val); } -template <class Result> -inline constant_unary_fun<Result,Result> constant1(const Result& val) +template <class _Result> +inline constant_unary_fun<_Result,_Result> constant1(const _Result& __val) { - return constant_unary_fun<Result,Result>(val); + return constant_unary_fun<_Result,_Result>(__val); } -template <class Result> -inline constant_binary_fun<Result,Result,Result> constant2(const Result& val) +template <class _Result> +inline constant_binary_fun<_Result,_Result,_Result> +constant2(const _Result& __val) { - return constant_binary_fun<Result,Result,Result>(val); + return constant_binary_fun<_Result,_Result,_Result>(__val); } +// subtractive_rng is an extension: it is not part of the standard. // Note: this code assumes that int is 32 bits. class subtractive_rng : public unary_function<unsigned int, unsigned int> { private: - unsigned int table[55]; - size_t index1; - size_t index2; + unsigned int _M_table[55]; + size_t _M_index1; + size_t _M_index2; public: - unsigned int operator()(unsigned int limit) { - index1 = (index1 + 1) % 55; - index2 = (index2 + 1) % 55; - table[index1] = table[index1] - table[index2]; - return table[index1] % limit; + unsigned int operator()(unsigned int __limit) { + _M_index1 = (_M_index1 + 1) % 55; + _M_index2 = (_M_index2 + 1) % 55; + _M_table[_M_index1] = _M_table[_M_index1] - _M_table[_M_index2]; + return _M_table[_M_index1] % __limit; } - void initialize(unsigned int seed) + void _M_initialize(unsigned int __seed) { - unsigned int k = 1; - table[54] = seed; - size_t i; - for (i = 0; i < 54; i++) { - size_t ii = (21 * (i + 1) % 55) - 1; - table[ii] = k; - k = seed - k; - seed = table[ii]; + unsigned int __k = 1; + _M_table[54] = __seed; + size_t __i; + for (__i = 0; __i < 54; __i++) { + size_t __ii = (21 * (__i + 1) % 55) - 1; + _M_table[__ii] = __k; + __k = __seed - __k; + __seed = _M_table[__ii]; } - for (int loop = 0; loop < 4; loop++) { - for (i = 0; i < 55; i++) - table[i] = table[i] - table[(1 + i + 30) % 55]; + for (int __loop = 0; __loop < 4; __loop++) { + for (__i = 0; __i < 55; __i++) + _M_table[__i] = _M_table[__i] - _M_table[(1 + __i + 30) % 55]; } - index1 = 0; - index2 = 31; + _M_index1 = 0; + _M_index2 = 31; } - subtractive_rng(unsigned int seed) { initialize(seed); } - subtractive_rng() { initialize(161803398u); } + subtractive_rng(unsigned int __seed) { _M_initialize(__seed); } + subtractive_rng() { _M_initialize(161803398u); } }; @@ -412,212 +470,226 @@ public: // non-void return type. // (4) Const vs non-const member function. -// Note that choice (4) is not present in the 8/97 draft C++ standard, -// which only allows these adaptors to be used with non-const functions. -// This is likely to be recified before the standard becomes final. -// Note also that choice (3) is nothing more than a workaround: according +// Note that choice (3) is nothing more than a workaround: according // to the draft, compilers should handle void and non-void the same way. // This feature is not yet widely implemented, though. You can only use // member functions returning void if your compiler supports partial // specialization. // All of this complexity is in the function objects themselves. You can -// ignore it by using the helper function mem_fun, mem_fun_ref, -// mem_fun1, and mem_fun1_ref, which create whichever type of adaptor -// is appropriate. +// ignore it by using the helper function mem_fun and mem_fun_ref, +// which create whichever type of adaptor is appropriate. +// (mem_fun1 and mem_fun1_ref are no longer part of the C++ standard, +// but they are provided for backward compatibility.) -template <class S, class T> -class mem_fun_t : public unary_function<T*, S> { +template <class _Ret, class _Tp> +class mem_fun_t : public unary_function<_Tp*,_Ret> { public: - explicit mem_fun_t(S (T::*pf)()) : f(pf) {} - S operator()(T* p) const { return (p->*f)(); } + explicit mem_fun_t(_Ret (_Tp::*__pf)()) : _M_f(__pf) {} + _Ret operator()(_Tp* __p) const { return (__p->*_M_f)(); } private: - S (T::*f)(); + _Ret (_Tp::*_M_f)(); }; -template <class S, class T> -class const_mem_fun_t : public unary_function<const T*, S> { +template <class _Ret, class _Tp> +class const_mem_fun_t : public unary_function<const _Tp*,_Ret> { public: - explicit const_mem_fun_t(S (T::*pf)() const) : f(pf) {} - S operator()(const T* p) const { return (p->*f)(); } + explicit const_mem_fun_t(_Ret (_Tp::*__pf)() const) : _M_f(__pf) {} + _Ret operator()(const _Tp* __p) const { return (__p->*_M_f)(); } private: - S (T::*f)() const; + _Ret (_Tp::*_M_f)() const; }; -template <class S, class T> -class mem_fun_ref_t : public unary_function<T, S> { +template <class _Ret, class _Tp> +class mem_fun_ref_t : public unary_function<_Tp,_Ret> { public: - explicit mem_fun_ref_t(S (T::*pf)()) : f(pf) {} - S operator()(T& r) const { return (r.*f)(); } + explicit mem_fun_ref_t(_Ret (_Tp::*__pf)()) : _M_f(__pf) {} + _Ret operator()(_Tp& __r) const { return (__r.*_M_f)(); } private: - S (T::*f)(); + _Ret (_Tp::*_M_f)(); }; -template <class S, class T> -class const_mem_fun_ref_t : public unary_function<T, S> { +template <class _Ret, class _Tp> +class const_mem_fun_ref_t : public unary_function<_Tp,_Ret> { public: - explicit const_mem_fun_ref_t(S (T::*pf)() const) : f(pf) {} - S operator()(const T& r) const { return (r.*f)(); } + explicit const_mem_fun_ref_t(_Ret (_Tp::*__pf)() const) : _M_f(__pf) {} + _Ret operator()(const _Tp& __r) const { return (__r.*_M_f)(); } private: - S (T::*f)() const; + _Ret (_Tp::*_M_f)() const; }; -template <class S, class T, class A> -class mem_fun1_t : public binary_function<T*, A, S> { +template <class _Ret, class _Tp, class _Arg> +class mem_fun1_t : public binary_function<_Tp*,_Arg,_Ret> { public: - explicit mem_fun1_t(S (T::*pf)(A)) : f(pf) {} - S operator()(T* p, A x) const { return (p->*f)(x); } + explicit mem_fun1_t(_Ret (_Tp::*__pf)(_Arg)) : _M_f(__pf) {} + _Ret operator()(_Tp* __p, _Arg __x) const { return (__p->*_M_f)(__x); } private: - S (T::*f)(A); + _Ret (_Tp::*_M_f)(_Arg); }; -template <class S, class T, class A> -class const_mem_fun1_t : public binary_function<const T*, A, S> { +template <class _Ret, class _Tp, class _Arg> +class const_mem_fun1_t : public binary_function<const _Tp*,_Arg,_Ret> { public: - explicit const_mem_fun1_t(S (T::*pf)(A) const) : f(pf) {} - S operator()(const T* p, A x) const { return (p->*f)(x); } + explicit const_mem_fun1_t(_Ret (_Tp::*__pf)(_Arg) const) : _M_f(__pf) {} + _Ret operator()(const _Tp* __p, _Arg __x) const + { return (__p->*_M_f)(__x); } private: - S (T::*f)(A) const; + _Ret (_Tp::*_M_f)(_Arg) const; }; -template <class S, class T, class A> -class mem_fun1_ref_t : public binary_function<T, A, S> { +template <class _Ret, class _Tp, class _Arg> +class mem_fun1_ref_t : public binary_function<_Tp,_Arg,_Ret> { public: - explicit mem_fun1_ref_t(S (T::*pf)(A)) : f(pf) {} - S operator()(T& r, A x) const { return (r.*f)(x); } + explicit mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg)) : _M_f(__pf) {} + _Ret operator()(_Tp& __r, _Arg __x) const { return (__r.*_M_f)(__x); } private: - S (T::*f)(A); + _Ret (_Tp::*_M_f)(_Arg); }; -template <class S, class T, class A> -class const_mem_fun1_ref_t : public binary_function<T, A, S> { +template <class _Ret, class _Tp, class _Arg> +class const_mem_fun1_ref_t : public binary_function<_Tp,_Arg,_Ret> { public: - explicit const_mem_fun1_ref_t(S (T::*pf)(A) const) : f(pf) {} - S operator()(const T& r, A x) const { return (r.*f)(x); } + explicit const_mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg) const) : _M_f(__pf) {} + _Ret operator()(const _Tp& __r, _Arg __x) const { return (__r.*_M_f)(__x); } private: - S (T::*f)(A) const; + _Ret (_Tp::*_M_f)(_Arg) const; }; #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION -template <class T> -class mem_fun_t<void, T> : public unary_function<T*, void> { +template <class _Tp> +class mem_fun_t<void, _Tp> : public unary_function<_Tp*,void> { public: - explicit mem_fun_t(void (T::*pf)()) : f(pf) {} - void operator()(T* p) const { (p->*f)(); } + explicit mem_fun_t(void (_Tp::*__pf)()) : _M_f(__pf) {} + void operator()(_Tp* __p) const { (__p->*_M_f)(); } private: - void (T::*f)(); + void (_Tp::*_M_f)(); }; -template <class T> -class const_mem_fun_t<void, T> : public unary_function<const T*, void> { +template <class _Tp> +class const_mem_fun_t<void, _Tp> : public unary_function<const _Tp*,void> { public: - explicit const_mem_fun_t(void (T::*pf)() const) : f(pf) {} - void operator()(const T* p) const { (p->*f)(); } + explicit const_mem_fun_t(void (_Tp::*__pf)() const) : _M_f(__pf) {} + void operator()(const _Tp* __p) const { (__p->*_M_f)(); } private: - void (T::*f)() const; + void (_Tp::*_M_f)() const; }; -template <class T> -class mem_fun_ref_t<void, T> : public unary_function<T, void> { +template <class _Tp> +class mem_fun_ref_t<void, _Tp> : public unary_function<_Tp,void> { public: - explicit mem_fun_ref_t(void (T::*pf)()) : f(pf) {} - void operator()(T& r) const { (r.*f)(); } + explicit mem_fun_ref_t(void (_Tp::*__pf)()) : _M_f(__pf) {} + void operator()(_Tp& __r) const { (__r.*_M_f)(); } private: - void (T::*f)(); + void (_Tp::*_M_f)(); }; -template <class T> -class const_mem_fun_ref_t<void, T> : public unary_function<T, void> { +template <class _Tp> +class const_mem_fun_ref_t<void, _Tp> : public unary_function<_Tp,void> { public: - explicit const_mem_fun_ref_t(void (T::*pf)() const) : f(pf) {} - void operator()(const T& r) const { (r.*f)(); } + explicit const_mem_fun_ref_t(void (_Tp::*__pf)() const) : _M_f(__pf) {} + void operator()(const _Tp& __r) const { (__r.*_M_f)(); } private: - void (T::*f)() const; + void (_Tp::*_M_f)() const; }; -template <class T, class A> -class mem_fun1_t<void, T, A> : public binary_function<T*, A, void> { +template <class _Tp, class _Arg> +class mem_fun1_t<void, _Tp, _Arg> : public binary_function<_Tp*,_Arg,void> { public: - explicit mem_fun1_t(void (T::*pf)(A)) : f(pf) {} - void operator()(T* p, A x) const { (p->*f)(x); } + explicit mem_fun1_t(void (_Tp::*__pf)(_Arg)) : _M_f(__pf) {} + void operator()(_Tp* __p, _Arg __x) const { (__p->*_M_f)(__x); } private: - void (T::*f)(A); + void (_Tp::*_M_f)(_Arg); }; -template <class T, class A> -class const_mem_fun1_t<void, T, A> : public binary_function<const T*, A, void> { +template <class _Tp, class _Arg> +class const_mem_fun1_t<void, _Tp, _Arg> + : public binary_function<const _Tp*,_Arg,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); } + explicit const_mem_fun1_t(void (_Tp::*__pf)(_Arg) const) : _M_f(__pf) {} + void operator()(const _Tp* __p, _Arg __x) const { (__p->*_M_f)(__x); } private: - void (T::*f)(A) const; + void (_Tp::*_M_f)(_Arg) const; }; -template <class T, class A> -class mem_fun1_ref_t<void, T, A> : public binary_function<T, A, void> { +template <class _Tp, class _Arg> +class mem_fun1_ref_t<void, _Tp, _Arg> + : public binary_function<_Tp,_Arg,void> { public: - explicit mem_fun1_ref_t(void (T::*pf)(A)) : f(pf) {} - void operator()(T& r, A x) const { (r.*f)(x); } + explicit mem_fun1_ref_t(void (_Tp::*__pf)(_Arg)) : _M_f(__pf) {} + void operator()(_Tp& __r, _Arg __x) const { (__r.*_M_f)(__x); } private: - void (T::*f)(A); + void (_Tp::*_M_f)(_Arg); }; -template <class T, class A> -class const_mem_fun1_ref_t<void, T, A> : public binary_function<T, A, void> { +template <class _Tp, class _Arg> +class const_mem_fun1_ref_t<void, _Tp, _Arg> + : public binary_function<_Tp,_Arg,void> { public: - explicit const_mem_fun1_ref_t(void (T::*pf)(A) const) : f(pf) {} - void operator()(const T& r, A x) const { (r.*f)(x); } + explicit const_mem_fun1_ref_t(void (_Tp::*__pf)(_Arg) const) : _M_f(__pf) {} + void operator()(const _Tp& __r, _Arg __x) const { (__r.*_M_f)(__x); } private: - void (T::*f)(A) const; + void (_Tp::*_M_f)(_Arg) const; }; #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ -// Mem_fun adaptor helper functions. There are only four: -// mem_fun, mem_fun_ref, mem_fun1, mem_fun1_ref. +// Mem_fun adaptor helper functions. There are only two: +// mem_fun and mem_fun_ref. (mem_fun1 and mem_fun1_ref +// are provided for backward compatibility, but they are no longer +// part of the C++ standard.) -template <class S, class T> -inline mem_fun_t<S,T> mem_fun(S (T::*f)()) { - return mem_fun_t<S,T>(f); -} +template <class _Ret, class _Tp> +inline mem_fun_t<_Ret,_Tp> mem_fun(_Ret (_Tp::*__f)()) + { return mem_fun_t<_Ret,_Tp>(__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 _Ret, class _Tp> +inline const_mem_fun_t<_Ret,_Tp> mem_fun(_Ret (_Tp::*__f)() const) + { return const_mem_fun_t<_Ret,_Tp>(__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 _Ret, class _Tp> +inline mem_fun_ref_t<_Ret,_Tp> mem_fun_ref(_Ret (_Tp::*__f)()) + { return mem_fun_ref_t<_Ret,_Tp>(__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 _Ret, class _Tp> +inline const_mem_fun_ref_t<_Ret,_Tp> mem_fun_ref(_Ret (_Tp::*__f)() const) + { return const_mem_fun_ref_t<_Ret,_Tp>(__f); } -template <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 _Ret, class _Tp, class _Arg> +inline mem_fun1_t<_Ret,_Tp,_Arg> mem_fun(_Ret (_Tp::*__f)(_Arg)) + { return mem_fun1_t<_Ret,_Tp,_Arg>(__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 _Ret, class _Tp, class _Arg> +inline const_mem_fun1_t<_Ret,_Tp,_Arg> mem_fun(_Ret (_Tp::*__f)(_Arg) const) + { return const_mem_fun1_t<_Ret,_Tp,_Arg>(__f); } -template <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 _Ret, class _Tp, class _Arg> +inline mem_fun1_ref_t<_Ret,_Tp,_Arg> mem_fun_ref(_Ret (_Tp::*__f)(_Arg)) + { return mem_fun1_ref_t<_Ret,_Tp,_Arg>(__f); } -template <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); -} +template <class _Ret, class _Tp, class _Arg> +inline const_mem_fun1_ref_t<_Ret,_Tp,_Arg> +mem_fun_ref(_Ret (_Tp::*__f)(_Arg) const) + { return const_mem_fun1_ref_t<_Ret,_Tp,_Arg>(__f); } + +template <class _Ret, class _Tp, class _Arg> +inline mem_fun1_t<_Ret,_Tp,_Arg> mem_fun1(_Ret (_Tp::*__f)(_Arg)) + { return mem_fun1_t<_Ret,_Tp,_Arg>(__f); } + +template <class _Ret, class _Tp, class _Arg> +inline const_mem_fun1_t<_Ret,_Tp,_Arg> mem_fun1(_Ret (_Tp::*__f)(_Arg) const) + { return const_mem_fun1_t<_Ret,_Tp,_Arg>(__f); } + +template <class _Ret, class _Tp, class _Arg> +inline mem_fun1_ref_t<_Ret,_Tp,_Arg> mem_fun1_ref(_Ret (_Tp::*__f)(_Arg)) + { return mem_fun1_ref_t<_Ret,_Tp,_Arg>(__f); } + +template <class _Ret, class _Tp, class _Arg> +inline const_mem_fun1_ref_t<_Ret,_Tp,_Arg> +mem_fun1_ref(_Ret (_Tp::*__f)(_Arg) const) + { return const_mem_fun1_ref_t<_Ret,_Tp,_Arg>(__f); } __STL_END_NAMESPACE diff --git a/contrib/libstdc++/stl/stl_hash_fun.h b/contrib/libstdc++/stl/stl_hash_fun.h index 3afa9dc..44ab9bb 100644 --- a/contrib/libstdc++/stl/stl_hash_fun.h +++ b/contrib/libstdc++/stl/stl_hash_fun.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996 + * Copyright (c) 1996-1998 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software @@ -35,53 +35,53 @@ __STL_BEGIN_NAMESPACE -template <class Key> struct hash { }; +template <class _Key> struct hash { }; -inline size_t __stl_hash_string(const char* s) +inline size_t __stl_hash_string(const char* __s) { - unsigned long h = 0; - for ( ; *s; ++s) - h = 5*h + *s; + unsigned long __h = 0; + for ( ; *__s; ++__s) + __h = 5*__h + *__s; - return size_t(h); + return size_t(__h); } __STL_TEMPLATE_NULL struct hash<char*> { - size_t operator()(const char* s) const { return __stl_hash_string(s); } + size_t operator()(const char* __s) const { return __stl_hash_string(__s); } }; __STL_TEMPLATE_NULL struct hash<const char*> { - size_t operator()(const char* s) const { return __stl_hash_string(s); } + size_t operator()(const char* __s) const { return __stl_hash_string(__s); } }; __STL_TEMPLATE_NULL struct hash<char> { - size_t operator()(char x) const { return x; } + size_t operator()(char __x) const { return __x; } }; __STL_TEMPLATE_NULL struct hash<unsigned char> { - size_t operator()(unsigned char x) const { return x; } + 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; } + size_t operator()(unsigned char __x) const { return __x; } }; __STL_TEMPLATE_NULL struct hash<short> { - size_t operator()(short x) const { return x; } + size_t operator()(short __x) const { return __x; } }; __STL_TEMPLATE_NULL struct hash<unsigned short> { - size_t operator()(unsigned short x) const { return x; } + size_t operator()(unsigned short __x) const { return __x; } }; __STL_TEMPLATE_NULL struct hash<int> { - size_t operator()(int x) const { return x; } + size_t operator()(int __x) const { return __x; } }; __STL_TEMPLATE_NULL struct hash<unsigned int> { - size_t operator()(unsigned int x) const { return x; } + size_t operator()(unsigned int __x) const { return __x; } }; __STL_TEMPLATE_NULL struct hash<long> { - size_t operator()(long x) const { return x; } + size_t operator()(long __x) const { return __x; } }; __STL_TEMPLATE_NULL struct hash<unsigned long> { - size_t operator()(unsigned long x) const { return x; } + size_t operator()(unsigned long __x) const { return __x; } }; __STL_END_NAMESPACE diff --git a/contrib/libstdc++/stl/stl_hash_map.h b/contrib/libstdc++/stl/stl_hash_map.h index 9999e9a..bf16f60 100644 --- a/contrib/libstdc++/stl/stl_hash_map.h +++ b/contrib/libstdc++/stl/stl_hash_map.h @@ -36,317 +36,375 @@ __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 +#pragma set woff 1375 #endif #ifndef __STL_LIMITED_DEFAULT_TEMPLATES -template <class Key, class T, class HashFcn = hash<Key>, - class EqualKey = equal_to<Key>, - class Alloc = alloc> +template <class _Key, class _Tp, class _HashFcn = hash<_Key>, + class _EqualKey = equal_to<_Key>, + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) > #else -template <class Key, class T, class HashFcn, class EqualKey, - class Alloc = alloc> +template <class _Key, class _Tp, class _HashFcn, class _EqualKey, + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) > #endif class hash_map { private: - typedef hashtable<pair<const Key, T>, Key, HashFcn, - select1st<pair<const Key, T> >, EqualKey, Alloc> ht; - ht rep; + typedef hashtable<pair<const _Key,_Tp>,_Key,_HashFcn, + _Select1st<pair<const _Key,_Tp> >,_EqualKey,_Alloc> _Ht; + _Ht _M_ht; public: - typedef typename ht::key_type key_type; - typedef T data_type; - typedef T mapped_type; - typedef typename ht::value_type value_type; - typedef typename ht::hasher hasher; - typedef typename ht::key_equal key_equal; - - typedef typename ht::size_type size_type; - typedef typename ht::difference_type difference_type; - typedef typename ht::pointer pointer; - typedef typename ht::const_pointer const_pointer; - typedef typename ht::reference reference; - typedef typename ht::const_reference const_reference; - - typedef typename ht::iterator iterator; - typedef typename ht::const_iterator const_iterator; - - hasher hash_funct() const { return rep.hash_funct(); } - key_equal key_eq() const { return rep.key_eq(); } + typedef typename _Ht::key_type key_type; + typedef _Tp data_type; + typedef _Tp mapped_type; + typedef typename _Ht::value_type value_type; + typedef typename _Ht::hasher hasher; + typedef typename _Ht::key_equal key_equal; + + typedef typename _Ht::size_type size_type; + typedef typename _Ht::difference_type difference_type; + typedef typename _Ht::pointer pointer; + typedef typename _Ht::const_pointer const_pointer; + typedef typename _Ht::reference reference; + typedef typename _Ht::const_reference const_reference; + + typedef typename _Ht::iterator iterator; + typedef typename _Ht::const_iterator const_iterator; + + typedef typename _Ht::allocator_type allocator_type; + + hasher hash_funct() const { return _M_ht.hash_funct(); } + key_equal key_eq() const { return _M_ht.key_eq(); } + allocator_type get_allocator() const { return _M_ht.get_allocator(); } public: - hash_map() : rep(100, hasher(), key_equal()) {} - explicit hash_map(size_type n) : rep(n, hasher(), key_equal()) {} - hash_map(size_type n, const hasher& hf) : rep(n, hf, key_equal()) {} - hash_map(size_type n, const hasher& hf, const key_equal& eql) - : rep(n, hf, eql) {} + hash_map() : _M_ht(100, hasher(), key_equal(), allocator_type()) {} + explicit hash_map(size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} + hash_map(size_type __n, const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) {} + hash_map(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) {} #ifdef __STL_MEMBER_TEMPLATES - template <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); } + template <class _InputIterator> + hash_map(_InputIterator __f, _InputIterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + template <class _InputIterator> + hash_map(_InputIterator __f, _InputIterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + template <class _InputIterator> + hash_map(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + template <class _InputIterator> + hash_map(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_unique(__f, __l); } #else - hash_map(const value_type* f, const value_type* l) - : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); } - hash_map(const value_type* f, const value_type* l, size_type n) - : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); } - hash_map(const value_type* f, const value_type* l, size_type n, - const hasher& hf) - : rep(n, hf, key_equal()) { rep.insert_unique(f, l); } - hash_map(const value_type* f, const value_type* l, size_type n, - const hasher& hf, const key_equal& eql) - : rep(n, hf, eql) { rep.insert_unique(f, l); } - - hash_map(const_iterator f, const_iterator l) - : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); } - hash_map(const_iterator f, const_iterator l, size_type n) - : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); } - hash_map(const_iterator f, const_iterator l, size_type n, - const hasher& hf) - : rep(n, hf, key_equal()) { rep.insert_unique(f, l); } - hash_map(const_iterator f, const_iterator l, size_type n, - const hasher& hf, const key_equal& eql) - : rep(n, hf, eql) { rep.insert_unique(f, l); } + hash_map(const value_type* __f, const value_type* __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_map(const value_type* __f, const value_type* __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_map(const value_type* __f, const value_type* __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_map(const value_type* __f, const value_type* __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_unique(__f, __l); } + + hash_map(const_iterator __f, const_iterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_map(const_iterator __f, const_iterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_map(const_iterator __f, const_iterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_map(const_iterator __f, const_iterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_unique(__f, __l); } #endif /*__STL_MEMBER_TEMPLATES */ public: - size_type size() const { return rep.size(); } - size_type max_size() const { return rep.max_size(); } - bool empty() const { return rep.empty(); } - void swap(hash_map& hs) { rep.swap(hs.rep); } + size_type size() const { return _M_ht.size(); } + size_type max_size() const { return _M_ht.max_size(); } + bool empty() const { return _M_ht.empty(); } + void swap(hash_map& __hs) { _M_ht.swap(__hs._M_ht); } friend bool operator== __STL_NULL_TMPL_ARGS (const hash_map&, const hash_map&); - iterator begin() { return rep.begin(); } - iterator end() { return rep.end(); } - const_iterator begin() const { return rep.begin(); } - const_iterator end() const { return rep.end(); } + iterator begin() { return _M_ht.begin(); } + iterator end() { return _M_ht.end(); } + const_iterator begin() const { return _M_ht.begin(); } + const_iterator end() const { return _M_ht.end(); } public: - pair<iterator, bool> insert(const value_type& obj) - { return rep.insert_unique(obj); } + pair<iterator,bool> insert(const value_type& __obj) + { return _M_ht.insert_unique(__obj); } #ifdef __STL_MEMBER_TEMPLATES - template <class InputIterator> - void insert(InputIterator f, InputIterator l) { rep.insert_unique(f,l); } + template <class _InputIterator> + void insert(_InputIterator __f, _InputIterator __l) + { _M_ht.insert_unique(__f,__l); } #else - void insert(const value_type* f, const value_type* l) { - rep.insert_unique(f,l); + void insert(const value_type* __f, const value_type* __l) { + _M_ht.insert_unique(__f,__l); } - void insert(const_iterator f, const_iterator l) { rep.insert_unique(f, l); } + void insert(const_iterator __f, const_iterator __l) + { _M_ht.insert_unique(__f, __l); } #endif /*__STL_MEMBER_TEMPLATES */ - pair<iterator, bool> insert_noresize(const value_type& obj) - { return rep.insert_unique_noresize(obj); } + pair<iterator,bool> insert_noresize(const value_type& __obj) + { return _M_ht.insert_unique_noresize(__obj); } - iterator find(const key_type& key) { return rep.find(key); } - const_iterator find(const key_type& key) const { return rep.find(key); } + iterator find(const key_type& __key) { return _M_ht.find(__key); } + const_iterator find(const key_type& __key) const + { return _M_ht.find(__key); } - T& operator[](const key_type& key) { - return rep.find_or_insert(value_type(key, T())).second; + _Tp& operator[](const key_type& __key) { + return _M_ht.find_or_insert(value_type(__key, _Tp())).second; } - size_type count(const key_type& key) const { return rep.count(key); } + size_type count(const key_type& __key) const { return _M_ht.count(__key); } - pair<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); } + pair<iterator, iterator> equal_range(const key_type& __key) + { return _M_ht.equal_range(__key); } + pair<const_iterator, const_iterator> + equal_range(const key_type& __key) const + { return _M_ht.equal_range(__key); } + + size_type erase(const key_type& __key) {return _M_ht.erase(__key); } + void erase(iterator __it) { _M_ht.erase(__it); } + void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } + void clear() { _M_ht.clear(); } + + void resize(size_type __hint) { _M_ht.resize(__hint); } + size_type bucket_count() const { return _M_ht.bucket_count(); } + size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } + size_type elems_in_bucket(size_type __n) const + { return _M_ht.elems_in_bucket(__n); } }; -template <class Key, class 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) +template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc> +inline bool +operator==(const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1, + const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2) { - return hm1.rep == hm2.rep; + return __hm1._M_ht == __hm2._M_ht; } #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) +template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc> +inline void +swap(hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1, + hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2) { - hm1.swap(hm2); + __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> +template <class _Key, class _Tp, class _HashFcn = hash<_Key>, + class _EqualKey = equal_to<_Key>, + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) > #else -template <class Key, class T, class HashFcn, class EqualKey, - class Alloc = alloc> +template <class _Key, class _Tp, class _HashFcn, class _EqualKey, + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) > #endif class hash_multimap { private: - typedef hashtable<pair<const Key, T>, Key, HashFcn, - select1st<pair<const Key, T> >, EqualKey, Alloc> ht; - ht rep; + typedef hashtable<pair<const _Key, _Tp>, _Key, _HashFcn, + _Select1st<pair<const _Key, _Tp> >, _EqualKey, _Alloc> + _Ht; + _Ht _M_ht; public: - typedef typename ht::key_type key_type; - typedef T data_type; - typedef T mapped_type; - typedef typename ht::value_type value_type; - typedef typename ht::hasher hasher; - typedef typename ht::key_equal key_equal; - - typedef typename ht::size_type size_type; - typedef typename ht::difference_type difference_type; - typedef typename ht::pointer pointer; - typedef typename ht::const_pointer const_pointer; - typedef typename ht::reference reference; - typedef typename ht::const_reference const_reference; - - typedef typename ht::iterator iterator; - typedef typename ht::const_iterator const_iterator; - - hasher hash_funct() const { return rep.hash_funct(); } - key_equal key_eq() const { return rep.key_eq(); } + typedef typename _Ht::key_type key_type; + typedef _Tp data_type; + typedef _Tp mapped_type; + typedef typename _Ht::value_type value_type; + typedef typename _Ht::hasher hasher; + typedef typename _Ht::key_equal key_equal; + + typedef typename _Ht::size_type size_type; + typedef typename _Ht::difference_type difference_type; + typedef typename _Ht::pointer pointer; + typedef typename _Ht::const_pointer const_pointer; + typedef typename _Ht::reference reference; + typedef typename _Ht::const_reference const_reference; + + typedef typename _Ht::iterator iterator; + typedef typename _Ht::const_iterator const_iterator; + + typedef typename _Ht::allocator_type allocator_type; + + hasher hash_funct() const { return _M_ht.hash_funct(); } + key_equal key_eq() const { return _M_ht.key_eq(); } + allocator_type get_allocator() const { return _M_ht.get_allocator(); } public: - hash_multimap() : rep(100, hasher(), key_equal()) {} - explicit hash_multimap(size_type n) : rep(n, hasher(), key_equal()) {} - hash_multimap(size_type n, const hasher& hf) : rep(n, hf, key_equal()) {} - hash_multimap(size_type n, const hasher& hf, const key_equal& eql) - : rep(n, hf, eql) {} + hash_multimap() : _M_ht(100, hasher(), key_equal(), allocator_type()) {} + explicit hash_multimap(size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} + hash_multimap(size_type __n, const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) {} + hash_multimap(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) {} #ifdef __STL_MEMBER_TEMPLATES - template <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); } + template <class _InputIterator> + hash_multimap(_InputIterator __f, _InputIterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + template <class _InputIterator> + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + template <class _InputIterator> + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + template <class _InputIterator> + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_equal(__f, __l); } #else - hash_multimap(const value_type* f, const value_type* l) - : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); } - hash_multimap(const value_type* f, const value_type* l, size_type n) - : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); } - hash_multimap(const value_type* f, const value_type* l, size_type n, - const hasher& hf) - : rep(n, hf, key_equal()) { rep.insert_equal(f, l); } - hash_multimap(const value_type* f, const value_type* l, size_type n, - const hasher& hf, const key_equal& eql) - : rep(n, hf, eql) { rep.insert_equal(f, l); } - - hash_multimap(const_iterator f, const_iterator l) - : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); } - hash_multimap(const_iterator f, const_iterator l, size_type n) - : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); } - hash_multimap(const_iterator f, const_iterator l, size_type n, - const hasher& hf) - : rep(n, hf, key_equal()) { rep.insert_equal(f, l); } - hash_multimap(const_iterator f, const_iterator l, size_type n, - const hasher& hf, const key_equal& eql) - : rep(n, hf, eql) { rep.insert_equal(f, l); } + hash_multimap(const value_type* __f, const value_type* __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multimap(const value_type* __f, const value_type* __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multimap(const value_type* __f, const value_type* __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multimap(const value_type* __f, const value_type* __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_equal(__f, __l); } + + hash_multimap(const_iterator __f, const_iterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multimap(const_iterator __f, const_iterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multimap(const_iterator __f, const_iterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multimap(const_iterator __f, const_iterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_equal(__f, __l); } #endif /*__STL_MEMBER_TEMPLATES */ public: - size_type size() const { return rep.size(); } - size_type max_size() const { return rep.max_size(); } - bool empty() const { return rep.empty(); } - void swap(hash_multimap& hs) { rep.swap(hs.rep); } + size_type size() const { return _M_ht.size(); } + size_type max_size() const { return _M_ht.max_size(); } + bool empty() const { return _M_ht.empty(); } + void swap(hash_multimap& __hs) { _M_ht.swap(__hs._M_ht); } friend bool - operator== __STL_NULL_TMPL_ARGS (const hash_multimap&, const hash_multimap&); + operator== __STL_NULL_TMPL_ARGS (const hash_multimap&, + const hash_multimap&); - iterator begin() { return rep.begin(); } - iterator end() { return rep.end(); } - const_iterator begin() const { return rep.begin(); } - const_iterator end() const { return rep.end(); } + iterator begin() { return _M_ht.begin(); } + iterator end() { return _M_ht.end(); } + const_iterator begin() const { return _M_ht.begin(); } + const_iterator end() const { return _M_ht.end(); } public: - iterator insert(const value_type& obj) { return rep.insert_equal(obj); } + iterator insert(const value_type& __obj) + { return _M_ht.insert_equal(__obj); } #ifdef __STL_MEMBER_TEMPLATES - template <class InputIterator> - void insert(InputIterator f, InputIterator l) { rep.insert_equal(f,l); } + template <class _InputIterator> + void insert(_InputIterator __f, _InputIterator __l) + { _M_ht.insert_equal(__f,__l); } #else - void insert(const value_type* f, const value_type* l) { - rep.insert_equal(f,l); + void insert(const value_type* __f, const value_type* __l) { + _M_ht.insert_equal(__f,__l); } - void insert(const_iterator f, const_iterator l) { rep.insert_equal(f, l); } + void insert(const_iterator __f, const_iterator __l) + { _M_ht.insert_equal(__f, __l); } #endif /*__STL_MEMBER_TEMPLATES */ - iterator insert_noresize(const value_type& obj) - { return rep.insert_equal_noresize(obj); } + iterator insert_noresize(const value_type& __obj) + { return _M_ht.insert_equal_noresize(__obj); } - iterator find(const key_type& key) { return rep.find(key); } - const_iterator find(const key_type& key) const { return rep.find(key); } + iterator find(const key_type& __key) { return _M_ht.find(__key); } + const_iterator find(const key_type& __key) const + { return _M_ht.find(__key); } - size_type count(const key_type& key) const { return rep.count(key); } + size_type count(const key_type& __key) const { return _M_ht.count(__key); } - pair<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); } + pair<iterator, iterator> equal_range(const key_type& __key) + { return _M_ht.equal_range(__key); } + pair<const_iterator, const_iterator> + equal_range(const key_type& __key) const + { return _M_ht.equal_range(__key); } - size_type erase(const key_type& key) {return rep.erase(key); } - void erase(iterator it) { rep.erase(it); } - void erase(iterator f, iterator l) { rep.erase(f, l); } - void clear() { rep.clear(); } + size_type erase(const key_type& __key) {return _M_ht.erase(__key); } + void erase(iterator __it) { _M_ht.erase(__it); } + void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } + void clear() { _M_ht.clear(); } public: - void resize(size_type hint) { rep.resize(hint); } - size_type bucket_count() const { return rep.bucket_count(); } - size_type max_bucket_count() const { return rep.max_bucket_count(); } - size_type elems_in_bucket(size_type n) const - { return rep.elems_in_bucket(n); } + void resize(size_type __hint) { _M_ht.resize(__hint); } + size_type bucket_count() const { return _M_ht.bucket_count(); } + size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } + size_type elems_in_bucket(size_type __n) const + { return _M_ht.elems_in_bucket(__n); } }; -template <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) +template <class _Key, class _Tp, class _HF, class _EqKey, class _Alloc> +inline bool +operator==(const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm1, + const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm2) { - return hm1.rep == hm2.rep; + return __hm1._M_ht == __hm2._M_ht; } #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) +template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc> +inline void +swap(hash_multimap<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1, + hash_multimap<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2) { - hm1.swap(hm2); + __hm1.swap(__hm2); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 +#pragma reset woff 1375 #endif __STL_END_NAMESPACE diff --git a/contrib/libstdc++/stl/stl_hash_set.h b/contrib/libstdc++/stl/stl_hash_set.h index 1ba87c4..b623a64 100644 --- a/contrib/libstdc++/stl/stl_hash_set.h +++ b/contrib/libstdc++/stl/stl_hash_set.h @@ -35,303 +35,361 @@ __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 +#pragma set woff 1375 #endif #ifndef __STL_LIMITED_DEFAULT_TEMPLATES -template <class Value, class HashFcn = hash<Value>, - class EqualKey = equal_to<Value>, - class Alloc = alloc> +template <class _Value, class _HashFcn = hash<_Value>, + class _EqualKey = equal_to<_Value>, + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Value) > #else -template <class Value, class HashFcn, class EqualKey, class Alloc = alloc> +template <class _Value, class _HashFcn, class _EqualKey, + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Value) > #endif class hash_set { private: - typedef hashtable<Value, Value, HashFcn, identity<Value>, - EqualKey, Alloc> ht; - ht rep; + typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>, + _EqualKey, _Alloc> _Ht; + _Ht _M_ht; public: - typedef typename ht::key_type key_type; - typedef typename ht::value_type value_type; - typedef typename ht::hasher hasher; - typedef typename ht::key_equal key_equal; + typedef typename _Ht::key_type key_type; + typedef typename _Ht::value_type value_type; + typedef typename _Ht::hasher hasher; + typedef typename _Ht::key_equal key_equal; - typedef typename ht::size_type size_type; - typedef typename ht::difference_type difference_type; - typedef typename ht::const_pointer pointer; - typedef typename ht::const_pointer const_pointer; - typedef typename ht::const_reference reference; - typedef typename ht::const_reference const_reference; + typedef typename _Ht::size_type size_type; + typedef typename _Ht::difference_type difference_type; + typedef typename _Ht::const_pointer pointer; + typedef typename _Ht::const_pointer const_pointer; + typedef typename _Ht::const_reference reference; + typedef typename _Ht::const_reference const_reference; - typedef typename ht::const_iterator iterator; - typedef typename ht::const_iterator const_iterator; + typedef typename _Ht::const_iterator iterator; + typedef typename _Ht::const_iterator const_iterator; - hasher hash_funct() const { return rep.hash_funct(); } - key_equal key_eq() const { return rep.key_eq(); } + typedef typename _Ht::allocator_type allocator_type; + + hasher hash_funct() const { return _M_ht.hash_funct(); } + key_equal key_eq() const { return _M_ht.key_eq(); } + allocator_type get_allocator() const { return _M_ht.get_allocator(); } public: - hash_set() : rep(100, hasher(), key_equal()) {} - explicit hash_set(size_type n) : rep(n, hasher(), key_equal()) {} - hash_set(size_type n, const hasher& hf) : rep(n, hf, key_equal()) {} - hash_set(size_type n, const hasher& hf, const key_equal& eql) - : rep(n, hf, eql) {} + hash_set() + : _M_ht(100, hasher(), key_equal(), allocator_type()) {} + explicit hash_set(size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} + hash_set(size_type __n, const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) {} + hash_set(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) {} #ifdef __STL_MEMBER_TEMPLATES - template <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); } + template <class _InputIterator> + hash_set(_InputIterator __f, _InputIterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + template <class _InputIterator> + hash_set(_InputIterator __f, _InputIterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + template <class _InputIterator> + hash_set(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + template <class _InputIterator> + hash_set(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_unique(__f, __l); } #else - hash_set(const value_type* f, const value_type* l) - : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); } - hash_set(const value_type* f, const value_type* l, size_type n) - : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); } - hash_set(const value_type* f, const value_type* l, size_type n, - const hasher& hf) - : rep(n, hf, key_equal()) { rep.insert_unique(f, l); } - hash_set(const value_type* f, const value_type* l, size_type n, - const hasher& hf, const key_equal& eql) - : rep(n, hf, eql) { rep.insert_unique(f, l); } - - hash_set(const_iterator f, const_iterator l) - : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); } - hash_set(const_iterator f, const_iterator l, size_type n) - : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); } - hash_set(const_iterator f, const_iterator l, size_type n, - const hasher& hf) - : rep(n, hf, key_equal()) { rep.insert_unique(f, l); } - hash_set(const_iterator f, const_iterator l, size_type n, - const hasher& hf, const key_equal& eql) - : rep(n, hf, eql) { rep.insert_unique(f, l); } + hash_set(const value_type* __f, const value_type* __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_set(const value_type* __f, const value_type* __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_set(const value_type* __f, const value_type* __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_set(const value_type* __f, const value_type* __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_unique(__f, __l); } + + hash_set(const_iterator __f, const_iterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_set(const_iterator __f, const_iterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_set(const_iterator __f, const_iterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_set(const_iterator __f, const_iterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_unique(__f, __l); } #endif /*__STL_MEMBER_TEMPLATES */ public: - size_type size() const { return rep.size(); } - size_type max_size() const { return rep.max_size(); } - bool empty() const { return rep.empty(); } - void swap(hash_set& hs) { rep.swap(hs.rep); } + size_type size() const { return _M_ht.size(); } + size_type max_size() const { return _M_ht.max_size(); } + bool empty() const { return _M_ht.empty(); } + void swap(hash_set& __hs) { _M_ht.swap(__hs._M_ht); } friend bool operator== __STL_NULL_TMPL_ARGS (const hash_set&, const hash_set&); - iterator begin() const { return rep.begin(); } - iterator end() const { return rep.end(); } + iterator begin() const { return _M_ht.begin(); } + iterator end() const { return _M_ht.end(); } public: - pair<iterator, bool> insert(const value_type& obj) + 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); + pair<typename _Ht::iterator, bool> __p = _M_ht.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); } + template <class _InputIterator> + void insert(_InputIterator __f, _InputIterator __l) + { _M_ht.insert_unique(__f,__l); } #else - void insert(const value_type* f, const value_type* l) { - rep.insert_unique(f,l); + void insert(const value_type* __f, const value_type* __l) { + _M_ht.insert_unique(__f,__l); } - void insert(const_iterator f, const_iterator l) {rep.insert_unique(f, l); } + void insert(const_iterator __f, const_iterator __l) + {_M_ht.insert_unique(__f, __l); } #endif /*__STL_MEMBER_TEMPLATES */ - pair<iterator, bool> insert_noresize(const value_type& obj) + 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); + pair<typename _Ht::iterator, bool> __p = + _M_ht.insert_unique_noresize(__obj); + return pair<iterator, bool>(__p.first, __p.second); } - iterator find(const key_type& key) const { return rep.find(key); } + iterator find(const key_type& __key) const { return _M_ht.find(__key); } - size_type count(const key_type& key) const { return rep.count(key); } + size_type count(const key_type& __key) const { return _M_ht.count(__key); } - pair<iterator, iterator> equal_range(const key_type& key) const - { return rep.equal_range(key); } + pair<iterator, iterator> equal_range(const key_type& __key) const + { return _M_ht.equal_range(__key); } - size_type erase(const key_type& key) {return rep.erase(key); } - void erase(iterator it) { rep.erase(it); } - void erase(iterator f, iterator l) { rep.erase(f, l); } - void clear() { rep.clear(); } + size_type erase(const key_type& __key) {return _M_ht.erase(__key); } + void erase(iterator __it) { _M_ht.erase(__it); } + void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } + void clear() { _M_ht.clear(); } public: - void resize(size_type hint) { rep.resize(hint); } - size_type bucket_count() const { return rep.bucket_count(); } - size_type max_bucket_count() const { return rep.max_bucket_count(); } - size_type elems_in_bucket(size_type n) const - { return rep.elems_in_bucket(n); } + void resize(size_type __hint) { _M_ht.resize(__hint); } + size_type bucket_count() const { return _M_ht.bucket_count(); } + size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } + size_type elems_in_bucket(size_type __n) const + { return _M_ht.elems_in_bucket(__n); } }; -template <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) +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; + return __hs1._M_ht == __hs2._M_ht; } #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); +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> +template <class _Value, class _HashFcn = hash<_Value>, + class _EqualKey = equal_to<_Value>, + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Value) > #else -template <class Value, class HashFcn, class EqualKey, class Alloc = alloc> +template <class _Value, class _HashFcn, class _EqualKey, + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Value) > #endif class hash_multiset { private: - typedef hashtable<Value, Value, HashFcn, identity<Value>, - EqualKey, Alloc> ht; - ht rep; + typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>, + _EqualKey, _Alloc> _Ht; + _Ht _M_ht; public: - typedef typename ht::key_type key_type; - typedef typename ht::value_type value_type; - typedef typename ht::hasher hasher; - typedef typename ht::key_equal key_equal; + typedef typename _Ht::key_type key_type; + typedef typename _Ht::value_type value_type; + typedef typename _Ht::hasher hasher; + typedef typename _Ht::key_equal key_equal; - typedef typename ht::size_type size_type; - typedef typename ht::difference_type difference_type; - typedef typename ht::const_pointer pointer; - typedef typename ht::const_pointer const_pointer; - typedef typename ht::const_reference reference; - typedef typename ht::const_reference const_reference; + typedef typename _Ht::size_type size_type; + typedef typename _Ht::difference_type difference_type; + typedef typename _Ht::const_pointer pointer; + typedef typename _Ht::const_pointer const_pointer; + typedef typename _Ht::const_reference reference; + typedef typename _Ht::const_reference const_reference; - typedef typename ht::const_iterator iterator; - typedef typename ht::const_iterator const_iterator; + typedef typename _Ht::const_iterator iterator; + typedef typename _Ht::const_iterator const_iterator; - hasher hash_funct() const { return rep.hash_funct(); } - key_equal key_eq() const { return rep.key_eq(); } + typedef typename _Ht::allocator_type allocator_type; + + hasher hash_funct() const { return _M_ht.hash_funct(); } + key_equal key_eq() const { return _M_ht.key_eq(); } + allocator_type get_allocator() const { return _M_ht.get_allocator(); } public: - hash_multiset() : rep(100, hasher(), key_equal()) {} - explicit hash_multiset(size_type n) : rep(n, hasher(), key_equal()) {} - hash_multiset(size_type n, const hasher& hf) : rep(n, hf, key_equal()) {} - hash_multiset(size_type n, const hasher& hf, const key_equal& eql) - : rep(n, hf, eql) {} + hash_multiset() + : _M_ht(100, hasher(), key_equal(), allocator_type()) {} + explicit hash_multiset(size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} + hash_multiset(size_type __n, const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) {} + hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) {} #ifdef __STL_MEMBER_TEMPLATES - template <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); } + template <class _InputIterator> + hash_multiset(_InputIterator __f, _InputIterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + template <class _InputIterator> + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + template <class _InputIterator> + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + template <class _InputIterator> + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_equal(__f, __l); } #else - hash_multiset(const value_type* f, const value_type* l) - : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); } - hash_multiset(const value_type* f, const value_type* l, size_type n) - : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); } - hash_multiset(const value_type* f, const value_type* l, size_type n, - const hasher& hf) - : rep(n, hf, key_equal()) { rep.insert_equal(f, l); } - hash_multiset(const value_type* f, const value_type* l, size_type n, - const hasher& hf, const key_equal& eql) - : rep(n, hf, eql) { rep.insert_equal(f, l); } - - hash_multiset(const_iterator f, const_iterator l) - : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); } - hash_multiset(const_iterator f, const_iterator l, size_type n) - : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); } - hash_multiset(const_iterator f, const_iterator l, size_type n, - const hasher& hf) - : rep(n, hf, key_equal()) { rep.insert_equal(f, l); } - hash_multiset(const_iterator f, const_iterator l, size_type n, - const hasher& hf, const key_equal& eql) - : rep(n, hf, eql) { rep.insert_equal(f, l); } + hash_multiset(const value_type* __f, const value_type* __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multiset(const value_type* __f, const value_type* __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multiset(const value_type* __f, const value_type* __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multiset(const value_type* __f, const value_type* __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_equal(__f, __l); } + + hash_multiset(const_iterator __f, const_iterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multiset(const_iterator __f, const_iterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multiset(const_iterator __f, const_iterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multiset(const_iterator __f, const_iterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_equal(__f, __l); } #endif /*__STL_MEMBER_TEMPLATES */ public: - size_type size() const { return rep.size(); } - size_type max_size() const { return rep.max_size(); } - bool empty() const { return rep.empty(); } - void swap(hash_multiset& hs) { rep.swap(hs.rep); } + size_type size() const { return _M_ht.size(); } + size_type max_size() const { return _M_ht.max_size(); } + bool empty() const { return _M_ht.empty(); } + void swap(hash_multiset& hs) { _M_ht.swap(hs._M_ht); } friend bool operator== __STL_NULL_TMPL_ARGS (const hash_multiset&, const hash_multiset&); - iterator begin() const { return rep.begin(); } - iterator end() const { return rep.end(); } + iterator begin() const { return _M_ht.begin(); } + iterator end() const { return _M_ht.end(); } public: - iterator insert(const value_type& obj) { return rep.insert_equal(obj); } + iterator insert(const value_type& __obj) + { return _M_ht.insert_equal(__obj); } #ifdef __STL_MEMBER_TEMPLATES - template <class InputIterator> - void insert(InputIterator f, InputIterator l) { rep.insert_equal(f,l); } + template <class _InputIterator> + void insert(_InputIterator __f, _InputIterator __l) + { _M_ht.insert_equal(__f,__l); } #else - void insert(const value_type* f, const value_type* l) { - rep.insert_equal(f,l); + void insert(const value_type* __f, const value_type* __l) { + _M_ht.insert_equal(__f,__l); } - void insert(const_iterator f, const_iterator l) { rep.insert_equal(f, l); } + void insert(const_iterator __f, const_iterator __l) + { _M_ht.insert_equal(__f, __l); } #endif /*__STL_MEMBER_TEMPLATES */ - iterator insert_noresize(const value_type& obj) - { return rep.insert_equal_noresize(obj); } + iterator insert_noresize(const value_type& __obj) + { return _M_ht.insert_equal_noresize(__obj); } - iterator find(const key_type& key) const { return rep.find(key); } + iterator find(const key_type& __key) const { return _M_ht.find(__key); } - size_type count(const key_type& key) const { return rep.count(key); } + size_type count(const key_type& __key) const { return _M_ht.count(__key); } - pair<iterator, iterator> equal_range(const key_type& key) const - { return rep.equal_range(key); } + pair<iterator, iterator> equal_range(const key_type& __key) const + { return _M_ht.equal_range(__key); } - size_type erase(const key_type& key) {return rep.erase(key); } - void erase(iterator it) { rep.erase(it); } - void erase(iterator f, iterator l) { rep.erase(f, l); } - void clear() { rep.clear(); } + size_type erase(const key_type& __key) {return _M_ht.erase(__key); } + void erase(iterator __it) { _M_ht.erase(__it); } + void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } + void clear() { _M_ht.clear(); } public: - void resize(size_type hint) { rep.resize(hint); } - size_type bucket_count() const { return rep.bucket_count(); } - size_type max_bucket_count() const { return rep.max_bucket_count(); } - size_type elems_in_bucket(size_type n) const - { return rep.elems_in_bucket(n); } + void resize(size_type __hint) { _M_ht.resize(__hint); } + size_type bucket_count() const { return _M_ht.bucket_count(); } + size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } + size_type elems_in_bucket(size_type __n) const + { return _M_ht.elems_in_bucket(__n); } }; -template <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) +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; + return __hs1._M_ht == __hs2._M_ht; } #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); +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 +#pragma reset woff 1375 #endif __STL_END_NAMESPACE diff --git a/contrib/libstdc++/stl/stl_hashtable.h b/contrib/libstdc++/stl/stl_hashtable.h index e5b63b2..78b36c1 100644 --- a/contrib/libstdc++/stl/stl_hashtable.h +++ b/contrib/libstdc++/stl/stl_hashtable.h @@ -46,128 +46,150 @@ __STL_BEGIN_NAMESPACE -template <class Value> -struct __hashtable_node +template <class _Val> +struct _Hashtable_node { - __hashtable_node* next; - Value val; + _Hashtable_node* _M_next; + _Val _M_val; }; -template <class Value, class Key, class HashFcn, - class ExtractKey, class EqualKey, class Alloc = alloc> +template <class _Val, 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> +template <class _Val, class _Key, class _HashFcn, + class _ExtractKey, class _EqualKey, class _Alloc> +struct _Hashtable_iterator; + +template <class _Val, class _Key, class _HashFcn, + class _ExtractKey, class _EqualKey, class _Alloc> +struct _Hashtable_const_iterator; + +template <class _Val, class _Key, class _HashFcn, + class _ExtractKey, class _EqualKey, class _Alloc> +struct _Hashtable_iterator { + typedef hashtable<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc> + _Hashtable; + typedef _Hashtable_iterator<_Val, _Key, _HashFcn, + _ExtractKey, _EqualKey, _Alloc> iterator; - typedef __hashtable_const_iterator<Value, Key, HashFcn, - ExtractKey, EqualKey, Alloc> + typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, + _ExtractKey, _EqualKey, _Alloc> const_iterator; - typedef __hashtable_node<Value> node; + typedef _Hashtable_node<_Val> _Node; typedef forward_iterator_tag iterator_category; - typedef Value value_type; + typedef _Val value_type; typedef ptrdiff_t difference_type; typedef size_t size_type; - typedef Value& reference; - typedef Value* pointer; + typedef _Val& reference; + typedef _Val* pointer; - node* cur; - hashtable* ht; + _Node* _M_cur; + _Hashtable* _M_ht; - __hashtable_iterator(node* n, hashtable* tab) : cur(n), ht(tab) {} - __hashtable_iterator() {} - reference operator*() const { return cur->val; } + _Hashtable_iterator(_Node* __n, _Hashtable* __tab) + : _M_cur(__n), _M_ht(__tab) {} + _Hashtable_iterator() {} + reference operator*() const { return _M_cur->_M_val; } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ iterator& operator++(); iterator operator++(int); - bool operator==(const iterator& it) const { return cur == it.cur; } - bool operator!=(const iterator& it) const { return cur != it.cur; } + bool operator==(const iterator& __it) const + { return _M_cur == __it._M_cur; } + bool operator!=(const iterator& __it) const + { return _M_cur != __it._M_cur; } }; -template <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> +template <class _Val, class _Key, class _HashFcn, + class _ExtractKey, class _EqualKey, class _Alloc> +struct _Hashtable_const_iterator { + typedef hashtable<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc> + _Hashtable; + typedef _Hashtable_iterator<_Val,_Key,_HashFcn, + _ExtractKey,_EqualKey,_Alloc> iterator; - typedef __hashtable_const_iterator<Value, Key, HashFcn, - ExtractKey, EqualKey, Alloc> + typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, + _ExtractKey, _EqualKey, _Alloc> const_iterator; - typedef __hashtable_node<Value> node; + typedef _Hashtable_node<_Val> _Node; typedef forward_iterator_tag iterator_category; - typedef Value value_type; + typedef _Val value_type; typedef ptrdiff_t difference_type; typedef size_t size_type; - typedef const Value& reference; - typedef const Value* pointer; - - const node* cur; - const hashtable* ht; - - __hashtable_const_iterator(const node* n, const hashtable* tab) - : cur(n), ht(tab) {} - __hashtable_const_iterator() {} - __hashtable_const_iterator(const iterator& it) : cur(it.cur), ht(it.ht) {} - reference operator*() const { return cur->val; } + typedef const _Val& reference; + typedef const _Val* pointer; + + const _Node* _M_cur; + const _Hashtable* _M_ht; + + _Hashtable_const_iterator(const _Node* __n, const _Hashtable* __tab) + : _M_cur(__n), _M_ht(__tab) {} + _Hashtable_const_iterator() {} + _Hashtable_const_iterator(const iterator& __it) + : _M_cur(__it._M_cur), _M_ht(__it._M_ht) {} + reference operator*() const { return _M_cur->_M_val; } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ const_iterator& operator++(); const_iterator operator++(int); - bool operator==(const const_iterator& it) const { return cur == it.cur; } - bool operator!=(const const_iterator& it) const { return cur != it.cur; } + bool operator==(const const_iterator& __it) const + { return _M_cur == __it._M_cur; } + bool operator!=(const const_iterator& __it) const + { return _M_cur != __it._M_cur; } }; // Note: assumes long is at least 32 bits. static const int __stl_num_primes = 28; static const unsigned long __stl_prime_list[__stl_num_primes] = { - 53, 97, 193, 389, 769, - 1543, 3079, 6151, 12289, 24593, - 49157, 98317, 196613, 393241, 786433, - 1572869, 3145739, 6291469, 12582917, 25165843, - 50331653, 100663319, 201326611, 402653189, 805306457, - 1610612741, 3221225473ul, 4294967291ul + 53ul, 97ul, 193ul, 389ul, 769ul, + 1543ul, 3079ul, 6151ul, 12289ul, 24593ul, + 49157ul, 98317ul, 196613ul, 393241ul, 786433ul, + 1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul, + 50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul, + 1610612741ul, 3221225473ul, 4294967291ul }; -inline unsigned long __stl_next_prime(unsigned long n) +inline unsigned long __stl_next_prime(unsigned long __n) { - const unsigned long* first = __stl_prime_list; - const unsigned long* last = __stl_prime_list + __stl_num_primes; - const unsigned long* pos = lower_bound(first, last, n); - return pos == last ? *(last - 1) : *pos; + const unsigned long* __first = __stl_prime_list; + const unsigned long* __last = __stl_prime_list + __stl_num_primes; + const unsigned long* pos = lower_bound(__first, __last, __n); + return pos == __last ? *(__last - 1) : *pos; } +// Forward declaration of operator==. + +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +class hashtable; + +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +bool operator==(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1, + const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2); -template <class Value, class Key, class HashFcn, - class ExtractKey, class EqualKey, - class Alloc> + +// Hashtables handle allocators a bit differently than other containers +// do. If we're using standard-conforming allocators, then a hashtable +// unconditionally has a member variable to hold its allocator, even if +// it so happens that all instances of the allocator type are identical. +// This is because, for hashtables, this extra storage is negligible. +// Additionally, a base class wouldn't serve any other purposes; it +// wouldn't, for example, simplify the exception-handling code. + +template <class _Val, class _Key, class _HashFcn, + class _ExtractKey, class _EqualKey, class _Alloc> class hashtable { public: - typedef Key key_type; - typedef Value value_type; - typedef HashFcn hasher; - typedef EqualKey key_equal; + typedef _Key key_type; + typedef _Val value_type; + typedef _HashFcn hasher; + typedef _EqualKey key_equal; typedef size_t size_type; typedef ptrdiff_t difference_type; @@ -176,90 +198,126 @@ public: typedef value_type& reference; typedef const value_type& const_reference; - hasher hash_funct() const { return hash; } - key_equal key_eq() const { return equals; } + hasher hash_funct() const { return _M_hash; } + key_equal key_eq() const { return _M_equals; } private: - hasher hash; - key_equal equals; - ExtractKey get_key; + typedef _Hashtable_node<_Val> _Node; - typedef __hashtable_node<Value> node; - typedef simple_alloc<node, Alloc> node_allocator; +#ifdef __STL_USE_STD_ALLOCATORS +public: + typedef typename _Alloc_traits<_Val,_Alloc>::allocator_type allocator_type; + allocator_type get_allocator() const { return _M_node_allocator; } +private: + typename _Alloc_traits<_Node, _Alloc>::allocator_type _M_node_allocator; + _Node* _M_get_node() { return _M_node_allocator.allocate(1); } + void _M_put_node(_Node* __p) { _M_node_allocator.deallocate(__p, 1); } +# define __HASH_ALLOC_INIT(__a) _M_node_allocator(__a), +#else /* __STL_USE_STD_ALLOCATORS */ +public: + typedef _Alloc allocator_type; + allocator_type get_allocator() const { return allocator_type(); } +private: + typedef simple_alloc<_Node, _Alloc> _M_node_allocator_type; + _Node* _M_get_node() { return _M_node_allocator_type::allocate(1); } + void _M_put_node(_Node* __p) { _M_node_allocator_type::deallocate(__p, 1); } +# define __HASH_ALLOC_INIT(__a) +#endif /* __STL_USE_STD_ALLOCATORS */ - vector<node*,Alloc> buckets; - size_type num_elements; +private: + hasher _M_hash; + key_equal _M_equals; + _ExtractKey _M_get_key; + vector<_Node*,_Alloc> _M_buckets; + size_type _M_num_elements; public: - typedef __hashtable_iterator<Value, Key, HashFcn, ExtractKey, EqualKey, - Alloc> - iterator; - - typedef __hashtable_const_iterator<Value, Key, HashFcn, ExtractKey, EqualKey, - Alloc> - const_iterator; + typedef _Hashtable_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc> + iterator; + typedef _Hashtable_const_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey, + _Alloc> + const_iterator; friend struct - __hashtable_iterator<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc>; + _Hashtable_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>; friend struct - __hashtable_const_iterator<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc>; + _Hashtable_const_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>; public: - hashtable(size_type n, - const HashFcn& hf, - const EqualKey& eql, - const ExtractKey& ext) - : hash(hf), equals(eql), get_key(ext), num_elements(0) + hashtable(size_type __n, + const _HashFcn& __hf, + const _EqualKey& __eql, + const _ExtractKey& __ext, + const allocator_type& __a = allocator_type()) + : __HASH_ALLOC_INIT(__a) + _M_hash(__hf), + _M_equals(__eql), + _M_get_key(__ext), + _M_buckets(__a), + _M_num_elements(0) { - initialize_buckets(n); + _M_initialize_buckets(__n); } - hashtable(size_type n, - const HashFcn& hf, - const EqualKey& eql) - : hash(hf), equals(eql), get_key(ExtractKey()), num_elements(0) + hashtable(size_type __n, + const _HashFcn& __hf, + const _EqualKey& __eql, + const allocator_type& __a = allocator_type()) + : __HASH_ALLOC_INIT(__a) + _M_hash(__hf), + _M_equals(__eql), + _M_get_key(_ExtractKey()), + _M_buckets(__a), + _M_num_elements(0) { - initialize_buckets(n); + _M_initialize_buckets(__n); } - hashtable(const hashtable& ht) - : hash(ht.hash), equals(ht.equals), get_key(ht.get_key), num_elements(0) + hashtable(const hashtable& __ht) + : __HASH_ALLOC_INIT(__ht.get_allocator()) + _M_hash(__ht._M_hash), + _M_equals(__ht._M_equals), + _M_get_key(__ht._M_get_key), + _M_buckets(__ht.get_allocator()), + _M_num_elements(0) { - copy_from(ht); + _M_copy_from(__ht); } - hashtable& operator= (const hashtable& ht) +#undef __HASH_ALLOC_INIT + + hashtable& operator= (const hashtable& __ht) { - if (&ht != this) { + if (&__ht != this) { clear(); - hash = ht.hash; - equals = ht.equals; - get_key = ht.get_key; - copy_from(ht); + _M_hash = __ht._M_hash; + _M_equals = __ht._M_equals; + _M_get_key = __ht._M_get_key; + _M_copy_from(__ht); } return *this; } ~hashtable() { clear(); } - size_type size() const { return num_elements; } + size_type size() const { return _M_num_elements; } size_type max_size() const { return size_type(-1); } bool empty() const { return size() == 0; } - void swap(hashtable& ht) + void swap(hashtable& __ht) { - __STD::swap(hash, ht.hash); - __STD::swap(equals, ht.equals); - __STD::swap(get_key, ht.get_key); - buckets.swap(ht.buckets); - __STD::swap(num_elements, ht.num_elements); + __STD::swap(_M_hash, __ht._M_hash); + __STD::swap(_M_equals, __ht._M_equals); + __STD::swap(_M_get_key, __ht._M_get_key); + _M_buckets.swap(__ht._M_buckets); + __STD::swap(_M_num_elements, __ht._M_num_elements); } iterator begin() { - for (size_type n = 0; n < buckets.size(); ++n) - if (buckets[n]) - return iterator(buckets[n], this); + for (size_type __n = 0; __n < _M_buckets.size(); ++__n) + if (_M_buckets[__n]) + return iterator(_M_buckets[__n], this); return end(); } @@ -267,9 +325,9 @@ public: const_iterator begin() const { - for (size_type n = 0; n < buckets.size(); ++n) - if (buckets[n]) - return const_iterator(buckets[n], this); + for (size_type __n = 0; __n < _M_buckets.size(); ++__n) + if (_M_buckets[__n]) + return const_iterator(_M_buckets[__n], this); return end(); } @@ -280,329 +338,345 @@ public: public: - size_type bucket_count() const { return buckets.size(); } + size_type bucket_count() const { return _M_buckets.size(); } size_type max_bucket_count() const { return __stl_prime_list[__stl_num_primes - 1]; } - size_type elems_in_bucket(size_type bucket) const + size_type elems_in_bucket(size_type __bucket) const { - size_type result = 0; - for (node* cur = buckets[bucket]; cur; cur = cur->next) - result += 1; - return result; + size_type __result = 0; + for (_Node* __cur = _M_buckets[__bucket]; __cur; __cur = __cur->_M_next) + __result += 1; + return __result; } - pair<iterator, bool> insert_unique(const value_type& obj) + pair<iterator, bool> insert_unique(const value_type& __obj) { - resize(num_elements + 1); - return insert_unique_noresize(obj); + resize(_M_num_elements + 1); + return insert_unique_noresize(__obj); } - iterator insert_equal(const value_type& obj) + iterator insert_equal(const value_type& __obj) { - resize(num_elements + 1); - return insert_equal_noresize(obj); + resize(_M_num_elements + 1); + return insert_equal_noresize(__obj); } - pair<iterator, bool> insert_unique_noresize(const value_type& obj); - iterator insert_equal_noresize(const value_type& 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) + template <class _InputIterator> + void insert_unique(_InputIterator __f, _InputIterator __l) { - insert_unique(f, l, iterator_category(f)); + insert_unique(__f, __l, __ITERATOR_CATEGORY(__f)); } - template <class InputIterator> - void insert_equal(InputIterator f, InputIterator l) + template <class _InputIterator> + void insert_equal(_InputIterator __f, _InputIterator __l) { - insert_equal(f, l, iterator_category(f)); + insert_equal(__f, __l, __ITERATOR_CATEGORY(__f)); } - template <class InputIterator> - void insert_unique(InputIterator f, InputIterator l, + template <class _InputIterator> + void insert_unique(_InputIterator __f, _InputIterator __l, input_iterator_tag) { - for ( ; f != l; ++f) - insert_unique(*f); + for ( ; __f != __l; ++__f) + insert_unique(*__f); } - template <class InputIterator> - void insert_equal(InputIterator f, InputIterator l, + template <class _InputIterator> + void insert_equal(_InputIterator __f, _InputIterator __l, input_iterator_tag) { - for ( ; f != l; ++f) - insert_equal(*f); + for ( ; __f != __l; ++__f) + insert_equal(*__f); } - template <class ForwardIterator> - void insert_unique(ForwardIterator f, ForwardIterator l, + 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); + size_type __n = 0; + distance(__f, __l, __n); + resize(_M_num_elements + __n); + for ( ; __n > 0; --__n, ++__f) + insert_unique_noresize(*__f); } - template <class ForwardIterator> - void insert_equal(ForwardIterator f, ForwardIterator l, + 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); + size_type __n = 0; + distance(__f, __l, __n); + resize(_M_num_elements + __n); + for ( ; __n > 0; --__n, ++__f) + insert_equal_noresize(*__f); } #else /* __STL_MEMBER_TEMPLATES */ - void insert_unique(const value_type* f, const value_type* l) + void insert_unique(const value_type* __f, const value_type* __l) { - size_type n = l - f; - resize(num_elements + n); - for ( ; n > 0; --n, ++f) - insert_unique_noresize(*f); + size_type __n = __l - __f; + resize(_M_num_elements + __n); + for ( ; __n > 0; --__n, ++__f) + insert_unique_noresize(*__f); } - void insert_equal(const value_type* f, const value_type* l) + void insert_equal(const value_type* __f, const value_type* __l) { - size_type n = l - f; - resize(num_elements + n); - for ( ; n > 0; --n, ++f) - insert_equal_noresize(*f); + size_type __n = __l - __f; + resize(_M_num_elements + __n); + for ( ; __n > 0; --__n, ++__f) + insert_equal_noresize(*__f); } - void insert_unique(const_iterator f, const_iterator l) + void insert_unique(const_iterator __f, const_iterator __l) { - size_type n = 0; - distance(f, l, n); - resize(num_elements + n); - for ( ; n > 0; --n, ++f) - insert_unique_noresize(*f); + size_type __n = 0; + distance(__f, __l, __n); + resize(_M_num_elements + __n); + for ( ; __n > 0; --__n, ++__f) + insert_unique_noresize(*__f); } - void insert_equal(const_iterator f, const_iterator l) + void insert_equal(const_iterator __f, const_iterator __l) { - size_type n = 0; - distance(f, l, n); - resize(num_elements + n); - for ( ; n > 0; --n, ++f) - insert_equal_noresize(*f); + size_type __n = 0; + distance(__f, __l, __n); + resize(_M_num_elements + __n); + for ( ; __n > 0; --__n, ++__f) + insert_equal_noresize(*__f); } #endif /*__STL_MEMBER_TEMPLATES */ - reference find_or_insert(const value_type& obj); + reference find_or_insert(const value_type& __obj); - iterator find(const key_type& key) + iterator find(const key_type& __key) { - size_type n = bkt_num_key(key); - node* first; - for ( first = buckets[n]; - first && !equals(get_key(first->val), key); - first = first->next) + size_type __n = _M_bkt_num_key(__key); + _Node* __first; + for ( __first = _M_buckets[__n]; + __first && !_M_equals(_M_get_key(__first->_M_val), __key); + __first = __first->_M_next) {} - return iterator(first, this); + return iterator(__first, this); } - const_iterator find(const key_type& key) const + const_iterator find(const key_type& __key) const { - size_type n = bkt_num_key(key); - const node* first; - for ( first = buckets[n]; - first && !equals(get_key(first->val), key); - first = first->next) + size_type __n = _M_bkt_num_key(__key); + const _Node* __first; + for ( __first = _M_buckets[__n]; + __first && !_M_equals(_M_get_key(__first->_M_val), __key); + __first = __first->_M_next) {} - return const_iterator(first, this); + return const_iterator(__first, this); } - size_type count(const key_type& key) const + size_type count(const key_type& __key) const { - const size_type n = bkt_num_key(key); - size_type result = 0; + const size_type __n = _M_bkt_num_key(__key); + size_type __result = 0; - for (const node* cur = buckets[n]; cur; cur = cur->next) - if (equals(get_key(cur->val), key)) - ++result; - return result; + for (const _Node* __cur = _M_buckets[__n]; __cur; __cur = __cur->_M_next) + if (_M_equals(_M_get_key(__cur->_M_val), __key)) + ++__result; + return __result; } - pair<iterator, iterator> equal_range(const key_type& key); - pair<const_iterator, const_iterator> equal_range(const key_type& key) const; + pair<iterator, iterator> + equal_range(const key_type& __key); - size_type erase(const key_type& key); - void erase(const iterator& it); - void erase(iterator first, iterator last); + pair<const_iterator, const_iterator> + equal_range(const key_type& __key) const; - void erase(const const_iterator& it); - void erase(const_iterator first, const_iterator last); + size_type erase(const key_type& __key); + void erase(const iterator& __it); + void erase(iterator __first, iterator __last); - void resize(size_type num_elements_hint); + void erase(const const_iterator& __it); + void erase(const_iterator __first, const_iterator __last); + + void resize(size_type __num_elements_hint); void clear(); private: - size_type next_size(size_type n) const { return __stl_next_prime(n); } + size_type _M_next_size(size_type __n) const + { return __stl_next_prime(__n); } - void initialize_buckets(size_type n) + void _M_initialize_buckets(size_type __n) { - const size_type n_buckets = next_size(n); - buckets.reserve(n_buckets); - buckets.insert(buckets.end(), n_buckets, (node*) 0); - num_elements = 0; + const size_type __n_buckets = _M_next_size(__n); + _M_buckets.reserve(__n_buckets); + _M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*) 0); + _M_num_elements = 0; } - size_type bkt_num_key(const key_type& key) const + size_type _M_bkt_num_key(const key_type& __key) const { - return bkt_num_key(key, buckets.size()); + return _M_bkt_num_key(__key, _M_buckets.size()); } - size_type bkt_num(const value_type& obj) const + size_type _M_bkt_num(const value_type& __obj) const { - return bkt_num_key(get_key(obj)); + return _M_bkt_num_key(_M_get_key(__obj)); } - size_type bkt_num_key(const key_type& key, size_t n) const + size_type _M_bkt_num_key(const key_type& __key, size_t __n) const { - return hash(key) % n; + return _M_hash(__key) % __n; } - size_type bkt_num(const value_type& obj, size_t n) const + size_type _M_bkt_num(const value_type& __obj, size_t __n) const { - return bkt_num_key(get_key(obj), n); + return _M_bkt_num_key(_M_get_key(__obj), __n); } - node* new_node(const value_type& obj) + _Node* _M_new_node(const value_type& __obj) { - node* n = node_allocator::allocate(); - n->next = 0; + _Node* __n = _M_get_node(); + __n->_M_next = 0; __STL_TRY { - construct(&n->val, obj); - return n; + construct(&__n->_M_val, __obj); + return __n; } - __STL_UNWIND(node_allocator::deallocate(n)); + __STL_UNWIND(_M_put_node(__n)); } - void delete_node(node* n) + void _M_delete_node(_Node* __n) { - destroy(&n->val); - node_allocator::deallocate(n); + destroy(&__n->_M_val); + _M_put_node(__n); } - void erase_bucket(const size_type n, node* first, node* last); - void erase_bucket(const size_type n, node* last); + void _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last); + void _M_erase_bucket(const size_type __n, _Node* __last); - void copy_from(const hashtable& ht); + void _M_copy_from(const hashtable& __ht); }; -template <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++() +template <class _Val, class _Key, class _HF, class _ExK, class _EqK, + class _All> +_Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>& +_Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++() { - const node* old = cur; - cur = cur->next; - if (!cur) { - size_type bucket = ht->bkt_num(old->val); - while (!cur && ++bucket < ht->buckets.size()) - cur = ht->buckets[bucket]; + const _Node* __old = _M_cur; + _M_cur = _M_cur->_M_next; + if (!_M_cur) { + size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val); + while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size()) + _M_cur = _M_ht->_M_buckets[__bucket]; } return *this; } -template <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) +template <class _Val, class _Key, class _HF, class _ExK, class _EqK, + class _All> +inline _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All> +_Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++(int) { - iterator tmp = *this; + iterator __tmp = *this; ++*this; - return tmp; + 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++() +template <class _Val, class _Key, class _HF, class _ExK, class _EqK, + class _All> +_Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>& +_Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++() { - const node* old = cur; - cur = cur->next; - if (!cur) { - size_type bucket = ht->bkt_num(old->val); - while (!cur && ++bucket < ht->buckets.size()) - cur = ht->buckets[bucket]; + const _Node* __old = _M_cur; + _M_cur = _M_cur->_M_next; + if (!_M_cur) { + size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val); + while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size()) + _M_cur = _M_ht->_M_buckets[__bucket]; } return *this; } -template <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) +template <class _Val, class _Key, class _HF, class _ExK, class _EqK, + class _All> +inline _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All> +_Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++(int) { - const_iterator tmp = *this; + const_iterator __tmp = *this; ++*this; - return tmp; + return __tmp; } #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION -template <class V, class K, class HF, class ExK, class EqK, class All> +template <class _Val, class _Key, class _HF, class _ExK, class _EqK, + class _All> inline forward_iterator_tag -iterator_category(const __hashtable_iterator<V, K, HF, ExK, EqK, All>&) +iterator_category(const _Hashtable_iterator<_Val,_Key,_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>&) +template <class _Val, class _Key, class _HF, class _ExK, class _EqK, + class _All> +inline _Val* +value_type(const _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&) { - return (V*) 0; + return (_Val*) 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>&) +template <class _Val, class _Key, class _HF, class _ExK, class _EqK, + class _All> +inline hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::difference_type* +distance_type(const _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&) { - return (hashtable<V, K, HF, ExK, EqK, All>::difference_type*) 0; + return (hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::difference_type*) 0; } -template <class V, class K, class HF, class ExK, class EqK, class All> +template <class _Val, class _Key, class _HF, class _ExK, class _EqK, + class _All> inline forward_iterator_tag -iterator_category(const __hashtable_const_iterator<V, K, HF, ExK, EqK, All>&) +iterator_category(const _Hashtable_const_iterator<_Val,_Key,_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>&) +template <class _Val, class _Key, class _HF, class _ExK, class _EqK, + class _All> +inline _Val* +value_type(const _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&) { - return (V*) 0; + return (_Val*) 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>&) +template <class _Val, class _Key, class _HF, class _ExK, class _EqK, + class _All> +inline hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::difference_type* +distance_type(const _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&) { - return (hashtable<V, K, HF, ExK, EqK, All>::difference_type*) 0; + return (hashtable<_Val,_Key,_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) +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +inline bool operator==(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1, + const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2) { - typedef typename hashtable<V, K, HF, Ex, Eq, A>::node node; - if (ht1.buckets.size() != ht2.buckets.size()) + typedef typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::_Node _Node; + if (__ht1._M_buckets.size() != __ht2._M_buckets.size()) return false; - for (int n = 0; n < ht1.buckets.size(); ++n) { - node* cur1 = ht1.buckets[n]; - node* cur2 = ht2.buckets[n]; - for ( ; cur1 && cur2 && cur1->val == cur2->val; - cur1 = cur1->next, cur2 = cur2->next) + for (int __n = 0; __n < __ht1._M_buckets.size(); ++__n) { + _Node* __cur1 = __ht1._M_buckets[__n]; + _Node* __cur2 = __ht2._M_buckets[__n]; + for ( ; __cur1 && __cur2 && __cur1->_M_val == __cur2->_M_val; + __cur1 = __cur1->_M_next, __cur2 = __cur2->_M_next) {} - if (cur1 || cur2) + if (__cur1 || __cur2) return false; } return true; @@ -610,253 +684,265 @@ bool operator==(const hashtable<V, K, HF, Ex, Eq, A>& ht1, #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); +template <class _Val, class _Key, class _HF, class _Extract, class _EqKey, + class _All> +inline void swap(hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht1, + hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht2) { + __ht1.swap(__ht2); } #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) +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +pair<typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator, bool> +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::insert_unique_noresize(const value_type& __obj) { - const size_type n = 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); + const size_type __n = _M_bkt_num(__obj); + _Node* __first = _M_buckets[__n]; + + for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) + if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) + return pair<iterator, bool>(iterator(__cur, this), false); + + _Node* __tmp = _M_new_node(__obj); + __tmp->_M_next = __first; + _M_buckets[__n] = __tmp; + ++_M_num_elements; + return pair<iterator, bool>(iterator(__tmp, this), true); } -template <class 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) +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::insert_equal_noresize(const value_type& __obj) { - const size_type n = bkt_num(obj); - node* first = buckets[n]; - - for (node* cur = first; cur; cur = cur->next) - if (equals(get_key(cur->val), get_key(obj))) { - node* tmp = new_node(obj); - tmp->next = cur->next; - cur->next = tmp; - ++num_elements; - return iterator(tmp, this); + const size_type __n = _M_bkt_num(__obj); + _Node* __first = _M_buckets[__n]; + + for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) + if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) { + _Node* __tmp = _M_new_node(__obj); + __tmp->_M_next = __cur->_M_next; + __cur->_M_next = __tmp; + ++_M_num_elements; + return iterator(__tmp, this); } - node* tmp = new_node(obj); - tmp->next = first; - buckets[n] = tmp; - ++num_elements; - return iterator(tmp, this); + _Node* __tmp = _M_new_node(__obj); + __tmp->_M_next = __first; + _M_buckets[__n] = __tmp; + ++_M_num_elements; + return iterator(__tmp, this); } -template <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) +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::reference +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::find_or_insert(const value_type& __obj) { - resize(num_elements + 1); + resize(_M_num_elements + 1); - size_type n = bkt_num(obj); - node* first = buckets[n]; + size_type __n = _M_bkt_num(__obj); + _Node* __first = _M_buckets[__n]; - for (node* cur = first; cur; cur = cur->next) - if (equals(get_key(cur->val), get_key(obj))) - return cur->val; + for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) + if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) + return __cur->_M_val; - node* tmp = new_node(obj); - tmp->next = first; - buckets[n] = tmp; - ++num_elements; - return tmp->val; + _Node* __tmp = _M_new_node(__obj); + __tmp->_M_next = __first; + _M_buckets[__n] = __tmp; + ++_M_num_elements; + return __tmp->_M_val; } -template <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) +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +pair<typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator, + typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator> +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::equal_range(const key_type& __key) { - typedef pair<iterator, iterator> pii; - const size_type n = bkt_num_key(key); - - for (node* first = buckets[n]; first; first = first->next) { - if (equals(get_key(first->val), key)) { - for (node* cur = first->next; cur; cur = cur->next) - if (!equals(get_key(cur->val), key)) - return pii(iterator(first, this), iterator(cur, this)); - for (size_type m = n + 1; m < buckets.size(); ++m) - if (buckets[m]) - return pii(iterator(first, this), - iterator(buckets[m], this)); - return pii(iterator(first, this), end()); + typedef pair<iterator, iterator> _Pii; + const size_type __n = _M_bkt_num_key(__key); + + for (_Node* __first = _M_buckets[__n]; __first; __first = __first->_M_next) + if (_M_equals(_M_get_key(__first->_M_val), __key)) { + for (_Node* __cur = __first->_M_next; __cur; __cur = __cur->_M_next) + if (!_M_equals(_M_get_key(__cur->_M_val), __key)) + return _Pii(iterator(__first, this), iterator(__cur, this)); + for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m) + if (_M_buckets[__m]) + return _Pii(iterator(__first, this), + iterator(_M_buckets[__m], this)); + return _Pii(iterator(__first, this), end()); } - } - return pii(end(), end()); + return _Pii(end(), end()); } -template <class 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 +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +pair<typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::const_iterator, + typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::const_iterator> +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::equal_range(const key_type& __key) const { - typedef pair<const_iterator, const_iterator> pii; - const size_type n = bkt_num_key(key); - - for (const node* first = buckets[n] ; first; first = first->next) { - if (equals(get_key(first->val), key)) { - for (const node* cur = first->next; cur; cur = cur->next) - if (!equals(get_key(cur->val), key)) - return pii(const_iterator(first, this), - const_iterator(cur, this)); - for (size_type m = n + 1; m < buckets.size(); ++m) - if (buckets[m]) - return pii(const_iterator(first, this), - const_iterator(buckets[m], this)); - return pii(const_iterator(first, this), end()); + typedef pair<const_iterator, const_iterator> _Pii; + const size_type __n = _M_bkt_num_key(__key); + + for (const _Node* __first = _M_buckets[__n] ; + __first; + __first = __first->_M_next) { + if (_M_equals(_M_get_key(__first->_M_val), __key)) { + for (const _Node* __cur = __first->_M_next; + __cur; + __cur = __cur->_M_next) + if (!_M_equals(_M_get_key(__cur->_M_val), __key)) + return _Pii(const_iterator(__first, this), + const_iterator(__cur, this)); + for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m) + if (_M_buckets[__m]) + return _Pii(const_iterator(__first, this), + const_iterator(_M_buckets[__m], this)); + return _Pii(const_iterator(__first, this), end()); } } - return pii(end(), end()); + 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) +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::size_type +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const key_type& __key) { - const size_type n = bkt_num_key(key); - node* first = buckets[n]; - size_type erased = 0; - - if (first) { - node* cur = first; - node* next = cur->next; - while (next) { - if (equals(get_key(next->val), key)) { - cur->next = next->next; - delete_node(next); - next = cur->next; - ++erased; - --num_elements; + const size_type __n = _M_bkt_num_key(__key); + _Node* __first = _M_buckets[__n]; + size_type __erased = 0; + + if (__first) { + _Node* __cur = __first; + _Node* __next = __cur->_M_next; + while (__next) { + if (_M_equals(_M_get_key(__next->_M_val), __key)) { + __cur->_M_next = __next->_M_next; + _M_delete_node(__next); + __next = __cur->_M_next; + ++__erased; + --_M_num_elements; } else { - cur = next; - next = cur->next; + __cur = __next; + __next = __cur->_M_next; } } - if (equals(get_key(first->val), key)) { - buckets[n] = first->next; - delete_node(first); - ++erased; - --num_elements; + if (_M_equals(_M_get_key(__first->_M_val), __key)) { + _M_buckets[__n] = __first->_M_next; + _M_delete_node(__first); + ++__erased; + --_M_num_elements; } } - return erased; + return __erased; } -template <class V, class K, class HF, class Ex, class Eq, class A> -void hashtable<V, K, HF, Ex, Eq, A>::erase(const iterator& it) +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const iterator& __it) { - if (node* const p = it.cur) { - const size_type n = bkt_num(p->val); - node* cur = buckets[n]; - - if (cur == p) { - buckets[n] = cur->next; - delete_node(cur); - --num_elements; + if (_Node* const __p = __it._M_cur) { + const size_type __n = _M_bkt_num(__p->_M_val); + _Node* __cur = _M_buckets[__n]; + + if (__cur == __p) { + _M_buckets[__n] = __cur->_M_next; + _M_delete_node(__cur); + --_M_num_elements; } else { - node* next = cur->next; - while (next) { - if (next == p) { - cur->next = next->next; - delete_node(next); - --num_elements; + _Node* __next = __cur->_M_next; + while (__next) { + if (__next == __p) { + __cur->_M_next = __next->_M_next; + _M_delete_node(__next); + --_M_num_elements; break; } else { - cur = next; - next = cur->next; + __cur = __next; + __next = __cur->_M_next; } } } } } -template <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) +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::erase(iterator __first, iterator __last) { - size_type f_bucket = first.cur ? bkt_num(first.cur->val) : buckets.size(); - size_type l_bucket = last.cur ? bkt_num(last.cur->val) : buckets.size(); + size_type __f_bucket = __first._M_cur ? + _M_bkt_num(__first._M_cur->_M_val) : _M_buckets.size(); + size_type __l_bucket = __last._M_cur ? + _M_bkt_num(__last._M_cur->_M_val) : _M_buckets.size(); - if (first.cur == last.cur) + if (__first._M_cur == __last._M_cur) return; - else if (f_bucket == l_bucket) - erase_bucket(f_bucket, first.cur, last.cur); + else if (__f_bucket == __l_bucket) + _M_erase_bucket(__f_bucket, __first._M_cur, __last._M_cur); else { - erase_bucket(f_bucket, first.cur, 0); - for (size_type n = f_bucket + 1; n < l_bucket; ++n) - erase_bucket(n, 0); - if (l_bucket != buckets.size()) - erase_bucket(l_bucket, last.cur); + _M_erase_bucket(__f_bucket, __first._M_cur, 0); + for (size_type __n = __f_bucket + 1; __n < __l_bucket; ++__n) + _M_erase_bucket(__n, 0); + if (__l_bucket != _M_buckets.size()) + _M_erase_bucket(__l_bucket, __last._M_cur); } } -template <class V, class K, class HF, class Ex, class Eq, class A> +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> inline void -hashtable<V, K, HF, Ex, Eq, A>::erase(const_iterator first, - const_iterator last) +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const_iterator __first, + const_iterator __last) { - erase(iterator(const_cast<node*>(first.cur), - const_cast<hashtable*>(first.ht)), - iterator(const_cast<node*>(last.cur), - const_cast<hashtable*>(last.ht))); + erase(iterator(const_cast<_Node*>(__first._M_cur), + const_cast<hashtable*>(__first._M_ht)), + iterator(const_cast<_Node*>(__last._M_cur), + const_cast<hashtable*>(__last._M_ht))); } -template <class V, class K, class HF, class Ex, class Eq, class A> +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> inline void -hashtable<V, K, HF, Ex, Eq, A>::erase(const const_iterator& it) +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const const_iterator& __it) { - erase(iterator(const_cast<node*>(it.cur), - const_cast<hashtable*>(it.ht))); + erase(iterator(const_cast<_Node*>(__it._M_cur), + const_cast<hashtable*>(__it._M_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) +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::resize(size_type __num_elements_hint) { - const size_type old_n = 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); + const size_type __old_n = _M_buckets.size(); + if (__num_elements_hint > __old_n) { + const size_type __n = _M_next_size(__num_elements_hint); + if (__n > __old_n) { + vector<_Node*, _All> __tmp(__n, (_Node*)(0), + _M_buckets.get_allocator()); __STL_TRY { - for (size_type bucket = 0; bucket < old_n; ++bucket) { - node* first = buckets[bucket]; - while (first) { - size_type new_bucket = bkt_num(first->val, n); - buckets[bucket] = first->next; - first->next = tmp[new_bucket]; - tmp[new_bucket] = first; - first = buckets[bucket]; + for (size_type __bucket = 0; __bucket < __old_n; ++__bucket) { + _Node* __first = _M_buckets[__bucket]; + while (__first) { + size_type __new_bucket = _M_bkt_num(__first->_M_val, __n); + _M_buckets[__bucket] = __first->_M_next; + __first->_M_next = __tmp[__new_bucket]; + __tmp[__new_bucket] = __first; + __first = _M_buckets[__bucket]; } } - buckets.swap(tmp); + _M_buckets.swap(__tmp); } # ifdef __STL_USE_EXCEPTIONS catch(...) { - for (size_type bucket = 0; bucket < tmp.size(); ++bucket) { - while (tmp[bucket]) { - node* next = tmp[bucket]->next; - delete_node(tmp[bucket]); - tmp[bucket] = next; + for (size_type __bucket = 0; __bucket < __tmp.size(); ++__bucket) { + while (__tmp[__bucket]) { + _Node* __next = __tmp[__bucket]->_M_next; + _M_delete_node(__tmp[__bucket]); + __tmp[__bucket] = __next; } } throw; @@ -866,75 +952,80 @@ void hashtable<V, K, HF, Ex, Eq, A>::resize(size_type num_elements_hint) } } -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) +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::_M_erase_bucket(const size_type __n, _Node* __first, _Node* __last) { - node* cur = buckets[n]; - if (cur == first) - erase_bucket(n, last); + _Node* __cur = _M_buckets[__n]; + if (__cur == __first) + _M_erase_bucket(__n, __last); else { - node* next; - for (next = cur->next; next != first; cur = next, next = cur->next) + _Node* __next; + for (__next = __cur->_M_next; + __next != __first; + __cur = __next, __next = __cur->_M_next) ; - while (next) { - cur->next = next->next; - delete_node(next); - next = cur->next; - --num_elements; + while (__next) { + __cur->_M_next = __next->_M_next; + _M_delete_node(__next); + __next = __cur->_M_next; + --_M_num_elements; } } } -template <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) +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::_M_erase_bucket(const size_type __n, _Node* __last) { - node* cur = buckets[n]; - while (cur != last) { - node* next = cur->next; - delete_node(cur); - cur = next; - buckets[n] = cur; - --num_elements; + _Node* __cur = _M_buckets[__n]; + while (__cur != __last) { + _Node* __next = __cur->_M_next; + _M_delete_node(__cur); + __cur = __next; + _M_buckets[__n] = __cur; + --_M_num_elements; } } -template <class V, class K, class HF, class Ex, class Eq, class A> -void hashtable<V, K, HF, Ex, Eq, A>::clear() +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::clear() { - for (size_type i = 0; i < buckets.size(); ++i) { - node* cur = buckets[i]; - while (cur != 0) { - node* next = cur->next; - delete_node(cur); - cur = next; + for (size_type __i = 0; __i < _M_buckets.size(); ++__i) { + _Node* __cur = _M_buckets[__i]; + while (__cur != 0) { + _Node* __next = __cur->_M_next; + _M_delete_node(__cur); + __cur = __next; } - buckets[i] = 0; + _M_buckets[__i] = 0; } - num_elements = 0; + _M_num_elements = 0; } -template <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) +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::_M_copy_from(const hashtable& __ht) { - buckets.clear(); - buckets.reserve(ht.buckets.size()); - buckets.insert(buckets.end(), ht.buckets.size(), (node*) 0); + _M_buckets.clear(); + _M_buckets.reserve(__ht._M_buckets.size()); + _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*) 0); __STL_TRY { - for (size_type i = 0; i < ht.buckets.size(); ++i) { - if (const node* cur = ht.buckets[i]) { - node* copy = new_node(cur->val); - buckets[i] = copy; - - for (node* next = cur->next; next; cur = next, next = cur->next) { - copy->next = new_node(next->val); - copy = copy->next; + for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) { + if (const _Node* __cur = __ht._M_buckets[__i]) { + _Node* __copy = _M_new_node(__cur->_M_val); + _M_buckets[__i] = __copy; + + for (_Node* __next = __cur->_M_next; + __next; + __cur = __next, __next = __cur->_M_next) { + __copy->_M_next = _M_new_node(__next->_M_val); + __copy = __copy->_M_next; } } } - num_elements = ht.num_elements; + _M_num_elements = __ht._M_num_elements; } __STL_UNWIND(clear()); } diff --git a/contrib/libstdc++/stl/stl_heap.h b/contrib/libstdc++/stl/stl_heap.h index 3fe24f8..62f142e 100644 --- a/contrib/libstdc++/stl/stl_heap.h +++ b/contrib/libstdc++/stl/stl_heap.h @@ -36,181 +36,236 @@ __STL_BEGIN_NAMESPACE #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; +// Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap. + +template <class _RandomAccessIterator, class _Distance, class _Tp> +void +__push_heap(_RandomAccessIterator __first, + _Distance __holeIndex, _Distance __topIndex, _Tp __value) +{ + _Distance __parent = (__holeIndex - 1) / 2; + while (__holeIndex > __topIndex && *(__first + __parent) < __value) { + *(__first + __holeIndex) = *(__first + __parent); + __holeIndex = __parent; + __parent = (__holeIndex - 1) / 2; } - *(first + holeIndex) = value; + *(__first + __holeIndex) = __value; } -template <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, class _Distance, class _Tp> +inline void +__push_heap_aux(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Distance*, _Tp*) +{ + __push_heap(__first, _Distance((__last - __first) - 1), _Distance(0), + _Tp(*(__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> +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; +template <class _RandomAccessIterator, class _Distance, class _Tp, + class _Compare> +void +__push_heap(_RandomAccessIterator __first, _Distance __holeIndex, + _Distance __topIndex, _Tp __value, _Compare __comp) +{ + _Distance __parent = (__holeIndex - 1) / 2; + while (__holeIndex > __topIndex && __comp(*(__first + __parent), __value)) { + *(__first + __holeIndex) = *(__first + __parent); + __holeIndex = __parent; + __parent = (__holeIndex - 1) / 2; } - *(first + holeIndex) = value; -} - -template <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); + *(__first + __holeIndex) = __value; +} + +template <class _RandomAccessIterator, class _Compare, + class _Distance, class _Tp> +inline void +__push_heap_aux(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp, + _Distance*, _Tp*) +{ + __push_heap(__first, _Distance((__last - __first) - 1), _Distance(0), + _Tp(*(__last - 1)), __comp); +} + +template <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 _Tp> +void +__adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex, + _Distance __len, _Tp __value) +{ + _Distance __topIndex = __holeIndex; + _Distance __secondChild = 2 * __holeIndex + 2; + while (__secondChild < __len) { + if (*(__first + __secondChild) < *(__first + (__secondChild - 1))) + __secondChild--; + *(__first + __holeIndex) = *(__first + __secondChild); + __holeIndex = __secondChild; + __secondChild = 2 * (__secondChild + 1); } - if (secondChild == len) { - *(first + holeIndex) = *(first + (secondChild - 1)); - holeIndex = secondChild - 1; + if (__secondChild == __len) { + *(__first + __holeIndex) = *(__first + (__secondChild - 1)); + __holeIndex = __secondChild - 1; } - __push_heap(first, holeIndex, topIndex, value); + __push_heap(__first, __holeIndex, __topIndex, __value); } -template <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 _Tp, class _Distance> +inline void +__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _RandomAccessIterator __result, _Tp __value, _Distance*) +{ + *__result = *__first; + __adjust_heap(__first, _Distance(0), _Distance(__last - __first), __value); } -template <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, class _Tp> +inline void +__pop_heap_aux(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Tp*) +{ + __pop_heap(__first, __last - 1, __last - 1, + _Tp(*(__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> +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); +template <class _RandomAccessIterator, class _Distance, + class _Tp, class _Compare> +void +__adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex, + _Distance __len, _Tp __value, _Compare __comp) +{ + _Distance __topIndex = __holeIndex; + _Distance __secondChild = 2 * __holeIndex + 2; + while (__secondChild < __len) { + if (__comp(*(__first + __secondChild), *(__first + (__secondChild - 1)))) + __secondChild--; + *(__first + __holeIndex) = *(__first + __secondChild); + __holeIndex = __secondChild; + __secondChild = 2 * (__secondChild + 1); } - if (secondChild == len) { - *(first + holeIndex) = *(first + (secondChild - 1)); - holeIndex = secondChild - 1; + if (__secondChild == __len) { + *(__first + __holeIndex) = *(__first + (__secondChild - 1)); + __holeIndex = __secondChild - 1; } - __push_heap(first, holeIndex, topIndex, value, comp); + __push_heap(__first, __holeIndex, __topIndex, __value, __comp); } -template <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 _Tp, class _Compare, + class _Distance> +inline void +__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _RandomAccessIterator __result, _Tp __value, _Compare __comp, + _Distance*) +{ + *__result = *__first; + __adjust_heap(__first, _Distance(0), _Distance(__last - __first), + __value, __comp); } -template <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 _Tp, class _Compare> +inline void +__pop_heap_aux(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Tp*, _Compare __comp) +{ + __pop_heap(__first, __last - 1, __last - 1, _Tp(*(__last - 1)), __comp, + __DISTANCE_TYPE(__first)); } -template <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 _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; +template <class _RandomAccessIterator, class _Tp, class _Distance> +void +__make_heap(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Tp*, _Distance*) +{ + if (__last - __first < 2) return; + _Distance __len = __last - __first; + _Distance __parent = (__len - 2)/2; while (true) { - __adjust_heap(first, parent, len, T(*(first + parent))); - if (parent == 0) return; - parent--; + __adjust_heap(__first, __parent, __len, _Tp(*(__first + __parent))); + if (__parent == 0) return; + __parent--; } } -template <class RandomAccessIterator> -inline void make_heap(RandomAccessIterator first, RandomAccessIterator last) { - __make_heap(first, last, value_type(first), distance_type(first)); +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; +template <class _RandomAccessIterator, class _Compare, + class _Tp, class _Distance> +void +__make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp, _Tp*, _Distance*) +{ + if (__last - __first < 2) return; + _Distance __len = __last - __first; + _Distance __parent = (__len - 2)/2; while (true) { - __adjust_heap(first, parent, len, T(*(first + parent)), comp); - if (parent == 0) return; - parent--; + __adjust_heap(__first, __parent, __len, _Tp(*(__first + __parent)), + __comp); + if (__parent == 0) return; + __parent--; } } -template <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, 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> +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); +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) diff --git a/contrib/libstdc++/stl/stl_iterator.h b/contrib/libstdc++/stl/stl_iterator.h index 892db3e..e2bd714 100644 --- a/contrib/libstdc++/stl/stl_iterator.h +++ b/contrib/libstdc++/stl/stl_iterator.h @@ -12,7 +12,7 @@ * purpose. It is provided "as is" without express or implied warranty. * * - * Copyright (c) 1996,1997 + * Copyright (c) 1996-1998 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software @@ -39,12 +39,17 @@ struct forward_iterator_tag : public input_iterator_tag {}; struct bidirectional_iterator_tag : public forward_iterator_tag {}; struct random_access_iterator_tag : public bidirectional_iterator_tag {}; -template <class T, class Distance> struct input_iterator { +// The base classes input_iterator, output_iterator, forward_iterator, +// bidirectional_iterator, and random_access_iterator are not part of +// the C++ standard. (they have been replaced by struct iterator.) +// They are included for backward compatibility with the HP STL. + +template <class _Tp, 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; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; }; struct output_iterator { @@ -55,459 +60,502 @@ struct output_iterator { typedef void reference; }; -template <class T, class Distance> struct forward_iterator { +template <class _Tp, 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; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; }; -template <class T, class Distance> struct bidirectional_iterator { +template <class _Tp, 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; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; }; -template <class T, class Distance> struct random_access_iterator { +template <class _Tp, 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; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; }; #ifdef __STL_USE_NAMESPACES -template <class Category, class T, class Distance = ptrdiff_t, - class Pointer = T*, class Reference = T&> +template <class _Category, class _Tp, class _Distance = ptrdiff_t, + class _Pointer = _Tp*, class _Reference = _Tp&> struct iterator { - typedef Category iterator_category; - typedef T value_type; - typedef Distance difference_type; - typedef Pointer pointer; - typedef Reference reference; + typedef _Category iterator_category; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Pointer pointer; + typedef _Reference reference; }; #endif /* __STL_USE_NAMESPACES */ #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION -template <class Iterator> +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; + 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*> { +template <class _Tp> +struct iterator_traits<_Tp*> { typedef random_access_iterator_tag iterator_category; - typedef T value_type; - typedef ptrdiff_t difference_type; - typedef T* pointer; - typedef T& reference; + typedef _Tp value_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; }; -template <class T> -struct iterator_traits<const T*> { +template <class _Tp> +struct iterator_traits<const _Tp*> { typedef random_access_iterator_tag iterator_category; - typedef T value_type; - typedef ptrdiff_t difference_type; - typedef const T* pointer; - typedef const T& reference; + typedef _Tp value_type; + typedef ptrdiff_t difference_type; + typedef const _Tp* pointer; + typedef const _Tp& reference; }; -template <class Iterator> -inline typename iterator_traits<Iterator>::iterator_category -iterator_category(const Iterator&) { - typedef typename iterator_traits<Iterator>::iterator_category category; - return category(); +// The overloaded functions iterator_category, distance_type, and +// value_type are not part of the C++ standard. (They have been +// replaced by struct iterator_traits.) They are included for +// backward compatibility with the HP STL. + +// We introduce internal names for these functions. + +template <class _Iter> +inline typename iterator_traits<_Iter>::iterator_category +__iterator_category(const _Iter&) +{ + typedef typename iterator_traits<_Iter>::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 _Iter> +inline typename iterator_traits<_Iter>::difference_type* +__distance_type(const _Iter&) +{ + return static_cast<typename iterator_traits<_Iter>::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); +template <class _Iter> +inline typename iterator_traits<_Iter>::value_type* +__value_type(const _Iter&) +{ + return static_cast<typename iterator_traits<_Iter>::value_type*>(0); } +template <class _Iter> +inline typename iterator_traits<_Iter>::iterator_category +iterator_category(const _Iter& __i) { return __iterator_category(__i); } + + +template <class _Iter> +inline typename iterator_traits<_Iter>::difference_type* +distance_type(const _Iter& __i) { return __distance_type(__i); } + +template <class _Iter> +inline typename iterator_traits<_Iter>::value_type* +value_type(const _Iter& __i) { return __value_type(__i); } + +#define __ITERATOR_CATEGORY(__i) __iterator_category(__i) +#define __DISTANCE_TYPE(__i) __distance_type(__i) +#define __VALUE_TYPE(__i) __value_type(__i) + #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ -template <class T, class Distance> +template <class _Tp, class _Distance> inline input_iterator_tag -iterator_category(const input_iterator<T, Distance>&) { - return input_iterator_tag(); -} +iterator_category(const input_iterator<_Tp, _Distance>&) + { return input_iterator_tag(); } -inline output_iterator_tag iterator_category(const output_iterator&) { - return output_iterator_tag(); -} +inline output_iterator_tag iterator_category(const output_iterator&) + { return output_iterator_tag(); } -template <class T, class Distance> +template <class _Tp, class _Distance> inline forward_iterator_tag -iterator_category(const forward_iterator<T, Distance>&) { - return forward_iterator_tag(); -} +iterator_category(const forward_iterator<_Tp, _Distance>&) + { return forward_iterator_tag(); } -template <class T, class Distance> +template <class _Tp, class _Distance> inline bidirectional_iterator_tag -iterator_category(const bidirectional_iterator<T, Distance>&) { - return bidirectional_iterator_tag(); -} +iterator_category(const bidirectional_iterator<_Tp, _Distance>&) + { return bidirectional_iterator_tag(); } -template <class T, class Distance> +template <class _Tp, class _Distance> inline random_access_iterator_tag -iterator_category(const random_access_iterator<T, Distance>&) { - return random_access_iterator_tag(); -} +iterator_category(const random_access_iterator<_Tp, _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 _Tp> +inline random_access_iterator_tag iterator_category(const _Tp*) + { return random_access_iterator_tag(); } -template <class T, class Distance> -inline T* value_type(const input_iterator<T, Distance>&) { - return (T*)(0); -} +template <class _Tp, class _Distance> +inline _Tp* value_type(const input_iterator<_Tp, _Distance>&) + { return (_Tp*)(0); } -template <class T, class Distance> -inline T* value_type(const forward_iterator<T, Distance>&) { - return (T*)(0); -} +template <class _Tp, class _Distance> +inline _Tp* value_type(const forward_iterator<_Tp, _Distance>&) + { return (_Tp*)(0); } -template <class T, class Distance> -inline T* value_type(const bidirectional_iterator<T, Distance>&) { - return (T*)(0); -} +template <class _Tp, class _Distance> +inline _Tp* value_type(const bidirectional_iterator<_Tp, _Distance>&) + { return (_Tp*)(0); } -template <class T, class Distance> -inline T* value_type(const random_access_iterator<T, Distance>&) { - return (T*)(0); -} +template <class _Tp, class _Distance> +inline _Tp* value_type(const random_access_iterator<_Tp, _Distance>&) + { return (_Tp*)(0); } -template <class T> -inline T* value_type(const T*) { return (T*)(0); } +template <class _Tp> +inline _Tp* value_type(const _Tp*) { return (_Tp*)(0); } -template <class T, class Distance> -inline Distance* distance_type(const input_iterator<T, Distance>&) { - return (Distance*)(0); +template <class _Tp, class _Distance> +inline _Distance* distance_type(const input_iterator<_Tp, _Distance>&) +{ + return (_Distance*)(0); } -template <class T, class Distance> -inline Distance* distance_type(const forward_iterator<T, Distance>&) { - return (Distance*)(0); +template <class _Tp, class _Distance> +inline _Distance* distance_type(const forward_iterator<_Tp, _Distance>&) +{ + return (_Distance*)(0); } -template <class T, class Distance> -inline Distance* -distance_type(const bidirectional_iterator<T, Distance>&) { - return (Distance*)(0); +template <class _Tp, class _Distance> +inline _Distance* +distance_type(const bidirectional_iterator<_Tp, _Distance>&) +{ + return (_Distance*)(0); } -template <class T, class Distance> -inline Distance* -distance_type(const random_access_iterator<T, Distance>&) { - return (Distance*)(0); +template <class _Tp, class _Distance> +inline _Distance* +distance_type(const random_access_iterator<_Tp, _Distance>&) +{ + return (_Distance*)(0); } -template <class T> -inline ptrdiff_t* distance_type(const T*) { return (ptrdiff_t*)(0); } +template <class _Tp> +inline ptrdiff_t* distance_type(const _Tp*) { return (ptrdiff_t*)(0); } + +// Without partial specialization we can't use iterator_traits, so +// we must keep the old iterator query functions around. + +#define __ITERATOR_CATEGORY(__i) iterator_category(__i) +#define __DISTANCE_TYPE(__i) distance_type(__i) +#define __VALUE_TYPE(__i) value_type(__i) #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ -template <class InputIterator, class Distance> -inline void __distance(InputIterator first, InputIterator last, Distance& n, - input_iterator_tag) { - while (first != last) { ++first; ++n; } +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 _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)); +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; +template <class _InputIterator> +inline typename iterator_traits<_InputIterator>::difference_type +__distance(_InputIterator __first, _InputIterator __last, input_iterator_tag) +{ + typename iterator_traits<_InputIterator>::difference_type __n = 0; + while (__first != __last) { + ++__first; ++__n; } - return n; + return __n; } -template <class RandomAccessIterator> -inline iterator_traits<RandomAccessIterator>::difference_type -__distance(RandomAccessIterator first, RandomAccessIterator last, +template <class _RandomAccessIterator> +inline typename iterator_traits<_RandomAccessIterator>::difference_type +__distance(_RandomAccessIterator __first, _RandomAccessIterator __last, random_access_iterator_tag) { - return last - first; + 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()); +template <class _InputIterator> +inline typename iterator_traits<_InputIterator>::difference_type +distance(_InputIterator __first, _InputIterator __last) { + typedef typename iterator_traits<_InputIterator>::iterator_category + _Category; + return __distance(__first, __last, _Category()); } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ -template <class InputIterator, class Distance> -inline void __advance(InputIterator& i, Distance n, input_iterator_tag) { - while (n--) ++i; +template <class _InputIter, class _Distance> +inline void __advance(_InputIter& __i, _Distance __n, input_iterator_tag) { + while (__n--) ++__i; } #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1183 #endif -template <class BidirectionalIterator, class Distance> -inline void __advance(BidirectionalIterator& i, Distance n, +template <class _BidirectionalIterator, class _Distance> +inline void __advance(_BidirectionalIterator& __i, _Distance __n, bidirectional_iterator_tag) { - if (n >= 0) - while (n--) ++i; + if (__n >= 0) + while (__n--) ++__i; else - while (n++) --i; + while (__n++) --__i; } #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1183 #endif -template <class RandomAccessIterator, class Distance> -inline void __advance(RandomAccessIterator& i, Distance n, +template <class _RandomAccessIterator, class _Distance> +inline void __advance(_RandomAccessIterator& __i, _Distance __n, random_access_iterator_tag) { - i += n; + __i += __n; } -template <class InputIterator, class Distance> -inline void advance(InputIterator& i, Distance n) { - __advance(i, n, iterator_category(i)); +template <class _InputIterator, class _Distance> +inline void advance(_InputIterator& __i, _Distance __n) { + __advance(__i, __n, iterator_category(__i)); } -template <class Container> +template <class _Container> class back_insert_iterator { protected: - Container* container; + _Container* container; public: + typedef _Container container_type; typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; - explicit back_insert_iterator(Container& x) : container(&x) {} - back_insert_iterator<Container>& - operator=(const typename Container::value_type& value) { - container->push_back(value); + explicit back_insert_iterator(_Container& __x) : container(&__x) {} + back_insert_iterator<_Container>& + operator=(const typename _Container::value_type& __value) { + container->push_back(__value); return *this; } - back_insert_iterator<Container>& operator*() { return *this; } - back_insert_iterator<Container>& operator++() { return *this; } - back_insert_iterator<Container>& operator++(int) { return *this; } + back_insert_iterator<_Container>& operator*() { return *this; } + back_insert_iterator<_Container>& operator++() { return *this; } + back_insert_iterator<_Container>& operator++(int) { return *this; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION -template <class Container> +template <class _Container> inline output_iterator_tag -iterator_category(const back_insert_iterator<Container>&) +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> +inline back_insert_iterator<_Container> back_inserter(_Container& __x) { + return back_insert_iterator<_Container>(__x); } -template <class Container> +template <class _Container> class front_insert_iterator { protected: - Container* container; + _Container* container; public: + typedef _Container container_type; typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; - explicit front_insert_iterator(Container& x) : container(&x) {} - front_insert_iterator<Container>& - operator=(const typename Container::value_type& value) { - container->push_front(value); + explicit front_insert_iterator(_Container& __x) : container(&__x) {} + front_insert_iterator<_Container>& + operator=(const typename _Container::value_type& __value) { + container->push_front(__value); return *this; } - front_insert_iterator<Container>& operator*() { return *this; } - front_insert_iterator<Container>& operator++() { return *this; } - front_insert_iterator<Container>& operator++(int) { return *this; } + front_insert_iterator<_Container>& operator*() { return *this; } + front_insert_iterator<_Container>& operator++() { return *this; } + front_insert_iterator<_Container>& operator++(int) { return *this; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION -template <class Container> +template <class _Container> inline output_iterator_tag -iterator_category(const front_insert_iterator<Container>&) +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> +inline front_insert_iterator<_Container> front_inserter(_Container& __x) { + return front_insert_iterator<_Container>(__x); } -template <class Container> +template <class _Container> class insert_iterator { protected: - Container* container; - typename Container::iterator iter; + _Container* container; + typename _Container::iterator iter; public: + typedef _Container container_type; typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; - insert_iterator(Container& x, typename Container::iterator i) - : container(&x), iter(i) {} - insert_iterator<Container>& - operator=(const typename Container::value_type& value) { - iter = container->insert(iter, value); + insert_iterator(_Container& __x, typename _Container::iterator __i) + : container(&__x), iter(__i) {} + insert_iterator<_Container>& + operator=(const typename _Container::value_type& __value) { + iter = container->insert(iter, __value); ++iter; return *this; } - insert_iterator<Container>& operator*() { return *this; } - insert_iterator<Container>& operator++() { return *this; } - insert_iterator<Container>& operator++(int) { return *this; } + insert_iterator<_Container>& operator*() { return *this; } + insert_iterator<_Container>& operator++() { return *this; } + insert_iterator<_Container>& operator++(int) { return *this; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION -template <class Container> +template <class _Container> inline output_iterator_tag -iterator_category(const insert_iterator<Container>&) +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)); +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> +template <class _BidirectionalIterator, class _Tp, class _Reference = _Tp&, + class _Distance = ptrdiff_t> #else -template <class BidirectionalIterator, class T, class Reference, - class Distance> +template <class _BidirectionalIterator, class _Tp, class _Reference, + class _Distance> #endif class reverse_bidirectional_iterator { - typedef reverse_bidirectional_iterator<BidirectionalIterator, T, Reference, - Distance> self; + typedef reverse_bidirectional_iterator<_BidirectionalIterator, _Tp, + _Reference, _Distance> _Self; protected: - BidirectionalIterator current; + _BidirectionalIterator current; public: typedef bidirectional_iterator_tag iterator_category; - typedef T value_type; - typedef Distance difference_type; - typedef T* pointer; - typedef Reference reference; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Reference reference; reverse_bidirectional_iterator() {} - explicit reverse_bidirectional_iterator(BidirectionalIterator x) - : current(x) {} - BidirectionalIterator base() const { return current; } - Reference operator*() const { - BidirectionalIterator tmp = current; - return *--tmp; + explicit reverse_bidirectional_iterator(_BidirectionalIterator __x) + : current(__x) {} + _BidirectionalIterator base() const { return current; } + _Reference operator*() const { + _BidirectionalIterator __tmp = current; + return *--__tmp; } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ - self& operator++() { + _Self& operator++() { --current; return *this; } - self operator++(int) { - self tmp = *this; + _Self operator++(int) { + _Self __tmp = *this; --current; - return tmp; + return __tmp; } - self& operator--() { + _Self& operator--() { ++current; return *this; } - self operator--(int) { - self tmp = *this; + _Self operator--(int) { + _Self __tmp = *this; ++current; - return tmp; + return __tmp; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION -template <class BidirectionalIterator, class T, class Reference, - class Distance> +template <class _BidirectionalIterator, class _Tp, class _Reference, + class _Distance> inline bidirectional_iterator_tag -iterator_category(const reverse_bidirectional_iterator<BidirectionalIterator, - T, - Reference, Distance>&) { +iterator_category(const reverse_bidirectional_iterator<_BidirectionalIterator, + _Tp, _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 _Tp, class _Reference, + class _Distance> +inline _Tp* +value_type(const reverse_bidirectional_iterator<_BidirectionalIterator, _Tp, + _Reference, _Distance>&) +{ + return (_Tp*) 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; +template <class _BidirectionalIterator, class _Tp, class _Reference, + class _Distance> +inline _Distance* +distance_type(const reverse_bidirectional_iterator<_BidirectionalIterator, + _Tp, + _Reference, _Distance>&) +{ + return (_Distance*) 0; } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ -template <class BidirectionalIterator, class T, class Reference, - class Distance> +template <class _BiIter, class _Tp, class _Ref, + 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(); + const reverse_bidirectional_iterator<_BiIter, _Tp, _Ref, _Distance>& __x, + const reverse_bidirectional_iterator<_BiIter, _Tp, _Ref, _Distance>& __y) +{ + return __x.base() == __y.base(); } #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION @@ -518,105 +566,106 @@ inline bool operator==( // reverse_bidirectional_iterator is no longer part of the draft // standard, but it is retained for backward compatibility. -template <class Iterator> +template <class _Iterator> class reverse_iterator { protected: - Iterator current; + _Iterator current; public: - typedef typename iterator_traits<Iterator>::iterator_category + typedef typename iterator_traits<_Iterator>::iterator_category iterator_category; - typedef typename iterator_traits<Iterator>::value_type + typedef typename iterator_traits<_Iterator>::value_type value_type; - typedef typename iterator_traits<Iterator>::difference_type + typedef typename iterator_traits<_Iterator>::difference_type difference_type; - typedef typename iterator_traits<Iterator>::pointer + typedef typename iterator_traits<_Iterator>::pointer pointer; - typedef typename iterator_traits<Iterator>::reference + typedef typename iterator_traits<_Iterator>::reference reference; - typedef Iterator iterator_type; - typedef reverse_iterator<Iterator> self; + typedef _Iterator iterator_type; + typedef reverse_iterator<_Iterator> _Self; public: reverse_iterator() {} - explicit reverse_iterator(iterator_type x) : current(x) {} + explicit reverse_iterator(iterator_type __x) : current(__x) {} - reverse_iterator(const self& x) : current(x.current) {} + reverse_iterator(const _Self& __x) : current(__x.current) {} #ifdef __STL_MEMBER_TEMPLATES - template <class Iter> - reverse_iterator(const reverse_iterator<Iter>& x) : current(x.current) {} + template <class _Iter> + reverse_iterator(const reverse_iterator<_Iter>& __x) + : current(__x.base()) {} #endif /* __STL_MEMBER_TEMPLATES */ iterator_type base() const { return current; } reference operator*() const { - Iterator tmp = current; - return *--tmp; + _Iterator __tmp = current; + return *--__tmp; } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ - self& operator++() { + _Self& operator++() { --current; return *this; } - self operator++(int) { - self tmp = *this; + _Self operator++(int) { + _Self __tmp = *this; --current; - return tmp; + return __tmp; } - self& operator--() { + _Self& operator--() { ++current; return *this; } - self operator--(int) { - self tmp = *this; + _Self operator--(int) { + _Self __tmp = *this; ++current; - return tmp; + return __tmp; } - self operator+(difference_type n) const { - return self(current - n); + _Self operator+(difference_type __n) const { + return _Self(current - __n); } - self& operator+=(difference_type n) { - current -= n; + _Self& operator+=(difference_type __n) { + current -= __n; return *this; } - self operator-(difference_type n) const { - return self(current + n); + _Self operator-(difference_type __n) const { + return _Self(current + __n); } - self& operator-=(difference_type n) { - current += n; + _Self& operator-=(difference_type __n) { + current += __n; return *this; } - reference operator[](difference_type n) const { return *(*this + n); } + reference operator[](difference_type __n) const { return *(*this + __n); } }; -template <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 __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 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 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); +template <class _Iterator> +inline reverse_iterator<_Iterator> +operator+(typename reverse_iterator<_Iterator>::difference_type __n, + const reverse_iterator<_Iterator>& __x) { + return reverse_iterator<_Iterator>(__x.base() - __n); } #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ @@ -625,186 +674,208 @@ operator+(reverse_iterator<Iterator>::difference_type n, // 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> +template <class _RandomAccessIterator, class _Tp, class _Reference = _Tp&, + class _Distance = ptrdiff_t> #else -template <class RandomAccessIterator, class T, class Reference, - class Distance> +template <class _RandomAccessIterator, class _Tp, class _Reference, + class _Distance> #endif class reverse_iterator { - typedef reverse_iterator<RandomAccessIterator, T, Reference, Distance> - self; + typedef reverse_iterator<_RandomAccessIterator, _Tp, _Reference, _Distance> + _Self; protected: - RandomAccessIterator current; + _RandomAccessIterator current; public: typedef random_access_iterator_tag iterator_category; - typedef T value_type; - typedef Distance difference_type; - typedef T* pointer; - typedef Reference reference; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Reference reference; reverse_iterator() {} - explicit reverse_iterator(RandomAccessIterator x) : current(x) {} - RandomAccessIterator base() const { return current; } - Reference operator*() const { return *(current - 1); } + explicit reverse_iterator(_RandomAccessIterator __x) : current(__x) {} + _RandomAccessIterator base() const { return current; } + _Reference operator*() const { return *(current - 1); } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ - self& operator++() { + _Self& operator++() { --current; return *this; } - self operator++(int) { - self tmp = *this; + _Self operator++(int) { + _Self __tmp = *this; --current; - return tmp; + return __tmp; } - self& operator--() { + _Self& operator--() { ++current; return *this; } - self operator--(int) { - self tmp = *this; + _Self operator--(int) { + _Self __tmp = *this; ++current; - return tmp; + return __tmp; } - self operator+(Distance n) const { - return self(current - n); + _Self operator+(_Distance __n) const { + return _Self(current - __n); } - self& operator+=(Distance n) { - current -= n; + _Self& operator+=(_Distance __n) { + current -= __n; return *this; } - self operator-(Distance n) const { - return self(current + n); + _Self operator-(_Distance __n) const { + return _Self(current + __n); } - self& operator-=(Distance n) { - current += n; + _Self& operator-=(_Distance __n) { + current += __n; return *this; } - Reference operator[](Distance n) const { return *(*this + n); } + _Reference operator[](_Distance __n) const { return *(*this + __n); } }; -template <class RandomAccessIterator, class T, class Reference, class Distance> +template <class _RandomAccessIterator, class _Tp, + class _Reference, class _Distance> inline random_access_iterator_tag -iterator_category(const reverse_iterator<RandomAccessIterator, T, - Reference, Distance>&) { +iterator_category(const reverse_iterator<_RandomAccessIterator, _Tp, + _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 _Tp, + class _Reference, class _Distance> +inline _Tp* value_type(const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>&) +{ + return (_Tp*) 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 _Tp, + class _Reference, class _Distance> +inline _Distance* +distance_type(const reverse_iterator<_RandomAccessIterator, + _Tp, _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 _Tp, + class _Reference, class _Distance> +inline bool +operator==(const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __x, + const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __y) +{ + return __x.base() == __y.base(); } -template <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 _Tp, + class _Reference, class _Distance> +inline bool +operator<(const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __x, + const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __y) +{ + return __y.base() < __x.base(); } -template <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 _RandomAccessIterator, class _Tp, + class _Reference, class _Distance> +inline _Distance +operator-(const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __x, + const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __y) +{ + return __y.base() - __x.base(); } -template <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); +template <class _RandAccIter, class _Tp, class _Ref, class _Dist> +inline reverse_iterator<_RandAccIter, _Tp, _Ref, _Dist> +operator+(_Dist __n, + const reverse_iterator<_RandAccIter, _Tp, _Ref, _Dist>& __x) +{ + return reverse_iterator<_RandAccIter, _Tp, _Ref, _Dist>(__x.base() - __n); } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ -template <class T, class Distance = ptrdiff_t> +// When we have templatized iostreams, istream_iterator and ostream_iterator +// must be rewritten. + +template <class _Tp, class _Dist = ptrdiff_t> class istream_iterator { - friend bool - operator== __STL_NULL_TMPL_ARGS (const istream_iterator<T, Distance>& x, - const istream_iterator<T, Distance>& y); + friend bool operator== __STL_NULL_TMPL_ARGS (const istream_iterator&, + const istream_iterator&); protected: - istream* stream; - T value; - bool end_marker; - void read() { - end_marker = (*stream) ? true : false; - if (end_marker) *stream >> value; - end_marker = (*stream) ? true : false; + istream* _M_stream; + _Tp _M_value; + bool _M_end_marker; + void _M_read() { + _M_end_marker = (*_M_stream) ? true : false; + if (_M_end_marker) *_M_stream >> _M_value; + _M_end_marker = (*_M_stream) ? true : false; } public: - typedef input_iterator_tag iterator_category; - typedef T value_type; - typedef Distance difference_type; - typedef const T* pointer; - typedef const T& reference; - - istream_iterator() : stream(&cin), end_marker(false) {} - istream_iterator(istream& s) : stream(&s) { read(); } - reference operator*() const { return value; } + typedef input_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Dist difference_type; + typedef const _Tp* pointer; + typedef const _Tp& reference; + + istream_iterator() : _M_stream(&cin), _M_end_marker(false) {} + istream_iterator(istream& __s) : _M_stream(&__s) { _M_read(); } + reference operator*() const { return _M_value; } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ - istream_iterator<T, Distance>& operator++() { - read(); + istream_iterator<_Tp, _Dist>& operator++() { + _M_read(); return *this; } - istream_iterator<T, Distance> operator++(int) { - istream_iterator<T, Distance> tmp = *this; - read(); - return tmp; + istream_iterator<_Tp, _Dist> operator++(int) { + istream_iterator<_Tp, _Dist> __tmp = *this; + _M_read(); + return __tmp; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION -template <class T, class Distance> +template <class _Tp, class _Dist> inline input_iterator_tag -iterator_category(const istream_iterator<T, Distance>&) { +iterator_category(const istream_iterator<_Tp, _Dist>&) +{ return input_iterator_tag(); } -template <class T, class Distance> -inline T* value_type(const istream_iterator<T, Distance>&) { return (T*) 0; } +template <class _Tp, class _Dist> +inline _Tp* +value_type(const istream_iterator<_Tp, _Dist>&) { return (_Tp*) 0; } -template <class T, class Distance> -inline Distance* distance_type(const istream_iterator<T, Distance>&) { - return (Distance*) 0; -} +template <class _Tp, class _Dist> +inline _Dist* +distance_type(const istream_iterator<_Tp, _Dist>&) { return (_Dist*)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 _Tp, class _Distance> +inline bool operator==(const istream_iterator<_Tp, _Distance>& __x, + const istream_iterator<_Tp, _Distance>& __y) { + return (__x._M_stream == __y._M_stream && + __x._M_end_marker == __y._M_end_marker) || + __x._M_end_marker == false && __y._M_end_marker == false; } -template <class T> +template <class _Tp> class ostream_iterator { protected: - ostream* stream; - const char* string; + ostream* _M_stream; + const char* _M_string; public: typedef output_iterator_tag iterator_category; typedef void value_type; @@ -812,23 +883,24 @@ public: typedef void pointer; typedef void reference; - ostream_iterator(ostream& s) : stream(&s), string(0) {} - ostream_iterator(ostream& s, const char* c) : stream(&s), string(c) {} - ostream_iterator<T>& operator=(const T& value) { - *stream << value; - if (string) *stream << string; + ostream_iterator(ostream& __s) : _M_stream(&__s), _M_string(0) {} + ostream_iterator(ostream& __s, const char* __c) + : _M_stream(&__s), _M_string(__c) {} + ostream_iterator<_Tp>& operator=(const _Tp& __value) { + *_M_stream << __value; + if (_M_string) *_M_stream << _M_string; return *this; } - ostream_iterator<T>& operator*() { return *this; } - ostream_iterator<T>& operator++() { return *this; } - ostream_iterator<T>& operator++(int) { return *this; } + ostream_iterator<_Tp>& operator*() { return *this; } + ostream_iterator<_Tp>& operator++() { return *this; } + ostream_iterator<_Tp>& operator++(int) { return *this; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION -template <class T> +template <class _Tp> inline output_iterator_tag -iterator_category(const ostream_iterator<T>&) { +iterator_category(const ostream_iterator<_Tp>&) { return output_iterator_tag(); } diff --git a/contrib/libstdc++/stl/stl_list.h b/contrib/libstdc++/stl/stl_list.h index ac836b6..5d95d64 100644 --- a/contrib/libstdc++/stl/stl_list.h +++ b/contrib/libstdc++/stl/stl_list.h @@ -35,577 +35,800 @@ __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 +#pragma set woff 1375 #endif -template <class T> -struct __list_node { - typedef void* void_pointer; - void_pointer next; - void_pointer prev; - T data; +template <class _Tp> +struct _List_node { + typedef void* _Void_pointer; + _Void_pointer _M_next; + _Void_pointer _M_prev; + _Tp _M_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; +template<class _Tp, class _Ref, class _Ptr> +struct _List_iterator { + typedef _List_iterator<_Tp,_Tp&,_Tp*> iterator; + typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator; + typedef _List_iterator<_Tp,_Ref,_Ptr> _Self; typedef bidirectional_iterator_tag iterator_category; - typedef T value_type; - typedef Ptr pointer; - typedef Ref reference; - typedef __list_node<T>* link_type; + typedef _Tp value_type; + typedef _Ptr pointer; + typedef _Ref reference; + typedef _List_node<_Tp> _Node; typedef size_t size_type; typedef ptrdiff_t difference_type; - link_type node; + _Node* _M_node; - __list_iterator(link_type x) : node(x) {} - __list_iterator() {} - __list_iterator(const iterator& x) : node(x.node) {} + _List_iterator(_Node* __x) : _M_node(__x) {} + _List_iterator() {} + _List_iterator(const iterator& __x) : _M_node(__x._M_node) {} - bool operator==(const self& x) const { return node == x.node; } - bool operator!=(const self& x) const { return node != x.node; } - reference operator*() const { return (*node).data; } + bool operator==(const _Self& __x) const { return _M_node == __x._M_node; } + bool operator!=(const _Self& __x) const { return _M_node != __x._M_node; } + reference operator*() const { return (*_M_node)._M_data; } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ - self& operator++() { - node = (link_type)((*node).next); + _Self& operator++() { + _M_node = (_Node*)(_M_node->_M_next); return *this; } - self operator++(int) { - self tmp = *this; + _Self operator++(int) { + _Self __tmp = *this; ++*this; - return tmp; + return __tmp; } - self& operator--() { - node = (link_type)((*node).prev); + _Self& operator--() { + _M_node = (_Node*)(_M_node->_M_prev); return *this; } - self operator--(int) { - self tmp = *this; + _Self operator--(int) { + _Self __tmp = *this; --*this; - return tmp; + return __tmp; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION -template <class T, class Ref, class Ptr> +template <class _Tp, class _Ref, class _Ptr> inline bidirectional_iterator_tag -iterator_category(const __list_iterator<T, Ref, Ptr>&) { +iterator_category(const _List_iterator<_Tp, _Ref, _Ptr>&) +{ return bidirectional_iterator_tag(); } -template <class T, class Ref, class Ptr> -inline T* -value_type(const __list_iterator<T, Ref, Ptr>&) { +template <class _Tp, class _Ref, class _Ptr> +inline _Tp* +value_type(const _List_iterator<_Tp, _Ref, _Ptr>&) +{ return 0; } -template <class T, class Ref, class Ptr> +template <class _Tp, class _Ref, class _Ptr> inline ptrdiff_t* -distance_type(const __list_iterator<T, Ref, Ptr>&) { +distance_type(const _List_iterator<_Tp, _Ref, _Ptr>&) +{ return 0; } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ -template <class T, class Alloc = alloc> -class list { + +// Base class that encapsulates details of allocators. Three cases: +// an ordinary standard-conforming allocator, a standard-conforming +// allocator with no non-static data, and an SGI-style allocator. +// This complexity is necessary only because we're worrying about backward +// compatibility and because we want to avoid wasting storage on an +// allocator instance if it isn't necessary. + +#ifdef __STL_USE_STD_ALLOCATORS + +// Base for general standard-conforming allocators. +template <class _Tp, class _Allocator, bool _IsStatic> +class _List_alloc_base { +public: + typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return _Node_allocator; } + + _List_alloc_base(const allocator_type& __a) : _Node_allocator(__a) {} + +protected: + _List_node<_Tp>* _M_get_node() + { return _Node_allocator.allocate(1); } + void _M_put_node(_List_node<_Tp>* __p) + { _Node_allocator.deallocate(__p, 1); } + +protected: + typename _Alloc_traits<_List_node<_Tp>, _Allocator>::allocator_type + _Node_allocator; + _List_node<_Tp>* _M_node; +}; + +// Specialization for instanceless allocators. + +template <class _Tp, class _Allocator> +class _List_alloc_base<_Tp, _Allocator, true> { +public: + typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _List_alloc_base(const allocator_type&) {} + +protected: + typedef typename _Alloc_traits<_List_node<_Tp>, _Allocator>::_Alloc_type + _Alloc_type; + _List_node<_Tp>* _M_get_node() { return _Alloc_type::allocate(1); } + void _M_put_node(_List_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); } + +protected: + _List_node<_Tp>* _M_node; +}; + +template <class _Tp, class _Alloc> +class _List_base + : public _List_alloc_base<_Tp, _Alloc, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> +{ +public: + typedef _List_alloc_base<_Tp, _Alloc, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> + _Base; + typedef typename _Base::allocator_type allocator_type; + + _List_base(const allocator_type& __a) : _Base(__a) { + _M_node = _M_get_node(); + _M_node->_M_next = _M_node; + _M_node->_M_prev = _M_node; + } + ~_List_base() { + clear(); + _M_put_node(_M_node); + } + + void clear(); +}; + +#else /* __STL_USE_STD_ALLOCATORS */ + +template <class _Tp, class _Alloc> +class _List_base +{ +public: + typedef _Alloc allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _List_base(const allocator_type&) { + _M_node = _M_get_node(); + _M_node->_M_next = _M_node; + _M_node->_M_prev = _M_node; + } + ~_List_base() { + clear(); + _M_put_node(_M_node); + } + + void clear(); + +protected: + typedef simple_alloc<_List_node<_Tp>, _Alloc> _Alloc_type; + _List_node<_Tp>* _M_get_node() { return _Alloc_type::allocate(1); } + void _M_put_node(_List_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); } + protected: - typedef void* void_pointer; - typedef __list_node<T> list_node; - typedef simple_alloc<list_node, Alloc> list_node_allocator; + _List_node<_Tp>* _M_node; +}; + +#endif /* __STL_USE_STD_ALLOCATORS */ + +template <class _Tp, class _Alloc> +void +_List_base<_Tp,_Alloc>::clear() +{ + _List_node<_Tp>* __cur = (_List_node<_Tp>*) _M_node->_M_next; + while (__cur != _M_node) { + _List_node<_Tp>* __tmp = __cur; + __cur = (_List_node<_Tp>*) __cur->_M_next; + destroy(&__tmp->_M_data); + _M_put_node(__tmp); + } + _M_node->_M_next = _M_node; + _M_node->_M_prev = _M_node; +} + +template <class _Tp, class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) > +class list : protected _List_base<_Tp, _Alloc> { + typedef _List_base<_Tp, _Alloc> _Base; +protected: + typedef void* _Void_pointer; + public: - typedef T value_type; + typedef _Tp value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type& reference; typedef const value_type& const_reference; - typedef list_node* link_type; + typedef _List_node<_Tp> _Node; typedef size_t size_type; typedef ptrdiff_t difference_type; + typedef typename _Base::allocator_type allocator_type; + allocator_type get_allocator() const { return _Base::get_allocator(); } + public: - typedef __list_iterator<T, T&, T*> iterator; - typedef __list_iterator<T, const T&, const T*> const_iterator; + typedef _List_iterator<_Tp,_Tp&,_Tp*> iterator; + typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator; #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION typedef reverse_iterator<const_iterator> const_reverse_iterator; - typedef reverse_iterator<iterator> 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; + 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); - } +#ifdef __STL_HAS_NAMESPACES + using _Base::_M_node; + using _Base::_M_put_node; + using _Base::_M_get_node; +#endif /* __STL_HAS_NAMESPACES */ protected: - void empty_initialize() { - node = get_node(); - node->next = node; - node->prev = node; - } - - void fill_initialize(size_type n, const T& value) { - empty_initialize(); + _Node* _M_create_node(const _Tp& __x) + { + _Node* __p = _M_get_node(); __STL_TRY { - insert(begin(), n, value); + construct(&__p->_M_data, __x); } - __STL_UNWIND(clear(); put_node(node)); + __STL_UNWIND(_M_put_node(__p)); + return __p; } -#ifdef __STL_MEMBER_TEMPLATES - template <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(); + _Node* _M_create_node() + { + _Node* __p = _M_get_node(); __STL_TRY { - insert(begin(), first, last); + construct(&__p->_M_data); } - __STL_UNWIND(clear(); put_node(node)); + __STL_UNWIND(_M_put_node(__p)); + return __p; } -#endif /* __STL_MEMBER_TEMPLATES */ - -protected: - link_type node; public: - list() { empty_initialize(); } - - iterator begin() { return (link_type)((*node).next); } - const_iterator begin() const { return (link_type)((*node).next); } - iterator end() { return node; } - const_iterator end() const { return node; } - reverse_iterator rbegin() { return reverse_iterator(end()); } - const_reverse_iterator rbegin() const { - return const_reverse_iterator(end()); - } - reverse_iterator rend() { return reverse_iterator(begin()); } - const_reverse_iterator rend() const { - return const_reverse_iterator(begin()); - } - bool empty() const { return node->next == node; } + explicit list(const allocator_type& __a = allocator_type()) : _Base(__a) {} + + iterator begin() { return (_Node*)(_M_node->_M_next); } + const_iterator begin() const { return (_Node*)(_M_node->_M_next); } + + iterator end() { return _M_node; } + const_iterator end() const { return _M_node; } + + reverse_iterator rbegin() + { return reverse_iterator(end()); } + const_reverse_iterator rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator rend() + { return reverse_iterator(begin()); } + const_reverse_iterator rend() const + { return const_reverse_iterator(begin()); } + + bool empty() const { return _M_node->_M_next == _M_node; } size_type size() const { - size_type result = 0; - distance(begin(), end(), result); - return result; + size_type __result = 0; + distance(begin(), end(), __result); + return __result; } size_type max_size() const { return size_type(-1); } + reference front() { return *begin(); } const_reference front() const { return *begin(); } reference back() { return *(--end()); } const_reference back() const { return *(--end()); } - void swap(list<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; + + void swap(list<_Tp, _Alloc>& __x) { __STD::swap(_M_node, __x._M_node); } + + iterator insert(iterator __position, const _Tp& __x) { + _Node* __tmp = _M_create_node(__x); + __tmp->_M_next = __position._M_node; + __tmp->_M_prev = __position._M_node->_M_prev; + ((_Node*) (__position._M_node->_M_prev))->_M_next = __tmp; + __position._M_node->_M_prev = __tmp; + return __tmp; } - iterator insert(iterator position) { return insert(position, T()); } + iterator insert(iterator __position) { return insert(__position, _Tp()); } #ifdef __STL_MEMBER_TEMPLATES - template <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); + // Check whether it's an integral type. If so, it's not an iterator. + + template<class _Integer> + void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, + __true_type) { + insert(__pos, (size_type) __n, (_Tp) __x); } - void push_front(const T& x) { insert(begin(), x); } - void push_back(const T& x) { insert(end(), x); } - iterator erase(iterator position) { - link_type next_node = link_type(position.node->next); - link_type prev_node = link_type(position.node->prev); - prev_node->next = next_node; - next_node->prev = prev_node; - destroy_node(position.node); - return iterator(next_node); + template <class _InputIterator> + void _M_insert_dispatch(iterator __pos, + _InputIterator __first, _InputIterator __last, + __false_type); + + template <class _InputIterator> + void insert(iterator __pos, _InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_insert_dispatch(__pos, __first, __last, _Integral()); } - iterator erase(iterator first, iterator last); - void resize(size_type new_size, const T& x); - void resize(size_type new_size) { resize(new_size, T()); } - void clear(); + +#else /* __STL_MEMBER_TEMPLATES */ + void insert(iterator __position, const _Tp* __first, const _Tp* __last); + void insert(iterator __position, + const_iterator __first, const_iterator __last); +#endif /* __STL_MEMBER_TEMPLATES */ + void insert(iterator __pos, size_type __n, const _Tp& __x); + + void push_front(const _Tp& __x) { insert(begin(), __x); } + void push_front() {insert(begin());} + void push_back(const _Tp& __x) { insert(end(), __x); } + void push_back() {insert(end());} + + iterator erase(iterator __position) { + _Node* __next_node = (_Node*) (__position._M_node->_M_next); + _Node* __prev_node = (_Node*) (__position._M_node->_M_prev); + __prev_node->_M_next = __next_node; + __next_node->_M_prev = __prev_node; + destroy(&__position._M_node->_M_data); + _M_put_node(__position._M_node); + return iterator(__next_node); + } + iterator erase(iterator __first, iterator __last); + void clear() { _Base::clear(); } + + void resize(size_type __new_size, const _Tp& __x); + void resize(size_type __new_size) { resize(__new_size, _Tp()); } void pop_front() { erase(begin()); } void pop_back() { - iterator tmp = end(); - erase(--tmp); + iterator __tmp = end(); + erase(--__tmp); } - list(size_type n, const T& value) { fill_initialize(n, value); } - list(int n, const T& value) { fill_initialize(n, value); } - list(long n, const T& value) { fill_initialize(n, value); } - explicit list(size_type n) { fill_initialize(n, T()); } + list(size_type __n, const _Tp& __value, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { insert(begin(), __n, __value); } + explicit list(size_type __n) + : _Base(allocator_type()) + { insert(begin(), __n, _Tp()); } #ifdef __STL_MEMBER_TEMPLATES - template <class InputIterator> - list(InputIterator first, InputIterator last) { - range_initialize(first, last); - } + + // We don't need any dispatching tricks here, because insert does all of + // that anyway. + template <class _InputIterator> + list(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { insert(begin(), __first, __last); } #else /* __STL_MEMBER_TEMPLATES */ - list(const T* first, const T* last) { range_initialize(first, last); } - list(const_iterator first, const_iterator last) { - range_initialize(first, last); - } + + list(const _Tp* __first, const _Tp* __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { insert(begin(), __first, __last); } + list(const_iterator __first, const_iterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { insert(begin(), __first, __last); } + #endif /* __STL_MEMBER_TEMPLATES */ - list(const list<T, Alloc>& x) { - range_initialize(x.begin(), x.end()); - } - ~list() { - clear(); - put_node(node); + list(const list<_Tp, _Alloc>& __x) : _Base(__x.get_allocator()) + { insert(begin(), __x.begin(), __x.end()); } + + ~list() { } + + list<_Tp, _Alloc>& operator=(const list<_Tp, _Alloc>& __x); + +public: + // assign(), a generalized assignment member function. Two + // versions: one that takes a count, and one that takes a range. + // The range version is a member template, so we dispatch on whether + // or not the type is an integer. + + void assign(size_type __n, const _Tp& __val); + +#ifdef __STL_MEMBER_TEMPLATES + + template <class _InputIterator> + void assign(_InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_assign_dispatch(__first, __last, _Integral()); } - list<T, Alloc>& operator=(const list<T, Alloc>& x); + + template <class _Integer> + void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { assign((size_type) __n, (_Tp) __val); } + + template <class _InputIterator> + void _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type); + +#endif /* __STL_MEMBER_TEMPLATES */ protected: - void transfer(iterator position, iterator first, iterator last) { - if (position != last) { - (*(link_type((*last.node).prev))).next = position.node; - (*(link_type((*first.node).prev))).next = last.node; - (*(link_type((*position.node).prev))).next = first.node; - link_type tmp = link_type((*position.node).prev); - (*position.node).prev = (*last.node).prev; - (*last.node).prev = (*first.node).prev; - (*first.node).prev = tmp; + void transfer(iterator __position, iterator __first, iterator __last) { + if (__position != __last) { + // Remove [first, last) from its old position. + ((_Node*) (__last._M_node->_M_prev))->_M_next = __position._M_node; + ((_Node*) (__first._M_node->_M_prev))->_M_next = __last._M_node; + ((_Node*) (__position._M_node->_M_prev))->_M_next = __first._M_node; + + // Splice [first, last) into its new position. + _Node* __tmp = (_Node*) (__position._M_node->_M_prev); + __position._M_node->_M_prev = __last._M_node->_M_prev; + __last._M_node->_M_prev = __first._M_node->_M_prev; + __first._M_node->_M_prev = __tmp; } } public: - void splice(iterator position, list& x) { - if (!x.empty()) - transfer(position, x.begin(), x.end()); + void splice(iterator __position, list& __x) { + if (!__x.empty()) + transfer(__position, __x.begin(), __x.end()); } - void splice(iterator position, list&, iterator i) { - iterator j = i; - ++j; - if (position == i || position == j) return; - transfer(position, i, j); + void splice(iterator __position, list&, iterator __i) { + iterator __j = __i; + ++__j; + if (__position == __i || __position == __j) return; + transfer(__position, __i, __j); } - void splice(iterator position, list&, iterator first, iterator last) { - if (first != last) - transfer(position, first, last); + void splice(iterator __position, list&, iterator __first, iterator __last) { + if (__first != __last) + transfer(__position, __first, __last); } - void remove(const T& value); + void remove(const _Tp& __value); void unique(); - void merge(list& x); + void merge(list& __x); void reverse(); void sort(); #ifdef __STL_MEMBER_TEMPLATES - template <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); + 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); + 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) +template <class _Tp, class _Alloc> +inline bool operator==(const list<_Tp,_Alloc>& __x, + const list<_Tp,_Alloc>& __y) +{ + typedef typename list<_Tp,_Alloc>::_Node _Node; + _Node* __e1 = __x._M_node; + _Node* __e2 = __y._M_node; + _Node* __n1 = (_Node*) __e1->_M_next; + _Node* __n2 = (_Node*) __e2->_M_next; + for ( ; __n1 != __e1 && __n2 != __e2 ; + __n1 = (_Node*) __n1->_M_next, __n2 = (_Node*) __n2->_M_next) + if (__n1->_M_data != __n2->_M_data) return false; - return n1 == e1 && n2 == e2; + return __n1 == __e1 && __n2 == __e2; } -template <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()); +template <class _Tp, class _Alloc> +inline bool operator<(const list<_Tp,_Alloc>& __x, + const list<_Tp,_Alloc>& __y) +{ + return lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER -template <class T, class Alloc> -inline void swap(list<T, Alloc>& x, list<T, Alloc>& y) { - x.swap(y); +template <class _Tp, class _Alloc> +inline void +swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y) +{ + __x.swap(__y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ #ifdef __STL_MEMBER_TEMPLATES -template <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); +template <class _Tp, class _Alloc> template <class _InputIter> +void +list<_Tp, _Alloc>::_M_insert_dispatch(iterator __position, + _InputIter __first, _InputIter __last, + __false_type) +{ + for ( ; __first != __last; ++__first) + insert(__position, *__first); } #else /* __STL_MEMBER_TEMPLATES */ -template <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 _Tp, class _Alloc> +void +list<_Tp, _Alloc>::insert(iterator __position, + const _Tp* __first, const _Tp* __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); +template <class _Tp, class _Alloc> +void +list<_Tp, _Alloc>::insert(iterator __position, + const_iterator __first, const_iterator __last) +{ + for ( ; __first != __last; ++__first) + insert(__position, *__first); } #endif /* __STL_MEMBER_TEMPLATES */ -template <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 _Tp, class _Alloc> +void +list<_Tp, _Alloc>::insert(iterator __position, size_type __n, const _Tp& __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 _Tp, class _Alloc> +list<_Tp,_Alloc>::iterator list<_Tp, _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) +template <class _Tp, class _Alloc> +void list<_Tp, _Alloc>::resize(size_type __new_size, const _Tp& __x) { - iterator i = begin(); - size_type len = 0; - for ( ; i != end() && len < new_size; ++i, ++len) + iterator __i = begin(); + size_type __len = 0; + for ( ; __i != end() && __len < __new_size; ++__i, ++__len) ; - if (len == new_size) - erase(i, end()); - else // i == end() - insert(end(), new_size - len, x); + if (__len == __new_size) + erase(__i, end()); + else // __i == end() + insert(end(), __new_size - __len, __x); } -template <class T, class Alloc> -void list<T, Alloc>::clear() +template <class _Tp, class _Alloc> +list<_Tp, _Alloc>& list<_Tp, _Alloc>::operator=(const list<_Tp, _Alloc>& __x) { - link_type cur = (link_type) node->next; - while (cur != node) { - link_type tmp = cur; - cur = (link_type) cur->next; - destroy_node(tmp); - } - node->next = node; - node->prev = node; -} - -template <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); + if (this != &__x) { + iterator __first1 = begin(); + iterator __last1 = end(); + const_iterator __first2 = __x.begin(); + const_iterator __last2 = __x.end(); + while (__first1 != __last1 && __first2 != __last2) + *__first1++ = *__first2++; + if (__first2 == __last2) + erase(__first1, __last1); else - insert(last1, first2, last2); + insert(__last1, __first2, __last2); } return *this; } -template <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 _Tp, class _Alloc> +void list<_Tp, _Alloc>::assign(size_type __n, const _Tp& __val) { + iterator __i = begin(); + for ( ; __i != end() && __n > 0; ++__i, --__n) + *__i = __val; + if (__n > 0) + insert(end(), __n, __val); + else + erase(__i, end()); +} + +#ifdef __STL_MEMBER_TEMPLATES + +template <class _Tp, class _Alloc> template <class _InputIter> +void +list<_Tp, _Alloc>::_M_assign_dispatch(_InputIter __first2, _InputIter __last2, + __false_type) +{ + iterator __first1 = begin(); + iterator __last1 = end(); + for ( ; __first1 != __last1 && __first2 != __last2; ++__first1, ++__first2) + *__first1 = *__first2; + if (__first2 == __last2) + erase(__first1, __last1); + else + insert(__last1, __first2, __last2); +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +template <class _Tp, class _Alloc> +void list<_Tp, _Alloc>::remove(const _Tp& __value) +{ + iterator __first = begin(); + iterator __last = end(); + while (__first != __last) { + iterator __next = __first; + ++__next; + if (*__first == __value) erase(__first); + __first = __next; } } -template <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); +template <class _Tp, class _Alloc> +void list<_Tp, _Alloc>::unique() +{ + iterator __first = begin(); + iterator __last = end(); + if (__first == __last) return; + iterator __next = __first; + while (++__next != __last) { + if (*__first == *__next) + erase(__next); else - first = next; - next = first; + __first = __next; + __next = __first; } } -template <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; +template <class _Tp, class _Alloc> +void list<_Tp, _Alloc>::merge(list<_Tp, _Alloc>& __x) +{ + iterator __first1 = begin(); + iterator __last1 = end(); + iterator __first2 = __x.begin(); + iterator __last2 = __x.end(); + while (__first1 != __last1 && __first2 != __last2) + if (*__first2 < *__first1) { + iterator __next = __first2; + transfer(__first1, __first2, ++__next); + __first2 = __next; } else - ++first1; - if (first2 != last2) transfer(last1, first2, last2); + ++__first1; + if (__first2 != __last2) transfer(__last1, __first2, __last2); } -template <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 _Tp, class _Alloc> +void list<_Tp, _Alloc>::reverse() +{ + // Do nothing if the list has length 0 or 1. + if (_M_node->_M_next != _M_node && + ((_Node*) (_M_node->_M_next))->_M_next != _M_node) { + iterator __first = begin(); + ++__first; + while (__first != end()) { + iterator __old = __first; + ++__first; + transfer(begin(), __old, __first); + } } } -template <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]); +template <class _Tp, class _Alloc> +void list<_Tp, _Alloc>::sort() +{ + // Do nothing if the list has length 0 or 1. + if (_M_node->_M_next != _M_node && + ((_Node*) (_M_node->_M_next))->_M_next != _M_node) { + list<_Tp, _Alloc> __carry; + list<_Tp, _Alloc> __counter[64]; + int __fill = 0; + while (!empty()) { + __carry.splice(__carry.begin(), *this, begin()); + int __i = 0; + while(__i < __fill && !__counter[__i].empty()) { + __counter[__i].merge(__carry); + __carry.swap(__counter[__i++]); + } + __carry.swap(__counter[__i]); + if (__i == __fill) ++__fill; + } + + for (int __i = 1; __i < __fill; ++__i) + __counter[__i].merge(__counter[__i-1]); + swap(__counter[__fill-1]); + } } #ifdef __STL_MEMBER_TEMPLATES -template <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 _Tp, class _Alloc> template <class _Predicate> +void list<_Tp, _Alloc>::remove_if(_Predicate __pred) +{ + iterator __first = begin(); + iterator __last = end(); + while (__first != __last) { + iterator __next = __first; + ++__next; + if (__pred(*__first)) erase(__first); + __first = __next; } } -template <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); +template <class _Tp, class _Alloc> template <class _BinaryPredicate> +void list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred) +{ + iterator __first = begin(); + iterator __last = end(); + if (__first == __last) return; + iterator __next = __first; + while (++__next != __last) { + if (__binary_pred(*__first, *__next)) + erase(__next); else - first = next; - next = first; + __first = __next; + __next = __first; } } -template <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; +template <class _Tp, class _Alloc> template <class _StrictWeakOrdering> +void list<_Tp, _Alloc>::merge(list<_Tp, _Alloc>& __x, + _StrictWeakOrdering __comp) +{ + iterator __first1 = begin(); + iterator __last1 = end(); + iterator __first2 = __x.begin(); + iterator __last2 = __x.end(); + while (__first1 != __last1 && __first2 != __last2) + if (__comp(*__first2, *__first1)) { + iterator __next = __first2; + transfer(__first1, __first2, ++__next); + __first2 = __next; } else - ++first1; - if (first2 != last2) transfer(last1, first2, last2); + ++__first1; + if (__first2 != __last2) transfer(__last1, __first2, __last2); } -template <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]); +template <class _Tp, class _Alloc> template <class _StrictWeakOrdering> +void list<_Tp, _Alloc>::sort(_StrictWeakOrdering __comp) +{ + // Do nothing if the list has length 0 or 1. + if (_M_node->_M_next != _M_node && + ((_Node*) (_M_node->_M_next))->_M_next != _M_node) { + list<_Tp, _Alloc> __carry; + list<_Tp, _Alloc> __counter[64]; + int __fill = 0; + while (!empty()) { + __carry.splice(__carry.begin(), *this, begin()); + int __i = 0; + while(__i < __fill && !__counter[__i].empty()) { + __counter[__i].merge(__carry, __comp); + __carry.swap(__counter[__i++]); + } + __carry.swap(__counter[__i]); + if (__i == __fill) ++__fill; + } + + for (int __i = 1; __i < __fill; ++__i) + __counter[__i].merge(__counter[__i-1], __comp); + swap(__counter[__fill-1]); + } } #endif /* __STL_MEMBER_TEMPLATES */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 +#pragma reset woff 1375 #endif __STL_END_NAMESPACE diff --git a/contrib/libstdc++/stl/stl_map.h b/contrib/libstdc++/stl/stl_map.h index 2a830cc..a702e80 100644 --- a/contrib/libstdc++/stl/stl_map.h +++ b/contrib/libstdc++/stl/stl_map.h @@ -35,177 +35,202 @@ __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 +#pragma set woff 1375 #endif #ifndef __STL_LIMITED_DEFAULT_TEMPLATES -template <class Key, class T, class Compare = less<Key>, class Alloc = alloc> +template <class _Key, class _Tp, class _Compare = less<_Key>, + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) > #else -template <class Key, class T, class Compare, class Alloc = alloc> +template <class _Key, class _Tp, class _Compare, + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) > #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; + typedef _Key key_type; + typedef _Tp data_type; + typedef _Tp mapped_type; + typedef pair<const _Key, _Tp> value_type; + typedef _Compare key_compare; class value_compare : public binary_function<value_type, value_type, bool> { - friend class map<Key, T, Compare, Alloc>; + friend class map<_Key,_Tp,_Compare,_Alloc>; protected : - Compare comp; - value_compare(Compare c) : comp(c) {} + _Compare _M_comp; + value_compare(_Compare __c) : _M_comp(__c) {} public: - bool operator()(const value_type& x, const value_type& y) const { - return comp(x.first, y.first); + bool operator()(const value_type& __x, const value_type& __y) const { + return _M_comp(__x.first, __y.first); } }; private: - typedef rb_tree<key_type, value_type, - select1st<value_type>, key_compare, Alloc> rep_type; - rep_type t; // red-black tree representing map + typedef _Rb_tree<key_type, value_type, + _Select1st<value_type>, key_compare, _Alloc> _Rep_type; + _Rep_type _M_t; // red-black tree representing map public: - typedef typename rep_type::pointer pointer; - typedef typename rep_type::const_pointer const_pointer; - typedef typename rep_type::reference reference; - typedef typename rep_type::const_reference const_reference; - typedef typename rep_type::iterator iterator; - typedef typename rep_type::const_iterator const_iterator; - typedef typename rep_type::reverse_iterator reverse_iterator; - typedef typename rep_type::const_reverse_iterator const_reverse_iterator; - typedef typename rep_type::size_type size_type; - typedef typename rep_type::difference_type difference_type; + typedef typename _Rep_type::pointer pointer; + typedef typename _Rep_type::const_pointer const_pointer; + typedef typename _Rep_type::reference reference; + typedef typename _Rep_type::const_reference const_reference; + typedef typename _Rep_type::iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + typedef typename _Rep_type::allocator_type allocator_type; // allocation/deallocation - map() : t(Compare()) {} - explicit map(const Compare& comp) : t(comp) {} + map() : _M_t(_Compare(), allocator_type()) {} + explicit map(const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) {} #ifdef __STL_MEMBER_TEMPLATES - template <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); } + template <class _InputIterator> + map(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_unique(__first, __last); } + + template <class _InputIterator> + map(_InputIterator __first, _InputIterator __last, const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); } #else - map(const value_type* first, const value_type* last) - : t(Compare()) { t.insert_unique(first, last); } - map(const value_type* first, const value_type* last, const Compare& comp) - : t(comp) { t.insert_unique(first, last); } - - map(const_iterator first, const_iterator last) - : t(Compare()) { t.insert_unique(first, last); } - map(const_iterator first, const_iterator last, const Compare& comp) - : t(comp) { t.insert_unique(first, last); } + map(const value_type* __first, const value_type* __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_unique(__first, __last); } + + map(const value_type* __first, + const value_type* __last, const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); } + + map(const_iterator __first, const_iterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_unique(__first, __last); } + + map(const_iterator __first, const_iterator __last, const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); } + #endif /* __STL_MEMBER_TEMPLATES */ - map(const map<Key, T, Compare, Alloc>& x) : t(x.t) {} - map<Key, T, Compare, Alloc>& operator=(const map<Key, T, Compare, Alloc>& x) + map(const map<_Key,_Tp,_Compare,_Alloc>& __x) : _M_t(__x._M_t) {} + map<_Key,_Tp,_Compare,_Alloc>& + operator=(const map<_Key, _Tp, _Compare, _Alloc>& __x) { - t = x.t; + _M_t = __x._M_t; return *this; } // accessors: - key_compare key_comp() const { return t.key_comp(); } - value_compare value_comp() const { return value_compare(t.key_comp()); } - iterator begin() { return t.begin(); } - const_iterator begin() const { return t.begin(); } - iterator end() { return t.end(); } - const_iterator end() const { return t.end(); } - reverse_iterator rbegin() { return t.rbegin(); } - const_reverse_iterator rbegin() const { return t.rbegin(); } - reverse_iterator rend() { return t.rend(); } - const_reverse_iterator rend() const { return t.rend(); } - bool empty() const { return t.empty(); } - size_type size() const { return t.size(); } - size_type max_size() const { return t.max_size(); } - T& operator[](const key_type& k) { - return (*((insert(value_type(k, T()))).first)).second; + key_compare key_comp() const { return _M_t.key_comp(); } + value_compare value_comp() const { return value_compare(_M_t.key_comp()); } + allocator_type get_allocator() const { return _M_t.get_allocator(); } + + iterator begin() { return _M_t.begin(); } + const_iterator begin() const { return _M_t.begin(); } + iterator end() { return _M_t.end(); } + const_iterator end() const { return _M_t.end(); } + reverse_iterator rbegin() { return _M_t.rbegin(); } + const_reverse_iterator rbegin() const { return _M_t.rbegin(); } + reverse_iterator rend() { return _M_t.rend(); } + const_reverse_iterator rend() const { return _M_t.rend(); } + bool empty() const { return _M_t.empty(); } + size_type size() const { return _M_t.size(); } + size_type max_size() const { return _M_t.max_size(); } + _Tp& operator[](const key_type& __k) { + iterator __i = lower_bound(__k); + // __i->first is greater than or equivalent to __k. + if (__i == end() || key_comp()(__k, (*__i).first)) + __i = insert(__i, value_type(__k, _Tp())); + return (*__i).second; } - void swap(map<Key, T, Compare, Alloc>& x) { t.swap(x.t); } + void swap(map<_Key,_Tp,_Compare,_Alloc>& __x) { _M_t.swap(__x._M_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); - } + pair<iterator,bool> insert(const value_type& __x) + { return _M_t.insert_unique(__x); } + iterator insert(iterator position, const value_type& __x) + { return _M_t.insert_unique(position, __x); } #ifdef __STL_MEMBER_TEMPLATES - template <class InputIterator> - void insert(InputIterator first, InputIterator last) { - t.insert_unique(first, last); + template <class _InputIterator> + void insert(_InputIterator __first, _InputIterator __last) { + _M_t.insert_unique(__first, __last); } #else - void insert(const value_type* first, const value_type* last) { - t.insert_unique(first, last); + void insert(const value_type* __first, const value_type* __last) { + _M_t.insert_unique(__first, __last); } - void insert(const_iterator first, const_iterator last) { - t.insert_unique(first, last); + void insert(const_iterator __first, const_iterator __last) { + _M_t.insert_unique(__first, __last); } #endif /* __STL_MEMBER_TEMPLATES */ - void erase(iterator position) { t.erase(position); } - size_type erase(const key_type& x) { return t.erase(x); } - void erase(iterator first, iterator last) { t.erase(first, last); } - void clear() { t.clear(); } + void erase(iterator __position) { _M_t.erase(__position); } + size_type erase(const key_type& __x) { return _M_t.erase(__x); } + void erase(iterator __first, iterator __last) + { _M_t.erase(__first, __last); } + void clear() { _M_t.clear(); } // map operations: - iterator find(const key_type& x) { return t.find(x); } - const_iterator find(const key_type& x) const { return t.find(x); } - size_type count(const key_type& x) const { return t.count(x); } - iterator lower_bound(const key_type& x) {return t.lower_bound(x); } - const_iterator lower_bound(const key_type& x) const { - return t.lower_bound(x); + iterator find(const key_type& __x) { return _M_t.find(__x); } + const_iterator find(const key_type& __x) const { return _M_t.find(__x); } + size_type count(const key_type& __x) const { return _M_t.count(__x); } + iterator lower_bound(const key_type& __x) {return _M_t.lower_bound(__x); } + const_iterator lower_bound(const key_type& __x) const { + return _M_t.lower_bound(__x); } - iterator upper_bound(const key_type& x) {return t.upper_bound(x); } - const_iterator upper_bound(const key_type& x) const { - return t.upper_bound(x); + iterator upper_bound(const key_type& __x) {return _M_t.upper_bound(__x); } + const_iterator upper_bound(const key_type& __x) const { + return _M_t.upper_bound(__x); } - pair<iterator,iterator> equal_range(const key_type& x) { - return t.equal_range(x); + pair<iterator,iterator> equal_range(const key_type& __x) { + return _M_t.equal_range(__x); } - pair<const_iterator,const_iterator> equal_range(const key_type& x) const { - return t.equal_range(x); + pair<const_iterator,const_iterator> equal_range(const key_type& __x) const { + return _M_t.equal_range(__x); } friend bool operator== __STL_NULL_TMPL_ARGS (const map&, const map&); friend bool operator< __STL_NULL_TMPL_ARGS (const map&, const map&); }; -template <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 _Tp, class _Compare, class _Alloc> +inline bool operator==(const map<_Key,_Tp,_Compare,_Alloc>& __x, + const map<_Key,_Tp,_Compare,_Alloc>& __y) { + return __x._M_t == __y._M_t; } -template <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 _Tp, class _Compare, class _Alloc> +inline bool operator<(const map<_Key,_Tp,_Compare,_Alloc>& __x, + const map<_Key,_Tp,_Compare,_Alloc>& __y) { + return __x._M_t < __y._M_t; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER -template <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); +template <class _Key, class _Tp, class _Compare, class _Alloc> +inline void swap(map<_Key,_Tp,_Compare,_Alloc>& __x, + map<_Key,_Tp,_Compare,_Alloc>& __y) { + __x.swap(__y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 +#pragma reset woff 1375 #endif __STL_END_NAMESPACE diff --git a/contrib/libstdc++/stl/stl_multimap.h b/contrib/libstdc++/stl/stl_multimap.h index b82159b..b7d3b87 100644 --- a/contrib/libstdc++/stl/stl_multimap.h +++ b/contrib/libstdc++/stl/stl_multimap.h @@ -35,143 +35,160 @@ __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 +#pragma set woff 1375 #endif #ifndef __STL_LIMITED_DEFAULT_TEMPLATES -template <class Key, class T, class Compare = less<Key>, class Alloc = alloc> +template <class _Key, class _Tp, class _Compare = less<_Key>, + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) > #else -template <class Key, class T, class Compare, class Alloc = alloc> +template <class _Key, class _Tp, class _Compare, + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) > #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; + typedef _Key key_type; + typedef _Tp data_type; + typedef _Tp mapped_type; + typedef pair<const _Key, _Tp> value_type; + typedef _Compare key_compare; class value_compare : public binary_function<value_type, value_type, bool> { - friend class multimap<Key, T, Compare, Alloc>; + friend class multimap<_Key,_Tp,_Compare,_Alloc>; protected: - Compare comp; - value_compare(Compare c) : comp(c) {} + _Compare _M_comp; + value_compare(_Compare __c) : _M_comp(__c) {} public: - bool operator()(const value_type& x, const value_type& y) const { - return comp(x.first, y.first); + bool operator()(const value_type& __x, const value_type& __y) const { + return _M_comp(__x.first, __y.first); } }; private: - typedef rb_tree<key_type, value_type, - select1st<value_type>, key_compare, Alloc> rep_type; - rep_type t; // red-black tree representing multimap + typedef _Rb_tree<key_type, value_type, + _Select1st<value_type>, key_compare, _Alloc> _Rep_type; + _Rep_type _M_t; // red-black tree representing multimap public: - typedef typename rep_type::pointer pointer; - typedef typename rep_type::const_pointer const_pointer; - typedef typename rep_type::reference reference; - typedef typename rep_type::const_reference const_reference; - typedef typename rep_type::iterator iterator; - typedef typename rep_type::const_iterator const_iterator; - typedef typename rep_type::reverse_iterator reverse_iterator; - typedef typename rep_type::const_reverse_iterator const_reverse_iterator; - typedef typename rep_type::size_type size_type; - typedef typename rep_type::difference_type difference_type; + typedef typename _Rep_type::pointer pointer; + typedef typename _Rep_type::const_pointer const_pointer; + typedef typename _Rep_type::reference reference; + typedef typename _Rep_type::const_reference const_reference; + typedef typename _Rep_type::iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + typedef typename _Rep_type::allocator_type allocator_type; // allocation/deallocation - multimap() : t(Compare()) { } - explicit multimap(const Compare& comp) : t(comp) { } + multimap() : _M_t(_Compare(), allocator_type()) { } + explicit multimap(const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { } #ifdef __STL_MEMBER_TEMPLATES - template <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); } + template <class _InputIterator> + multimap(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_equal(__first, __last); } + + template <class _InputIterator> + multimap(_InputIterator __first, _InputIterator __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); } #else - multimap(const value_type* first, const value_type* last) - : t(Compare()) { t.insert_equal(first, last); } - multimap(const value_type* first, const value_type* last, - const Compare& comp) - : t(comp) { t.insert_equal(first, last); } - - multimap(const_iterator first, const_iterator last) - : t(Compare()) { t.insert_equal(first, last); } - multimap(const_iterator first, const_iterator last, const Compare& comp) - : t(comp) { t.insert_equal(first, last); } + multimap(const value_type* __first, const value_type* __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_equal(__first, __last); } + multimap(const value_type* __first, const value_type* __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); } + + multimap(const_iterator __first, const_iterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_equal(__first, __last); } + multimap(const_iterator __first, const_iterator __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); } #endif /* __STL_MEMBER_TEMPLATES */ - multimap(const multimap<Key, T, Compare, Alloc>& x) : t(x.t) { } - multimap<Key, T, Compare, Alloc>& - operator=(const multimap<Key, T, Compare, Alloc>& x) { - t = x.t; + multimap(const multimap<_Key,_Tp,_Compare,_Alloc>& __x) : _M_t(__x._M_t) { } + multimap<_Key,_Tp,_Compare,_Alloc>& + operator=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x) { + _M_t = __x._M_t; return *this; } // accessors: - key_compare key_comp() const { return t.key_comp(); } - value_compare value_comp() const { return value_compare(t.key_comp()); } - iterator begin() { return t.begin(); } - const_iterator begin() const { return t.begin(); } - iterator end() { return t.end(); } - const_iterator end() const { return t.end(); } - reverse_iterator rbegin() { return t.rbegin(); } - const_reverse_iterator rbegin() const { return t.rbegin(); } - reverse_iterator rend() { return t.rend(); } - const_reverse_iterator rend() const { return t.rend(); } - bool empty() const { return t.empty(); } - size_type size() const { return t.size(); } - size_type max_size() const { return t.max_size(); } - void swap(multimap<Key, T, Compare, Alloc>& x) { t.swap(x.t); } + key_compare key_comp() const { return _M_t.key_comp(); } + value_compare value_comp() const { return value_compare(_M_t.key_comp()); } + allocator_type get_allocator() const { return _M_t.get_allocator(); } + + iterator begin() { return _M_t.begin(); } + const_iterator begin() const { return _M_t.begin(); } + iterator end() { return _M_t.end(); } + const_iterator end() const { return _M_t.end(); } + reverse_iterator rbegin() { return _M_t.rbegin(); } + const_reverse_iterator rbegin() const { return _M_t.rbegin(); } + reverse_iterator rend() { return _M_t.rend(); } + const_reverse_iterator rend() const { return _M_t.rend(); } + bool empty() const { return _M_t.empty(); } + size_type size() const { return _M_t.size(); } + size_type max_size() const { return _M_t.max_size(); } + void swap(multimap<_Key,_Tp,_Compare,_Alloc>& __x) { _M_t.swap(__x._M_t); } // insert/erase - iterator insert(const value_type& x) { return t.insert_equal(x); } - iterator insert(iterator position, const value_type& x) { - return t.insert_equal(position, x); + iterator insert(const value_type& __x) { return _M_t.insert_equal(__x); } + iterator insert(iterator __position, const value_type& __x) { + return _M_t.insert_equal(__position, __x); } #ifdef __STL_MEMBER_TEMPLATES - template <class InputIterator> - void insert(InputIterator first, InputIterator last) { - t.insert_equal(first, last); + template <class _InputIterator> + void insert(_InputIterator __first, _InputIterator __last) { + _M_t.insert_equal(__first, __last); } #else - void insert(const value_type* first, const value_type* last) { - t.insert_equal(first, last); + void insert(const value_type* __first, const value_type* __last) { + _M_t.insert_equal(__first, __last); } - void insert(const_iterator first, const_iterator last) { - t.insert_equal(first, last); + void insert(const_iterator __first, const_iterator __last) { + _M_t.insert_equal(__first, __last); } #endif /* __STL_MEMBER_TEMPLATES */ - void erase(iterator position) { t.erase(position); } - size_type erase(const key_type& x) { return t.erase(x); } - void erase(iterator first, iterator last) { t.erase(first, last); } - void clear() { t.clear(); } + void erase(iterator __position) { _M_t.erase(__position); } + size_type erase(const key_type& __x) { return _M_t.erase(__x); } + void erase(iterator __first, iterator __last) + { _M_t.erase(__first, __last); } + void clear() { _M_t.clear(); } // multimap operations: - iterator find(const key_type& x) { return t.find(x); } - const_iterator find(const key_type& x) const { return t.find(x); } - size_type count(const key_type& x) const { return t.count(x); } - iterator lower_bound(const key_type& x) {return t.lower_bound(x); } - const_iterator lower_bound(const key_type& x) const { - return t.lower_bound(x); + iterator find(const key_type& __x) { return _M_t.find(__x); } + const_iterator find(const key_type& __x) const { return _M_t.find(__x); } + size_type count(const key_type& __x) const { return _M_t.count(__x); } + iterator lower_bound(const key_type& __x) {return _M_t.lower_bound(__x); } + const_iterator lower_bound(const key_type& __x) const { + return _M_t.lower_bound(__x); } - iterator upper_bound(const key_type& x) {return t.upper_bound(x); } - const_iterator upper_bound(const key_type& x) const { - return t.upper_bound(x); + iterator upper_bound(const key_type& __x) {return _M_t.upper_bound(__x); } + const_iterator upper_bound(const key_type& __x) const { + return _M_t.upper_bound(__x); } - pair<iterator,iterator> equal_range(const key_type& x) { - return t.equal_range(x); + pair<iterator,iterator> equal_range(const key_type& __x) { + return _M_t.equal_range(__x); } - pair<const_iterator,const_iterator> equal_range(const key_type& x) const { - return t.equal_range(x); + pair<const_iterator,const_iterator> equal_range(const key_type& __x) const { + return _M_t.equal_range(__x); } friend bool operator== __STL_NULL_TMPL_ARGS (const multimap&, const multimap&); @@ -179,30 +196,31 @@ public: const multimap&); }; -template <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 _Tp, class _Compare, class _Alloc> +inline bool operator==(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y) { + return __x._M_t == __y._M_t; } -template <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 _Tp, class _Compare, class _Alloc> +inline bool operator<(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y) { + return __x._M_t < __y._M_t; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER -template <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); +template <class _Key, class _Tp, class _Compare, class _Alloc> +inline void swap(multimap<_Key,_Tp,_Compare,_Alloc>& __x, + multimap<_Key,_Tp,_Compare,_Alloc>& __y) { + __x.swap(__y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 +#pragma reset woff 1375 #endif __STL_END_NAMESPACE diff --git a/contrib/libstdc++/stl/stl_multiset.h b/contrib/libstdc++/stl/stl_multiset.h index ff5947e..7378e43 100644 --- a/contrib/libstdc++/stl/stl_multiset.h +++ b/contrib/libstdc++/stl/stl_multiset.h @@ -35,129 +35,152 @@ __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 +#pragma set woff 1375 #endif #ifndef __STL_LIMITED_DEFAULT_TEMPLATES -template <class Key, class Compare = less<Key>, class Alloc = alloc> +template <class _Key, class _Compare = less<_Key>, + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Key) > #else -template <class Key, class Compare, class Alloc = alloc> +template <class _Key, class _Compare, + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Key) > #endif class multiset { public: // typedefs: - typedef Key key_type; - typedef Key value_type; - typedef Compare key_compare; - typedef Compare value_compare; + typedef _Key key_type; + typedef _Key value_type; + typedef _Compare key_compare; + typedef _Compare value_compare; private: - typedef rb_tree<key_type, value_type, - identity<value_type>, key_compare, Alloc> rep_type; - rep_type t; // red-black tree representing multiset + typedef _Rb_tree<key_type, value_type, + _Identity<value_type>, key_compare, _Alloc> _Rep_type; + _Rep_type _M_t; // red-black tree representing multiset public: - typedef typename rep_type::const_pointer pointer; - typedef typename rep_type::const_pointer const_pointer; - typedef typename rep_type::const_reference reference; - typedef typename rep_type::const_reference const_reference; - typedef typename rep_type::const_iterator iterator; - typedef typename rep_type::const_iterator const_iterator; - typedef typename rep_type::const_reverse_iterator reverse_iterator; - typedef typename rep_type::const_reverse_iterator const_reverse_iterator; - typedef typename rep_type::size_type size_type; - typedef typename rep_type::difference_type difference_type; + typedef typename _Rep_type::const_pointer pointer; + typedef typename _Rep_type::const_pointer const_pointer; + typedef typename _Rep_type::const_reference reference; + typedef typename _Rep_type::const_reference const_reference; + typedef typename _Rep_type::const_iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::const_reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + typedef typename _Rep_type::allocator_type allocator_type; // allocation/deallocation - multiset() : t(Compare()) {} - explicit multiset(const Compare& comp) : t(comp) {} + multiset() : _M_t(_Compare(), allocator_type()) {} + explicit multiset(const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) {} #ifdef __STL_MEMBER_TEMPLATES - template <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); } + + template <class _InputIterator> + multiset(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_equal(__first, __last); } + + template <class _InputIterator> + multiset(_InputIterator __first, _InputIterator __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); } + #else - multiset(const value_type* first, const value_type* last) - : t(Compare()) { t.insert_equal(first, last); } - multiset(const value_type* first, const value_type* last, - const Compare& comp) - : t(comp) { t.insert_equal(first, last); } - - multiset(const_iterator first, const_iterator last) - : t(Compare()) { t.insert_equal(first, last); } - multiset(const_iterator first, const_iterator last, const Compare& comp) - : t(comp) { t.insert_equal(first, last); } + + multiset(const value_type* __first, const value_type* __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_equal(__first, __last); } + + multiset(const value_type* __first, const value_type* __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); } + + multiset(const_iterator __first, const_iterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_equal(__first, __last); } + + multiset(const_iterator __first, const_iterator __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); } + #endif /* __STL_MEMBER_TEMPLATES */ - multiset(const multiset<Key, Compare, Alloc>& x) : t(x.t) {} - multiset<Key, Compare, Alloc>& - operator=(const multiset<Key, Compare, Alloc>& x) { - t = x.t; + multiset(const multiset<_Key,_Compare,_Alloc>& __x) : _M_t(__x._M_t) {} + multiset<_Key,_Compare,_Alloc>& + operator=(const multiset<_Key,_Compare,_Alloc>& __x) { + _M_t = __x._M_t; return *this; } // accessors: - key_compare key_comp() const { return t.key_comp(); } - value_compare value_comp() const { return t.key_comp(); } - iterator begin() const { return t.begin(); } - iterator end() const { return t.end(); } - reverse_iterator rbegin() const { return t.rbegin(); } - reverse_iterator rend() const { return t.rend(); } - bool empty() const { return t.empty(); } - size_type size() const { return t.size(); } - size_type max_size() const { return t.max_size(); } - void swap(multiset<Key, Compare, Alloc>& x) { t.swap(x.t); } + key_compare key_comp() const { return _M_t.key_comp(); } + value_compare value_comp() const { return _M_t.key_comp(); } + allocator_type get_allocator() const { return _M_t.get_allocator(); } + + iterator begin() const { return _M_t.begin(); } + iterator end() const { return _M_t.end(); } + reverse_iterator rbegin() const { return _M_t.rbegin(); } + reverse_iterator rend() const { return _M_t.rend(); } + bool empty() const { return _M_t.empty(); } + size_type size() const { return _M_t.size(); } + size_type max_size() const { return _M_t.max_size(); } + void swap(multiset<_Key,_Compare,_Alloc>& __x) { _M_t.swap(__x._M_t); } // insert/erase - iterator insert(const value_type& x) { - return t.insert_equal(x); + iterator insert(const value_type& __x) { + return _M_t.insert_equal(__x); } - iterator insert(iterator position, const value_type& x) { - typedef typename rep_type::iterator rep_iterator; - return t.insert_equal((rep_iterator&)position, x); + iterator insert(iterator __position, const value_type& __x) { + typedef typename _Rep_type::iterator _Rep_iterator; + return _M_t.insert_equal((_Rep_iterator&)__position, __x); } #ifdef __STL_MEMBER_TEMPLATES - template <class InputIterator> - void insert(InputIterator first, InputIterator last) { - t.insert_equal(first, last); + template <class _InputIterator> + void insert(_InputIterator __first, _InputIterator __last) { + _M_t.insert_equal(__first, __last); } #else - void insert(const value_type* first, const value_type* last) { - t.insert_equal(first, last); + void insert(const value_type* __first, const value_type* __last) { + _M_t.insert_equal(__first, __last); } - void insert(const_iterator first, const_iterator last) { - t.insert_equal(first, last); + void insert(const_iterator __first, const_iterator __last) { + _M_t.insert_equal(__first, __last); } #endif /* __STL_MEMBER_TEMPLATES */ - void erase(iterator position) { - typedef typename rep_type::iterator rep_iterator; - t.erase((rep_iterator&)position); + void erase(iterator __position) { + typedef typename _Rep_type::iterator _Rep_iterator; + _M_t.erase((_Rep_iterator&)__position); } - size_type erase(const key_type& x) { - return t.erase(x); + size_type erase(const key_type& __x) { + return _M_t.erase(__x); } - void erase(iterator first, iterator last) { - typedef typename rep_type::iterator rep_iterator; - t.erase((rep_iterator&)first, (rep_iterator&)last); + void erase(iterator __first, iterator __last) { + typedef typename _Rep_type::iterator _Rep_iterator; + _M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last); } - void clear() { t.clear(); } + void clear() { _M_t.clear(); } // multiset operations: - iterator find(const key_type& x) const { return t.find(x); } - size_type count(const key_type& x) const { return t.count(x); } - iterator lower_bound(const key_type& x) const { - return t.lower_bound(x); + iterator find(const key_type& __x) const { return _M_t.find(__x); } + size_type count(const key_type& __x) const { return _M_t.count(__x); } + iterator lower_bound(const key_type& __x) const { + return _M_t.lower_bound(__x); } - iterator upper_bound(const key_type& x) const { - return t.upper_bound(x); + iterator upper_bound(const key_type& __x) const { + return _M_t.upper_bound(__x); } - pair<iterator,iterator> equal_range(const key_type& x) const { - return t.equal_range(x); + pair<iterator,iterator> equal_range(const key_type& __x) const { + return _M_t.equal_range(__x); } friend bool operator== __STL_NULL_TMPL_ARGS (const multiset&, const multiset&); @@ -165,30 +188,31 @@ public: const multiset&); }; -template <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._M_t == __y._M_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; +template <class _Key, class _Compare, class _Alloc> +inline bool operator<(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y) { + return __x._M_t < __y._M_t; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER -template <class Key, class Compare, class Alloc> -inline void swap(multiset<Key, Compare, Alloc>& x, - multiset<Key, Compare, Alloc>& y) { - x.swap(y); +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 +#pragma reset woff 1375 #endif __STL_END_NAMESPACE diff --git a/contrib/libstdc++/stl/stl_numeric.h b/contrib/libstdc++/stl/stl_numeric.h index 57fee2b..392515a 100644 --- a/contrib/libstdc++/stl/stl_numeric.h +++ b/contrib/libstdc++/stl/stl_numeric.h @@ -34,157 +34,200 @@ __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; +template <class _InputIterator, class _Tp> +_Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init) +{ + for ( ; __first != __last; ++__first) + __init = __init + *__first; + return __init; +} + +template <class _InputIterator, class _Tp, class _BinaryOperation> +_Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init, + _BinaryOperation __binary_op) +{ + for ( ; __first != __last; ++__first) + __init = __binary_op(__init, *__first); + return __init; +} + +template <class _InputIterator1, class _InputIterator2, class _Tp> +_Tp inner_product(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _Tp __init) +{ + for ( ; __first1 != __last1; ++__first1, ++__first2) + __init = __init + (*__first1 * *__first2); + return __init; +} + +template <class _InputIterator1, class _InputIterator2, class _Tp, + class _BinaryOperation1, class _BinaryOperation2> +_Tp inner_product(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _Tp __init, + _BinaryOperation1 __binary_op1, + _BinaryOperation2 __binary_op2) +{ + for ( ; __first1 != __last1; ++__first1, ++__first2) + __init = __binary_op1(__init, __binary_op2(*__first1, *__first2)); + return __init; +} + +template <class _InputIterator, class _OutputIterator, class _Tp> +_OutputIterator +__partial_sum(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _Tp*) +{ + _Tp __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> +_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 _Tp, + class _BinaryOperation> +_OutputIterator +__partial_sum(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _Tp*, _BinaryOperation __binary_op) +{ + _Tp __value = *__first; + while (++__first != __last) { + __value = __binary_op(__value, *__first); + *++__result = __value; } - return ++result; + return ++__result; } -template <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 _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; +template <class _InputIterator, class _OutputIterator, class _Tp> +_OutputIterator +__adjacent_difference(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _Tp*) +{ + _Tp __value = *__first; + while (++__first != __last) { + _Tp __tmp = *__first; + *++__result = __tmp - __value; + __value = __tmp; } - return ++result; -} - -template <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> +_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 _Tp, + class _BinaryOperation> +_OutputIterator +__adjacent_difference(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _Tp*, + _BinaryOperation __binary_op) { + _Tp __value = *__first; + while (++__first != __last) { + _Tp __tmp = *__first; + *++__result = __binary_op(__tmp, __value); + __value = __tmp; } - return ++result; -} - -template <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); + 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 _Tp, class _Integer, class _MonoidOperation> +_Tp __power(_Tp __x, _Integer __n, _MonoidOperation __oper) +{ + if (__n == 0) + return identity_element(__oper); else { - while ((n & 1) == 0) { - n >>= 1; - x = op(x, x); + while ((__n & 1) == 0) { + __n >>= 1; + __x = __oper(__x, __x); } - T result = x; - n >>= 1; - while (n != 0) { - x = op(x, x); - if ((n & 1) != 0) - result = op(result, x); - n >>= 1; + _Tp __result = __x; + __n >>= 1; + while (__n != 0) { + __x = __oper(__x, __x); + if ((__n & 1) != 0) + __result = __oper(__result, __x); + __n >>= 1; } - return result; + return __result; } } -template <class T, class Integer> -inline T power(T x, Integer n) { - return power(x, n, multiplies<T>()); +template <class _Tp, class _Integer> +inline _Tp __power(_Tp __x, _Integer __n) +{ + return __power(__x, __n, multiplies<_Tp>()); +} + +// Alias for the internal name __power. Note that power is an extension, +// not part of the C++ standard. + +template <class _Tp, class _Integer, class _MonoidOperation> +inline _Tp power(_Tp __x, _Integer __n, _MonoidOperation __oper) +{ + return __power(__x, __n, __oper); +} + +template <class _Tp, class _Integer> +inline _Tp power(_Tp __x, _Integer __n) +{ + return __power(__x, __n); } +// iota is not part of the C++ standard. It is an extension. -template <class ForwardIterator, class T> -void iota(ForwardIterator first, ForwardIterator last, T value) { - while (first != last) *first++ = value++; +template <class _ForwardIterator, class _Tp> +void +iota(_ForwardIterator __first, _ForwardIterator __last, _Tp __value) +{ + while (__first != __last) + *__first++ = __value++; } __STL_END_NAMESPACE diff --git a/contrib/libstdc++/stl/stl_pair.h b/contrib/libstdc++/stl/stl_pair.h index 10a9cb0..3aa290b 100644 --- a/contrib/libstdc++/stl/stl_pair.h +++ b/contrib/libstdc++/stl/stl_pair.h @@ -33,35 +33,39 @@ __STL_BEGIN_NAMESPACE -template <class T1, class T2> +template <class _T1, class _T2> struct pair { - typedef T1 first_type; - typedef T2 second_type; + typedef _T1 first_type; + typedef _T2 second_type; - T1 first; - T2 second; - pair() : first(T1()), second(T2()) {} - pair(const T1& a, const T2& b) : first(a), second(b) {} + _T1 first; + _T2 second; + pair() : first(_T1()), second(_T2()) {} + pair(const _T1& __a, const _T2& __b) : first(__a), second(__b) {} #ifdef __STL_MEMBER_TEMPLATES - template <class U1, class U2> - pair(const pair<U1, U2>& p) : first(p.first), second(p.second) {} + 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 && __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 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); +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 diff --git a/contrib/libstdc++/stl/stl_queue.h b/contrib/libstdc++/stl/stl_queue.h index ff6eede..c1e2b69 100644 --- a/contrib/libstdc++/stl/stl_queue.h +++ b/contrib/libstdc++/stl/stl_queue.h @@ -34,82 +34,150 @@ __STL_BEGIN_NAMESPACE #ifndef __STL_LIMITED_DEFAULT_TEMPLATES -template <class T, class Sequence = deque<T> > +template <class _Tp, class _Sequence = deque<_Tp> > #else -template <class T, class Sequence> +template <class _Tp, 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); + friend bool operator== __STL_NULL_TMPL_ARGS (const queue&, const queue&); + friend bool operator< __STL_NULL_TMPL_ARGS (const queue&, const queue&); public: - typedef typename Sequence::value_type value_type; - typedef typename Sequence::size_type size_type; - typedef typename Sequence::reference reference; - typedef typename Sequence::const_reference const_reference; + typedef typename _Sequence::value_type value_type; + typedef typename _Sequence::size_type size_type; + typedef _Sequence container_type; + + typedef typename _Sequence::reference reference; + typedef typename _Sequence::const_reference const_reference; protected: - Sequence c; + _Sequence c; public: + queue() : c() {} + explicit queue(const _Sequence& __c) : c(__c) {} + bool empty() const { return c.empty(); } size_type size() const { return c.size(); } reference front() { return c.front(); } const_reference front() const { return c.front(); } reference back() { return c.back(); } const_reference back() const { return c.back(); } - void push(const value_type& x) { c.push_back(x); } + void 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 _Tp, class _Sequence> +bool +operator==(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) +{ + return __x.c == __y.c; +} + +template <class _Tp, class _Sequence> +bool +operator<(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) +{ + return __x.c < __y.c; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template <class _Tp, class _Sequence> +bool +operator!=(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) +{ + return !(__x == __y); +} + +template <class _Tp, class _Sequence> +bool +operator>(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) +{ + return __y < __x; +} + +template <class _Tp, class _Sequence> +bool +operator<=(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) +{ + return !(__y < __x); } -template <class T, class Sequence> -bool operator<(const queue<T, Sequence>& x, const queue<T, Sequence>& y) { - return x.c < y.c; +template <class _Tp, class _Sequence> +bool +operator>=(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) +{ + return !(__x < __y); } +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + #ifndef __STL_LIMITED_DEFAULT_TEMPLATES -template <class T, class Sequence = vector<T>, - class Compare = less<typename Sequence::value_type> > +template <class _Tp, class _Sequence = vector<_Tp>, + class _Compare = less<typename _Sequence::value_type> > #else -template <class T, class Sequence, class Compare> +template <class _Tp, 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; + typedef typename _Sequence::value_type value_type; + typedef typename _Sequence::size_type size_type; + typedef _Sequence container_type; + + typedef typename _Sequence::reference reference; + typedef typename _Sequence::const_reference const_reference; protected: - Sequence c; - Compare comp; + _Sequence c; + _Compare comp; public: priority_queue() : c() {} - explicit priority_queue(const Compare& x) : c(), comp(x) {} + explicit priority_queue(const _Compare& __x) : c(), comp(__x) {} + priority_queue(const _Compare& __x, const _Sequence& __s) + : c(__s), comp(__x) + { make_heap(c.begin(), c.end(), comp); } #ifdef __STL_MEMBER_TEMPLATES - template <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); } + template <class _InputIterator> + priority_queue(_InputIterator __first, _InputIterator __last) + : c(__first, __last) { make_heap(c.begin(), c.end(), comp); } + + 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, + const _Compare& __x, const _Sequence& __s) + : c(__s), comp(__x) + { + c.insert(c.end(), __first, __last); + make_heap(c.begin(), c.end(), comp); + } + #else /* __STL_MEMBER_TEMPLATES */ - priority_queue(const value_type* first, const value_type* last, - const Compare& x) : c(first, last), comp(x) { + priority_queue(const value_type* __first, const value_type* __last) + : c(__first, __last) { make_heap(c.begin(), c.end(), comp); } + + priority_queue(const value_type* __first, const value_type* __last, + const _Compare& __x) + : c(__first, __last), comp(__x) + { make_heap(c.begin(), c.end(), comp); } + + priority_queue(const value_type* __first, const value_type* __last, + const _Compare& __x, const _Sequence& __c) + : c(__c), comp(__x) + { + c.insert(c.end(), __first, __last); make_heap(c.begin(), c.end(), comp); } - 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) { + void push(const value_type& __x) { __STL_TRY { - c.push_back(x); + c.push_back(__x); push_heap(c.begin(), c.end(), comp); } __STL_UNWIND(c.clear()); diff --git a/contrib/libstdc++/stl/stl_raw_storage_iter.h b/contrib/libstdc++/stl/stl_raw_storage_iter.h index 5d3d074..6f3951c 100644 --- a/contrib/libstdc++/stl/stl_raw_storage_iter.h +++ b/contrib/libstdc++/stl/stl_raw_storage_iter.h @@ -25,7 +25,7 @@ */ /* NOTE: This is an internal header file, included by other STL headers. - * You should not attempt to use it directly. + * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_RAW_STORAGE_ITERATOR_H @@ -33,10 +33,10 @@ __STL_BEGIN_NAMESPACE -template <class ForwardIterator, class T> +template <class _ForwardIterator, class _Tp> class raw_storage_iterator { protected: - ForwardIterator iter; + _ForwardIterator _M_iter; public: typedef output_iterator_tag iterator_category; typedef void value_type; @@ -44,38 +44,38 @@ public: typedef void pointer; typedef void reference; - explicit raw_storage_iterator(ForwardIterator x) : iter(x) {} - raw_storage_iterator<ForwardIterator, T>& operator*() { return *this; } - raw_storage_iterator<ForwardIterator, T>& operator=(const T& element) { - construct(&*iter, element); + explicit raw_storage_iterator(_ForwardIterator __x) : _M_iter(__x) {} + raw_storage_iterator& operator*() { return *this; } + raw_storage_iterator& operator=(const _Tp& __element) { + construct(&*_M_iter, __element); return *this; } - raw_storage_iterator<ForwardIterator, T>& operator++() { - ++iter; + raw_storage_iterator<_ForwardIterator, _Tp>& operator++() { + ++_M_iter; return *this; } - raw_storage_iterator<ForwardIterator, T> operator++(int) { - raw_storage_iterator<ForwardIterator, T> tmp = *this; - ++iter; - return tmp; + raw_storage_iterator<_ForwardIterator, _Tp> operator++(int) { + raw_storage_iterator<_ForwardIterator, _Tp> __tmp = *this; + ++_M_iter; + return __tmp; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION -template <class ForwardIterator, class T> +template <class _ForwardIterator, class _Tp> inline output_iterator_tag -iterator_category(const raw_storage_iterator<ForwardIterator, T>&) +iterator_category(const raw_storage_iterator<_ForwardIterator, _Tp>&) { return output_iterator_tag(); } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ -#endif /* __SGI_STL_INTERNAL_RAW_STORAGE_ITERATOR_H */ - __STL_END_NAMESPACE +#endif /* __SGI_STL_INTERNAL_RAW_STORAGE_ITERATOR_H */ + // Local Variables: // mode:C++ // End: diff --git a/contrib/libstdc++/stl/stl_relops.h b/contrib/libstdc++/stl/stl_relops.h index 01a0c7c..16cad1b 100644 --- a/contrib/libstdc++/stl/stl_relops.h +++ b/contrib/libstdc++/stl/stl_relops.h @@ -33,24 +33,24 @@ __STL_BEGIN_RELOPS_NAMESPACE -template <class T> -inline bool operator!=(const T& x, const T& y) { - return !(x == y); +template <class _Tp> +inline bool operator!=(const _Tp& __x, const _Tp& __y) { + return !(__x == __y); } -template <class T> -inline bool operator>(const T& x, const T& y) { - return y < x; +template <class _Tp> +inline bool operator>(const _Tp& __x, const _Tp& __y) { + return __y < __x; } -template <class T> -inline bool operator<=(const T& x, const T& y) { - return !(y < x); +template <class _Tp> +inline bool operator<=(const _Tp& __x, const _Tp& __y) { + return !(__y < __x); } -template <class T> -inline bool operator>=(const T& x, const T& y) { - return !(x < y); +template <class _Tp> +inline bool operator>=(const _Tp& __x, const _Tp& __y) { + return !(__x < __y); } __STL_END_RELOPS_NAMESPACE diff --git a/contrib/libstdc++/stl/stl_rope.h b/contrib/libstdc++/stl/stl_rope.h index d37c679..44f51ae 100644 --- a/contrib/libstdc++/stl/stl_rope.h +++ b/contrib/libstdc++/stl/stl_rope.h @@ -15,6 +15,12 @@ * You should not attempt to use it directly. */ +// rope<_CharT,_Alloc> is a sequence of _CharT. +// Ropes appear to be mutable, but update operations +// really copy enough of the data structure to leave the original +// valid. Thus ropes can be logically copied by just copying +// a pointer value. + #ifndef __SGI_STL_INTERNAL_ROPE_H # define __SGI_STL_INTERNAL_ROPE_H @@ -33,49 +39,47 @@ __STL_BEGIN_NAMESPACE #pragma set woff 1174 #endif +// The _S_eos function is used for those functions that +// convert to/from C-like strings to detect the end of the string. + // The end-of-C-string character. // This is what the draft standard says it should be. -template <class charT> -inline charT __eos(charT*) { return charT(); } +template <class _CharT> +inline _CharT _S_eos(_CharT*) { return _CharT(); } // Test for basic character types. // For basic character types leaves having a trailing eos. -template <class charT> -inline bool __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> +template <class _CharT> +inline bool _S_is_basic_char_type(_CharT*) { return false; } +template <class _CharT> +inline bool _S_is_one_byte_char_type(_CharT*) { return false; } + +inline bool _S_is_basic_char_type(char*) { return true; } +inline bool _S_is_one_byte_char_type(char*) { return true; } +inline bool _S_is_basic_char_type(wchar_t*) { return true; } + +// Store an eos iff _CharT is a basic character type. +// Do not reference _S_eos if it isn't. +template <class _CharT> +inline void _S_cond_store_eos(_CharT&) {} + +inline void _S_cond_store_eos(char& __c) { __c = 0; } +inline void _S_cond_store_eos(wchar_t& __c) { __c = 0; } + +// char_producers are logically functions that generate a section of +// a string. These can be convereted to ropes. The resulting rope +// invokes the char_producer on demand. This allows, for example, +// files to be viewed as ropes without reading the entire file. +template <class _CharT> class char_producer { public: - virtual ~char_producer() {}; - virtual void operator()(size_t start_pos, size_t len, charT* buffer) - = 0; - // Buffer should really be an arbitrary output iterator. - // That way we could flatten directly into an ostream, etc. - // This is thoroughly impossible, since iterator types don't - // have runtime descriptions. + virtual ~char_producer() {}; + virtual void operator()(size_t __start_pos, size_t __len, + _CharT* __buffer) = 0; + // Buffer should really be an arbitrary output iterator. + // That way we could flatten directly into an ostream, etc. + // This is thoroughly impossible, since iterator types don't + // have runtime descriptions. }; // Sequence buffers: @@ -92,111 +96,112 @@ class char_producer { // behave a little like basic_ostringstream<sequence::value_type> and a // little like containers. -template<class sequence, size_t buf_sz = 100 +template<class _Sequence, size_t _Buf_sz = 100 # if defined(__sgi) && !defined(__GNUC__) -# define __TYPEDEF_WORKAROUND - ,class v = typename sequence::value_type +# 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 + typedef typename _Sequence::value_type value_type; +# else + typedef _V value_type; +# endif protected: - sequence *prefix; - value_type buffer[buf_sz]; - size_t buf_count; + _Sequence* _M_prefix; + value_type _M_buffer[_Buf_sz]; + size_t _M_buf_count; public: - void flush() { - prefix->append(buffer, buffer + buf_count); - buf_count = 0; - } - ~sequence_buffer() { flush(); } - sequence_buffer() : prefix(0), buf_count(0) {} - sequence_buffer(const sequence_buffer & x) { - prefix = x.prefix; - buf_count = x.buf_count; - copy(x.buffer, x.buffer + x.buf_count, buffer); - } - sequence_buffer(sequence_buffer & x) { - x.flush(); - prefix = x.prefix; - buf_count = 0; - } - sequence_buffer(sequence& s) : prefix(&s), buf_count(0) {} - sequence_buffer& operator= (sequence_buffer& x) { - x.flush(); - prefix = x.prefix; - buf_count = 0; - return *this; - } - sequence_buffer& operator= (const sequence_buffer& x) { - prefix = x.prefix; - buf_count = x.buf_count; - copy(x.buffer, x.buffer + x.buf_count, buffer); - return *this; - } - void push_back(value_type x) - { - if (buf_count < buf_sz) { - buffer[buf_count] = x; - ++buf_count; - } else { - flush(); - buffer[0] = x; - buf_count = 1; - } - } - void append(value_type *s, size_t len) - { - if (len + buf_count <= buf_sz) { - size_t i, j; - for (i = buf_count, j = 0; j < len; i++, j++) { - buffer[i] = s[j]; - } - buf_count += len; - } else if (0 == buf_count) { - prefix->append(s, s + len); - } else { - flush(); - append(s, len); - } - } - sequence_buffer& write(value_type *s, size_t len) - { - append(s, len); - return *this; - } - sequence_buffer& put(value_type x) - { - push_back(x); - return *this; - } - sequence_buffer& operator=(const value_type& rhs) - { - push_back(rhs); - return *this; - } - sequence_buffer& operator*() { return *this; } - sequence_buffer& operator++() { return *this; } - sequence_buffer& operator++(int) { return *this; } + void flush() { + _M_prefix->append(_M_buffer, _M_buffer + _M_buf_count); + _M_buf_count = 0; + } + ~sequence_buffer() { flush(); } + sequence_buffer() : _M_prefix(0), _M_buf_count(0) {} + sequence_buffer(const sequence_buffer& __x) { + _M_prefix = __x._M_prefix; + _M_buf_count = __x._M_buf_count; + copy(__x._M_buffer, __x._M_buffer + __x._M_buf_count, _M_buffer); + } + sequence_buffer(sequence_buffer& __x) { + __x.flush(); + _M_prefix = __x._M_prefix; + _M_buf_count = 0; + } + sequence_buffer(_Sequence& __s) : _M_prefix(&__s), _M_buf_count(0) {} + sequence_buffer& operator= (sequence_buffer& __x) { + __x.flush(); + _M_prefix = __x._M_prefix; + _M_buf_count = 0; + return *this; + } + sequence_buffer& operator= (const sequence_buffer& __x) { + _M_prefix = __x._M_prefix; + _M_buf_count = __x._M_buf_count; + copy(__x._M_buffer, __x._M_buffer + __x._M_buf_count, _M_buffer); + return *this; + } + void push_back(value_type __x) + { + if (_M_buf_count < _Buf_sz) { + _M_buffer[_M_buf_count] = __x; + ++_M_buf_count; + } else { + flush(); + _M_buffer[0] = __x; + _M_buf_count = 1; + } + } + void append(value_type* __s, size_t __len) + { + if (__len + _M_buf_count <= _Buf_sz) { + size_t __i = _M_buf_count; + size_t __j = 0; + for (; __j < __len; __i++, __j++) { + _M_buffer[__i] = __s[__j]; + } + _M_buf_count += __len; + } else if (0 == _M_buf_count) { + _M_prefix->append(__s, __s + __len); + } else { + flush(); + append(__s, __len); + } + } + sequence_buffer& write(value_type* __s, size_t __len) + { + append(__s, __len); + return *this; + } + sequence_buffer& put(value_type __x) + { + push_back(__x); + return *this; + } + sequence_buffer& operator=(const value_type& __rhs) + { + push_back(__rhs); + return *this; + } + sequence_buffer& operator*() { return *this; } + sequence_buffer& operator++() { return *this; } + sequence_buffer& operator++(int) { return *this; } }; // The following should be treated as private, at least for now. -template<class charT> -class __rope_char_consumer { +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; + // If we had member templates, these should not be virtual. + // For now we need to use run-time parametrization where + // compile-time would do. _Hence this should all be private + // for now. + // The symmetry with char_producer is accidental and temporary. + virtual ~_Rope_char_consumer() {}; + virtual bool operator()(const _CharT* __buffer, size_t __len) = 0; }; // @@ -205,22 +210,22 @@ class __rope_char_consumer { // equality on rope iterators. According to the draft standard, the // template parameters for such an equality operator cannot be inferred // from the occurence of a member class as a parameter. -// (SGI compilers in fact allow this, but the result wouldn't be +// (SGI compilers in fact allow this, but the __result wouldn't be // portable.) // Similarly, some of the static member functions are member functions // only to avoid polluting the global namespace, and to circumvent // restrictions on type inference for template functions. // -template<class 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; +template<class _CharT, class _Alloc=__STL_DEFAULT_ALLOCATOR(_CharT)> class rope; +template<class _CharT, class _Alloc> struct _Rope_RopeConcatenation; +template<class _CharT, class _Alloc> struct _Rope_RopeLeaf; +template<class _CharT, class _Alloc> struct _Rope_RopeFunction; +template<class _CharT, class _Alloc> struct _Rope_RopeSubstring; +template<class _CharT, class _Alloc> class _Rope_iterator; +template<class _CharT, class _Alloc> class _Rope_const_iterator; +template<class _CharT, class _Alloc> class _Rope_char_ref_proxy; +template<class _CharT, class _Alloc> class _Rope_char_ptr_proxy; // // The internal data structure for representing a rope. This is @@ -228,273 +233,488 @@ template<class CharT, class Alloc> class __rope_charT_ptr_proxy; // to one of these. // // A few basic functions for manipulating this data structure -// are members of RopeBase. Most of the more complex algorithms +// are members of _RopeRep. Most of the more complex algorithms // are implemented as rope members. // -// Some of the static member functions of RopeBase have identically -// named functions in rope that simply invoke the RopeBase versions. +// Some of the static member functions of _RopeRep have identically +// named functions in rope that simply invoke the _RopeRep versions. // +// A macro to introduce various allocation and deallocation functions +// These need to be defined differently depending on whether or not +// we are using standard conforming allocators, and whether the allocator +// instances have real state. Thus this macro is invoked repeatedly +// with different definitions of __ROPE_DEFINE_ALLOC. +// __ROPE_DEFINE_ALLOC(type,name) defines +// type * name_allocate(size_t) and +// void name_deallocate(tipe *, size_t) +// Both functions may or may not be static. + +#define __ROPE_DEFINE_ALLOCS(__a) \ + __ROPE_DEFINE_ALLOC(_CharT,_Data) /* character data */ \ + typedef _Rope_RopeConcatenation<_CharT,__a> __C; \ + __ROPE_DEFINE_ALLOC(__C,_C) \ + typedef _Rope_RopeLeaf<_CharT,__a> __L; \ + __ROPE_DEFINE_ALLOC(__L,_L) \ + typedef _Rope_RopeFunction<_CharT,__a> __F; \ + __ROPE_DEFINE_ALLOC(__F,_F) \ + typedef _Rope_RopeSubstring<_CharT,__a> __S; \ + __ROPE_DEFINE_ALLOC(__S,_S) + +// Internal rope nodes potentially store a copy of the allocator +// instance used to allocate them. This is mostly redundant. +// But the alternative would be to pass allocator instances around +// in some form to nearly all internal functions, since any pointer +// assignment may result in a zero reference count and thus require +// deallocation. +// The _Rope_rep_base class encapsulates +// the differences between SGI-style allocators and standard-conforming +// allocators. + +#ifdef __STL_USE_STD_ALLOCATORS + +#define __STATIC_IF_SGI_ALLOC /* not static */ + +// Base class for ordinary allocators. +template <class _CharT, class _Allocator, bool _IsStatic> +class _Rope_rep_alloc_base { +public: + typedef typename _Alloc_traits<_CharT,_Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return _M_data_allocator; } + _Rope_rep_alloc_base(size_t __size, const allocator_type& __a) + : _M_size(__size), _M_data_allocator(__a) {} + size_t _M_size; // This is here only to avoid wasting space + // for an otherwise empty base class. + + +protected: + allocator_type _M_data_allocator; + +# define __ROPE_DEFINE_ALLOC(_Tp, __name) \ + typedef typename \ + _Alloc_traits<_Tp,_Allocator>::allocator_type __name##Allocator; \ + /*static*/ _Tp * __name##_allocate(size_t __n) \ + { return __name##Allocator(_M_data_allocator).allocate(__n); } \ + void __name##_deallocate(_Tp* __p, size_t __n) \ + { __name##Allocator(_M_data_allocator).deallocate(__p, __n); } + __ROPE_DEFINE_ALLOCS(_Allocator); +# undef __ROPE_DEFINE_ALLOC +}; + +// Specialization for allocators that have the property that we don't +// actually have to store an allocator object. +template <class _CharT, class _Allocator> +class _Rope_rep_alloc_base<_CharT,_Allocator,true> { +public: + typedef typename _Alloc_traits<_CharT,_Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + _Rope_rep_alloc_base(size_t __size, const allocator_type&) + : _M_size(__size) {} + size_t _M_size; + +protected: + +# define __ROPE_DEFINE_ALLOC(_Tp, __name) \ + typedef typename \ + _Alloc_traits<_Tp,_Allocator>::_Alloc_type __name##Alloc; \ + typedef typename \ + _Alloc_traits<_Tp,_Allocator>::allocator_type __name##Allocator; \ + static _Tp* __name##_allocate(size_t __n) \ + { return __name##Alloc::allocate(__n); } \ + void __name##_deallocate(_Tp *__p, size_t __n) \ + { __name##Alloc::deallocate(__p, __n); } + __ROPE_DEFINE_ALLOCS(_Allocator); +# undef __ROPE_DEFINE_ALLOC +}; + +template <class _CharT, class _Alloc> +struct _Rope_rep_base + : public _Rope_rep_alloc_base<_CharT,_Alloc, + _Alloc_traits<_CharT,_Alloc>::_S_instanceless> +{ + typedef _Rope_rep_alloc_base<_CharT,_Alloc, + _Alloc_traits<_CharT,_Alloc>::_S_instanceless> + _Base; + typedef typename _Base::allocator_type allocator_type; + _Rope_rep_base(size_t __size, const allocator_type& __a) + : _Base(__size, __a) {} +}; + +#else /* !__STL_USE_STD_ALLOCATORS */ + +#define __STATIC_IF_SGI_ALLOC static + +template <class _CharT, class _Alloc> +class _Rope_rep_base { +public: + typedef _Alloc allocator_type; + static allocator_type get_allocator() { return allocator_type(); } + _Rope_rep_base(size_t __size, const allocator_type&) : _M_size(__size) {} + size_t _M_size; + +protected: + +# define __ROPE_DEFINE_ALLOC(_Tp, __name) \ + typedef simple_alloc<_Tp, _Alloc> __name##Alloc; \ + static _Tp* __name##_allocate(size_t __n) \ + { return __name##Alloc::allocate(__n); } \ + static void __name##_deallocate(_Tp* __p, size_t __n) \ + { __name##Alloc::deallocate(__p, __n); } + __ROPE_DEFINE_ALLOCS(_Alloc); +# undef __ROPE_DEFINE_ALLOC +}; + +#endif /* __STL_USE_STD_ALLOCATORS */ -template<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; + +template<class _CharT, class _Alloc> +struct _Rope_RopeRep : public _Rope_rep_base<_CharT,_Alloc> { public: - enum { max_rope_depth = 45 }; - enum {leaf, concat, substringfn, function} tag:8; - bool is_balanced:8; - unsigned char depth; - size_t size; - __GC_CONST charT * c_string; - /* Flattened version of string, if needed. */ - /* typically 0. */ - /* If it's not 0, then the memory is owned */ - /* by this node. */ - /* In the case of a leaf, this may point to */ - /* the same memory as the data field. */ + enum { _S_max_rope_depth = 45 }; + enum _Tag {_S_leaf, _S_concat, _S_substringfn, _S_function}; + _Tag _M_tag:8; + bool _M_is_balanced:8; + unsigned char _M_depth; + __GC_CONST _CharT* _M_c_string; + /* Flattened version of string, if needed. */ + /* typically 0. */ + /* If it's not 0, then the memory is owned */ + /* by this node. */ + /* In the case of a leaf, this may point to */ + /* the same memory as the data field. */ + typedef _Rope_rep_base<_CharT,_Alloc>::allocator_type allocator_type; + _Rope_RopeRep(_Tag __t, int __d, bool __b, size_t __size, + allocator_type __a) + : _M_tag(__t), _M_depth(__d), _M_is_balanced(__b), _M_c_string(0), + _Rope_rep_base<_CharT,_Alloc>(__size, __a) + { +# ifndef __GC + _M_refcount = 1; + _M_init_refcount_lock(); +# endif + } # ifndef __GC # if defined(__STL_WIN32THREADS) - long refcount; // InterlockedIncrement wants a long * -# else - size_t refcount; -# endif - // We count references from rope instances - // and references from other rope nodes. We - // do not count const_iterator references. - // Iterator references are counted so that rope modifications - // can be detected after the fact. - // Generally function results are counted, i.e. - // a pointer returned by a function is included at the - // point at which the pointer is returned. - // The recipient should decrement the count if the - // result is not needed. - // Generally function arguments are not reflected - // in the reference count. The callee should increment - // the count before saving the argument someplace that - // will outlive the call. + long _M_refcount; // InterlockedIncrement wants a long * +# else + size_t _M_refcount; +# endif + // We count references from rope instances + // and references from other rope nodes. We + // do not count const_iterator references. + // Iterator references are counted so that rope modifications + // can be detected after the fact. + // Generally function results are counted, i.__e. + // a pointer returned by a function is included at the + // point at which the pointer is returned. + // The recipient should decrement the count if the + // __result is not needed. + // Generally function arguments are not reflected + // in the reference count. The callee should increment + // the count before saving the argument someplace that + // will outlive the call. # endif # ifndef __GC # ifdef __STL_SGI_THREADS - // Reference counting with multiple threads and no - // hardware or thread package support is pretty awful. - // Mutexes are normally too expensive. - // We'll assume a COMPARE_AND_SWAP(destp, old, new) - // operation, which might be cheaper. + // Reference counting with multiple threads and no + // hardware or thread package support is pretty awful. + // Mutexes are normally too expensive. + // We'll assume a COMPARE_AND_SWAP(destp, __old, new) + // operation, which might be cheaper. # if __mips < 3 || !(defined (_ABIN32) || defined(_ABI64)) -# define __add_and_fetch(l,v) add_then_test((unsigned long *)l,v) +# define __add_and_fetch(l,v) add_then_test((unsigned long*)l,v) # endif - void init_refcount_lock() {} - void incr_refcount () - { - __add_and_fetch(&refcount, 1); - } - size_t decr_refcount () - { - return __add_and_fetch(&refcount, (size_t)(-1)); - } + void _M_init_refcount_lock() {} + void _M_incr_refcount () + { + __add_and_fetch(&_M_refcount, 1); + } + size_t _M_decr_refcount () + { + return __add_and_fetch(&_M_refcount, (size_t)(-1)); + } # elif defined(__STL_WIN32THREADS) - void init_refcount_lock() {} - void incr_refcount () + void _M_init_refcount_lock() {} + void _M_incr_refcount () { - InterlockedIncrement(&refcount); + InterlockedIncrement(&_M_refcount); } - size_t decr_refcount () + size_t _M_decr_refcount () { - return InterlockedDecrement(&refcount); + return InterlockedDecrement(&_M_refcount); } # elif defined(__STL_PTHREADS) - // This should be portable, but performance is expected - // to be quite awful. This really needs platform specific - // code. - pthread_mutex_t refcount_lock; - void init_refcount_lock() { - pthread_mutex_init(&refcount_lock, 0); - } - void incr_refcount () + // This should be portable, but performance is expected + // to be quite awful. This really needs platform specific + // code. + pthread_mutex_t _M_refcount_lock; + void _M_init_refcount_lock() { + pthread_mutex_init(&_M_refcount_lock, 0); + } + void _M_incr_refcount () { - pthread_mutex_lock(&refcount_lock); - ++refcount; - pthread_mutex_unlock(&refcount_lock); + pthread_mutex_lock(&_M_refcount_lock); + ++_M_refcount; + pthread_mutex_unlock(&_M_refcount_lock); } - size_t decr_refcount () + size_t _M_decr_refcount () { - size_t result; - pthread_mutex_lock(&refcount_lock); - result = --refcount; - pthread_mutex_unlock(&refcount_lock); - return result; + size_t __result; + pthread_mutex_lock(&_M_refcount_lock); + __result = --_M_refcount; + pthread_mutex_unlock(&_M_refcount_lock); + return __result; + } +# else + void _M_init_refcount_lock() {} + void _M_incr_refcount () + { + ++_M_refcount; + } + size_t _M_decr_refcount () + { + --_M_refcount; + return _M_refcount; } -# else - void init_refcount_lock() {} - void incr_refcount () - { - ++refcount; - } - size_t decr_refcount () - { - --refcount; - return refcount; - } # endif # else - void incr_refcount () {} + void _M_incr_refcount () {} +# endif +# ifdef __STL_USE_STD_ALLOCATORS + static void _S_free_string(__GC_CONST _CharT*, size_t __len, + allocator_type __a); +# define __STL_FREE_STRING(__s, __l, __a) _S_free_string(__s, __l, __a); +# else + static void _S_free_string(__GC_CONST _CharT*, size_t __len); +# define __STL_FREE_STRING(__s, __l, __a) _S_free_string(__s, __l); # endif - static void free_string(charT *, size_t len); - // Deallocate data section of a leaf. - // This shouldn't be a member function. - // But its hard to do anything else at the - // moment, because it's templatized w.r.t. - // an allocator. - // Does nothing if __GC is defined. + // Deallocate data section of a leaf. + // This shouldn't be a member function. + // But its hard to do anything else at the + // moment, because it's templatized w.r.t. + // an allocator. + // Does nothing if __GC is defined. # ifndef __GC - void free_c_string(); - void free_tree(); - // Deallocate t. Assumes t is not 0. - void unref_nonnil() - { - if (0 == decr_refcount()) free_tree(); - } - void ref_nonnil() - { - incr_refcount(); - } - static void unref(__rope_RopeBase* t) - { - if (0 != t) { - t -> unref_nonnil(); - } - } - static void ref(__rope_RopeBase* t) - { - if (0 != t) t -> incr_refcount(); - } - static void free_if_unref(__rope_RopeBase* t) - { - if (0 != t && 0 == t -> refcount) t -> free_tree(); - } + void _M_free_c_string(); + void _M_free_tree(); + // Deallocate t. Assumes t is not 0. + void _M_unref_nonnil() + { + if (0 == _M_decr_refcount()) _M_free_tree(); + } + void _M_ref_nonnil() + { + _M_incr_refcount(); + } + static void _S_unref(_Rope_RopeRep* __t) + { + if (0 != __t) { + __t->_M_unref_nonnil(); + } + } + static void _S_ref(_Rope_RopeRep* __t) + { + if (0 != __t) __t->_M_incr_refcount(); + } + static void _S_free_if_unref(_Rope_RopeRep* __t) + { + if (0 != __t && 0 == __t->_M_refcount) __t->_M_free_tree(); + } # else /* __GC */ - void unref_nonnil() {} - void ref_nonnil() {} - static void unref(__rope_RopeBase* t) {} - static void ref(__rope_RopeBase* t) {} - static void fn_finalization_proc(void * tree, void *); - static void free_if_unref(__rope_RopeBase* t) {} + void _M_unref_nonnil() {} + void _M_ref_nonnil() {} + static void _S_unref(_Rope_RopeRep*) {} + static void _S_ref(_Rope_RopeRep*) {} + static void _S_free_if_unref(_Rope_RopeRep*) {} # endif +}; + +template<class _CharT, class _Alloc> +struct _Rope_RopeLeaf : public _Rope_RopeRep<_CharT,_Alloc> { + public: + // Apparently needed by VC++ // The data fields of leaves are allocated with some // extra space, to accomodate future growth and for basic // character types, to hold a trailing eos character. - enum { alloc_granularity = 8 }; - static size_t rounded_up_size(size_t n) { - size_t size_with_eos; - - if (__is_basic_char_type((charT *)0)) { - size_with_eos = n + 1; - } else { - size_with_eos = n; - } + enum { _S_alloc_granularity = 8 }; + static size_t _S_rounded_up_size(size_t __n) { + size_t __size_with_eos; + + if (_S_is_basic_char_type((_CharT*)0)) { + __size_with_eos = __n + 1; + } else { + __size_with_eos = __n; + } # ifdef __GC - return size_with_eos; -# else - // Allow slop for in-place expansion. - return (size_with_eos + alloc_granularity-1) - &~ (alloc_granularity-1); -# endif + return __size_with_eos; +# else + // Allow slop for in-place expansion. + return (__size_with_eos + _S_alloc_granularity-1) + &~ (_S_alloc_granularity-1); +# endif } + __GC_CONST _CharT* _M_data; /* Not necessarily 0 terminated. */ + /* The allocated size is */ + /* _S_rounded_up_size(size), except */ + /* in the GC case, in which it */ + /* doesn't matter. */ + typedef _Rope_rep_base<_CharT,_Alloc>::allocator_type allocator_type; + _Rope_RopeLeaf(__GC_CONST _CharT* __d, size_t __size, allocator_type __a) + : _M_data(__d) + , _Rope_RopeRep<_CharT,_Alloc>(_S_leaf, 0, true, __size, __a) + { + __stl_assert(__size > 0); + if (_S_is_basic_char_type((_CharT *)0)) { + // already eos terminated. + _M_c_string = __d; + } + } + // The constructor assumes that d has been allocated with + // the proper allocator and the properly padded size. + // In contrast, the destructor deallocates the data: +# ifndef __GC + ~_Rope_RopeLeaf() { + if (_M_data != _M_c_string) { + _M_free_c_string(); + } + __STL_FREE_STRING(_M_data, _M_size, get_allocator()); + } +# endif }; -template<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> { +template<class _CharT, class _Alloc> +struct _Rope_RopeConcatenation : public _Rope_RopeRep<_CharT,_Alloc> { public: - __rope_RopeBase<charT,Alloc>* left; - __rope_RopeBase<charT,Alloc>* right; + _Rope_RopeRep<_CharT,_Alloc>* _M_left; + _Rope_RopeRep<_CharT,_Alloc>* _M_right; + typedef _Rope_rep_base<_CharT,_Alloc>::allocator_type allocator_type; + _Rope_RopeConcatenation(_Rope_RopeRep<_CharT,_Alloc>* __l, + _Rope_RopeRep<_CharT,_Alloc>* __r, + allocator_type __a) + : _M_left(__l), _M_right(__r) + , _Rope_RopeRep<_CharT,_Alloc>( + _S_concat, max(__l->_M_depth, __r->_M_depth) + 1, false, + __l->_M_size + __r->_M_size, __a) + {} +# ifndef __GC + ~_Rope_RopeConcatenation() { + _M_free_c_string(); + _M_left->_M_unref_nonnil(); + _M_right->_M_unref_nonnil(); + } +# endif }; -template<class charT, class Alloc> -struct __rope_RopeFunction : public __rope_RopeBase<charT,Alloc> { +template<class _CharT, class _Alloc> +struct _Rope_RopeFunction : public _Rope_RopeRep<_CharT,_Alloc> { public: - char_producer<charT>* fn; + char_producer<_CharT>* _M_fn; # ifndef __GC - bool delete_when_done; // Char_producer is owned by the - // rope and should be explicitly - // deleted when the rope becomes - // inaccessible. + bool _M_delete_when_done; // Char_producer is owned by the + // rope and should be explicitly + // deleted when the rope becomes + // inaccessible. # else // In the GC case, we either register the rope for // finalization, or not. Thus the field is unnecessary; // the information is stored in the collector data structures. + // We do need a finalization procedure to be invoked by the + // collector. + static void _S_fn_finalization_proc(void * __tree, void *) { + delete ((_Rope_RopeFunction *)__tree) -> _M_fn; + } # endif + typedef _Rope_rep_base<_CharT,_Alloc>::allocator_type allocator_type; + _Rope_RopeFunction(char_producer<_CharT>* __f, size_t __size, + bool __d, allocator_type __a) + : _M_fn(__f) +# ifndef __GC + , _M_delete_when_done(__d) +# endif + , _Rope_RopeRep<_CharT,_Alloc>(_S_function, 0, true, __size, __a) { + __stl_assert(__size > 0); +# ifdef __GC + if (__d) { + GC_REGISTER_FINALIZER( + this, _Rope_RopeFunction::_S_fn_finalization_proc, 0, 0, 0); + } +# endif + } +# ifndef __GC + ~_Rope_RopeFunction() { + _M_free_c_string(); + if (_M_delete_when_done) { + delete _M_fn; + } + } +# endif }; // Substring results are usually represented using just // concatenation nodes. But in the case of very long flat ropes // or ropes with a functional representation that isn't practical. -// In that case, we represent the result as a special case of +// In that case, we represent the __result as a special case of // RopeFunction, whose char_producer points back to the rope itself. // In all cases except repeated substring operations and -// deallocation, we treat the result as a RopeFunction. -template<class charT, class Alloc> -struct __rope_RopeSubstring: public __rope_RopeFunction<charT,Alloc>, - public char_producer<charT> { +// 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); - } + // XXX this whole class should be rewritten. + _Rope_RopeRep<_CharT,_Alloc>* _M_base; // not 0 + size_t _M_start; + virtual void operator()(size_t __start_pos, size_t __req_len, + _CharT* __buffer) { + switch(_M_base->_M_tag) { + case _S_function: + case _S_substringfn: + { + char_producer<_CharT>* __fn = + ((_Rope_RopeFunction<_CharT,_Alloc>*)_M_base)->_M_fn; + __stl_assert(__start_pos + __req_len <= _M_size); + __stl_assert(_M_start + _M_size <= _M_base->_M_size); + (*__fn)(__start_pos + _M_start, __req_len, __buffer); + } + break; + case _S_leaf: + { + __GC_CONST _CharT* __s = + ((_Rope_RopeLeaf<_CharT,_Alloc>*)_M_base)->_M_data; + uninitialized_copy_n(__s + __start_pos + _M_start, __req_len, + __buffer); + } + break; + default: + __stl_assert(false); + } } - __rope_RopeSubstring(__rope_RopeBase<charT,Alloc> * b, size_t s, size_t l) : - base(b), start(s) { + typedef _Rope_rep_base<_CharT,_Alloc>::allocator_type allocator_type; + _Rope_RopeSubstring(_Rope_RopeRep<_CharT,_Alloc>* __b, size_t __s, + size_t __l, allocator_type __a) + : _M_base(__b) + , _M_start(__s) + , _Rope_RopeFunction<_CharT,_Alloc>(this, __l, false, __a) + { + __stl_assert(__l > 0); + __stl_assert(__s + __l <= __b->_M_size); # ifndef __GC - refcount = 1; - init_refcount_lock(); - base -> ref_nonnil(); + _M_base->_M_ref_nonnil(); # endif - size = l; - tag = substringfn; - depth = 0; - c_string = 0; - fn = this; + _M_tag = _S_substringfn; } + virtual ~_Rope_RopeSubstring() + { +# ifndef __GC + _M_base->_M_unref_nonnil(); + // _M_free_c_string(); -- done by parent class +# endif + } }; -// Self-destructing pointers to RopeBase. +// Self-destructing pointers to Rope_rep. // These are not conventional smart pointers. Their // only purpose in life is to ensure that unref is called // on the pointer either at normal exit or if an exception @@ -504,21 +724,22 @@ struct __rope_RopeSubstring: public __rope_RopeFunction<charT,Alloc>, // 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); } + template<class _CharT, class _Alloc> + struct _Rope_self_destruct_ptr { + _Rope_RopeRep<_CharT,_Alloc>* _M_ptr; + ~_Rope_self_destruct_ptr() + { _Rope_RopeRep<_CharT,_Alloc>::_S_unref(_M_ptr); } # ifdef __STL_USE_EXCEPTIONS - __rope_self_destruct_ptr() : ptr(0) {}; + _Rope_self_destruct_ptr() : _M_ptr(0) {}; # else - __rope_self_destruct_ptr() {}; + _Rope_self_destruct_ptr() {}; # endif - __rope_self_destruct_ptr(__rope_RopeBase<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; } + _Rope_self_destruct_ptr(_Rope_RopeRep<_CharT,_Alloc>* __p) : _M_ptr(__p) {} + _Rope_RopeRep<_CharT,_Alloc>& operator*() { return *_M_ptr; } + _Rope_RopeRep<_CharT,_Alloc>* operator->() { return _M_ptr; } + operator _Rope_RopeRep<_CharT,_Alloc>*() { return _M_ptr; } + _Rope_self_destruct_ptr& operator= (_Rope_RopeRep<_CharT,_Alloc>* __x) + { _M_ptr = __x; return *this; } }; #endif @@ -527,73 +748,100 @@ struct __rope_RopeSubstring: public __rope_RopeFunction<charT,Alloc>, // 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>; +template<class _CharT, class _Alloc> +class _Rope_char_ref_proxy { + friend class rope<_CharT,_Alloc>; + friend class _Rope_iterator<_CharT,_Alloc>; + friend class _Rope_char_ptr_proxy<_CharT,_Alloc>; # ifdef __GC - typedef __rope_RopeBase<charT,Alloc> * self_destruct_ptr; + typedef _Rope_RopeRep<_CharT,_Alloc>* _Self_destruct_ptr; # else - typedef __rope_self_destruct_ptr<charT,Alloc> self_destruct_ptr; + 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. + typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep; + typedef rope<_CharT,_Alloc> _My_rope; + size_t _M_pos; + _CharT _M_current; + bool _M_current_valid; + _My_rope* _M_root; // The whole rope. public: - __rope_charT_ref_proxy(my_rope * r, size_t p) : - pos(p), root(r), current_valid(false) {} - __rope_charT_ref_proxy(my_rope * r, size_t p, - charT c) : - pos(p), root(r), current(c), current_valid(true) {} - operator charT () const; - __rope_charT_ref_proxy& operator= (charT c); - __rope_charT_ptr_proxy<charT,Alloc> operator& () const; - __rope_charT_ref_proxy& operator= (const __rope_charT_ref_proxy& c) { - return operator=((charT)c); + _Rope_char_ref_proxy(_My_rope* __r, size_t __p) : + _M_pos(__p), _M_root(__r), _M_current_valid(false) {} + _Rope_char_ref_proxy(const _Rope_char_ref_proxy& __x) : + _M_pos(__x._M_pos), _M_root(__x._M_root), _M_current_valid(false) {} + // Don't preserve cache if the reference can outlive the + // expression. We claim that's not possible without calling + // a copy constructor or generating reference to a proxy + // reference. We declare the latter to have undefined semantics. + _Rope_char_ref_proxy(_My_rope* __r, size_t __p, + _CharT __c) : + _M_pos(__p), _M_root(__r), _M_current(__c), _M_current_valid(true) {} + inline operator _CharT () const; + _Rope_char_ref_proxy& operator= (_CharT __c); + _Rope_char_ptr_proxy<_CharT,_Alloc> operator& () const; + _Rope_char_ref_proxy& operator= (const _Rope_char_ref_proxy& __c) { + return operator=((_CharT)__c); } }; -template<class 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. +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + template<class _CharT, class __Alloc> + inline void swap(_Rope_char_ref_proxy <_CharT, __Alloc > __a, + _Rope_char_ref_proxy <_CharT, __Alloc > __b) { + _CharT __tmp = __a; + __a = __b; + __b = __tmp; + } +#else +// There is no really acceptable way to handle this. The default +// definition of swap doesn't work for proxy references. +// It can't really be made to work, even with ugly hacks, since +// the only unusual operation it uses is the copy constructor, which +// is needed for other purposes. We provide a macro for +// full specializations, and instantiate the most common case. +# define _ROPE_SWAP_SPECIALIZATION(_CharT, __Alloc) \ + inline void swap(_Rope_char_ref_proxy <_CharT, __Alloc > __a, \ + _Rope_char_ref_proxy <_CharT, __Alloc > __b) { \ + _CharT __tmp = __a; \ + __a = __b; \ + __b = __tmp; \ + } + +_ROPE_SWAP_SPECIALIZATION(char,__STL_DEFAULT_ALLOCATOR(char)) + +#endif /* !__STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +template<class _CharT, class _Alloc> +class _Rope_char_ptr_proxy { + // XXX this class should be rewritten. + friend class _Rope_char_ref_proxy<_CharT,_Alloc>; + size_t _M_pos; + rope<_CharT,_Alloc>* _M_root; // The whole rope. public: - __rope_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_char_ptr_proxy(const _Rope_char_ref_proxy<_CharT,_Alloc>& __x) + : _M_pos(__x._M_pos), _M_root(__x._M_root) {} + _Rope_char_ptr_proxy(const _Rope_char_ptr_proxy& __x) + : _M_pos(__x._M_pos), _M_root(__x._M_root) {} + _Rope_char_ptr_proxy() {} + _Rope_char_ptr_proxy(_CharT* __x) : _M_root(0), _M_pos(0) { + __stl_assert(0 == __x); } - __rope_charT_ptr_proxy& operator= (const __rope_charT_ptr_proxy& x) { - pos = x.pos; - current = x.current; - current_valid = x.current_valid; - root = x.root; - return *this; + _Rope_char_ptr_proxy& + operator= (const _Rope_char_ptr_proxy& __x) { + _M_pos = __x._M_pos; + _M_root = __x._M_root; + return *this; } - friend bool operator== __STL_NULL_TMPL_ARGS - (const __rope_charT_ptr_proxy<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); - } + friend bool operator== __STL_NULL_TMPL_ARGS + (const _Rope_char_ptr_proxy<_CharT,_Alloc>& __x, + const _Rope_char_ptr_proxy<_CharT,_Alloc>& __y); + + _Rope_char_ref_proxy<_CharT,_Alloc> operator*() const { + return _Rope_char_ref_proxy<_CharT,_Alloc>(_M_root, _M_pos); } }; + // Rope iterators: // Unlike in the C version, we cache only part of the stack // for rope iterators, since they must be efficiently copyable. @@ -607,294 +855,297 @@ class __rope_charT_ptr_proxy { #pragma set woff 1375 #endif -template<class charT, class Alloc> -class __rope_iterator_base: - public random_access_iterator<charT, ptrdiff_t> { - friend class rope<charT, Alloc>; +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. + typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep; + // Borland doesnt want this to be protected. protected: - enum { path_cache_len = 4 }; // Must be <= 9. - enum { iterator_buf_len = 15 }; - size_t current_pos; - RopeBase * root; // The whole rope. - size_t leaf_pos; // Starting position for current leaf - __GC_CONST charT * buf_start; - // Buffer possibly - // containing current char. - __GC_CONST charT * buf_ptr; - // Pointer to current char in buffer. - // != 0 ==> buffer valid. - __GC_CONST charT * buf_end; - // One past last valid char in buffer. + enum { _S_path_cache_len = 4 }; // Must be <= 9. + enum { _S_iterator_buf_len = 15 }; + size_t _M_current_pos; + _RopeRep* _M_root; // The whole rope. + size_t _M_leaf_pos; // Starting position for current leaf + __GC_CONST _CharT* _M_buf_start; + // Buffer possibly + // containing current char. + __GC_CONST _CharT* _M_buf_ptr; + // Pointer to current char in buffer. + // != 0 ==> buffer valid. + __GC_CONST _CharT* _M_buf_end; + // One past __last valid char in buffer. // What follows is the path cache. We go out of our // way to make this compact. // Path_end contains the bottom section of the path from // the root to the current leaf. - const RopeBase * path_end[path_cache_len]; - int leaf_index; // Last valid pos in path_end; - // path_end[0] ... path_end[leaf_index-1] - // point to concatenation nodes. - unsigned char path_directions; - // (path_directions >> i) & 1 is 1 - // iff we got from path_end[leaf_index - i - 1] - // to path_end[leaf_index - i] by going to the - // right. Assumes path_cache_len <= 9. - charT tmp_buf[iterator_buf_len]; - // Short buffer for surrounding chars. - // This is useful primarily for - // RopeFunctions. We put the buffer - // here to avoid locking in the - // multithreaded case. + const _RopeRep* _M_path_end[_S_path_cache_len]; + int _M_leaf_index; // Last valid __pos in path_end; + // _M_path_end[0] ... _M_path_end[leaf_index-1] + // point to concatenation nodes. + unsigned char _M_path_directions; + // (path_directions >> __i) & 1 is 1 + // iff we got from _M_path_end[leaf_index - __i - 1] + // to _M_path_end[leaf_index - __i] by going to the + // __right. Assumes path_cache_len <= 9. + _CharT _M_tmp_buf[_S_iterator_buf_len]; + // Short buffer for surrounding chars. + // This is useful primarily for + // RopeFunctions. We put the buffer + // here to avoid locking in the + // multithreaded case. // The cached path is generally assumed to be valid // only if the buffer is valid. - static void setbuf(__rope_iterator_base &x); - // Set buffer contents given - // path cache. - static void setcache(__rope_iterator_base &x); - // Set buffer contents and - // path cache. - static void setcache_for_incr(__rope_iterator_base &x); - // As above, but assumes path - // cache is valid for previous posn. - __rope_iterator_base() {} - __rope_iterator_base(RopeBase * root, size_t pos): - root(root), current_pos(pos), buf_ptr(0) {} - __rope_iterator_base(const __rope_iterator_base& x) { - if (0 != x.buf_ptr) { - *this = x; - } else { - current_pos = x.current_pos; - root = x.root; - buf_ptr = 0; - } - } - void incr(size_t n); - void decr(size_t n); + static void _S_setbuf(_Rope_iterator_base& __x); + // Set buffer contents given + // path cache. + static void _S_setcache(_Rope_iterator_base& __x); + // Set buffer contents and + // path cache. + static void _S_setcache_for_incr(_Rope_iterator_base& __x); + // As above, but assumes path + // cache is valid for previous posn. + _Rope_iterator_base() {} + _Rope_iterator_base(_RopeRep* __root, size_t __pos) + : _M_root(__root), _M_current_pos(__pos), _M_buf_ptr(0) {} + void _M_incr(size_t __n); + void _M_decr(size_t __n); public: - size_t index() const { return current_pos; } + size_t index() const { return _M_current_pos; } + _Rope_iterator_base(const _Rope_iterator_base& __x) { + if (0 != __x._M_buf_ptr) { + *this = __x; + } else { + _M_current_pos = __x._M_current_pos; + _M_root = __x._M_root; + _M_buf_ptr = 0; + } + } }; -template<class charT, class Alloc> class __rope_iterator; +template<class _CharT, class _Alloc> class _Rope_iterator; -template<class charT, class Alloc> -class __rope_const_iterator : public __rope_iterator_base<charT,Alloc> { - friend class rope<charT,Alloc>; +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 + _Rope_const_iterator(const _RopeRep* __root, size_t __pos): + _Rope_iterator_base<_CharT,_Alloc>( + const_cast<_RopeRep*>(__root), __pos) + // Only nonconst iterators modify root ref count {} public: - typedef charT reference; // Really a value. Returning a reference - // Would be a mess, since it would have - // to be included in refcount. - typedef const charT* pointer; + typedef _CharT reference; // Really a value. Returning a reference + // Would be a mess, since it would have + // to be included in refcount. + typedef const _CharT* pointer; public: - __rope_const_iterator() {}; - __rope_const_iterator(const __rope_const_iterator & x) : - __rope_iterator_base<charT,Alloc>(x) { } - __rope_const_iterator(const __rope_iterator<charT,Alloc> & x); - __rope_const_iterator(const rope<charT,Alloc> &r, size_t pos) : - __rope_iterator_base<charT,Alloc>(r.tree_ptr, pos) {} - __rope_const_iterator& operator= (const __rope_const_iterator & x) { - if (0 != x.buf_ptr) { - *this = x; - } else { - current_pos = x.current_pos; - root = x.root; - buf_ptr = 0; - } - return(*this); + _Rope_const_iterator() {}; + _Rope_const_iterator(const _Rope_const_iterator& __x) : + _Rope_iterator_base<_CharT,_Alloc>(__x) { } + _Rope_const_iterator(const _Rope_iterator<_CharT,_Alloc>& __x); + _Rope_const_iterator(const rope<_CharT,_Alloc>& __r, size_t __pos) : + _Rope_iterator_base<_CharT,_Alloc>(__r._M_tree_ptr, __pos) {} + _Rope_const_iterator& operator= (const _Rope_const_iterator& __x) { + if (0 != __x._M_buf_ptr) { + *(static_cast<_Rope_iterator_base<_CharT,_Alloc>*>(this)) = __x; + } else { + _M_current_pos = __x._M_current_pos; + _M_root = __x._M_root; + _M_buf_ptr = 0; + } + return(*this); } reference operator*() { - if (0 == buf_ptr) setcache(*this); - return *buf_ptr; + if (0 == _M_buf_ptr) _S_setcache(*this); + return *_M_buf_ptr; } - __rope_const_iterator& operator++() { - __GC_CONST charT * next; - if (0 != buf_ptr && (next = buf_ptr + 1) < buf_end) { - buf_ptr = next; - ++current_pos; - } else { - incr(1); - } - return *this; + _Rope_const_iterator& operator++() { + __GC_CONST _CharT* __next; + if (0 != _M_buf_ptr && (__next = _M_buf_ptr + 1) < _M_buf_end) { + _M_buf_ptr = __next; + ++_M_current_pos; + } else { + _M_incr(1); + } + return *this; } - __rope_const_iterator& operator+=(ptrdiff_t n) { - if (n >= 0) { - incr(n); - } else { - decr(-n); - } - return *this; + _Rope_const_iterator& operator+=(ptrdiff_t __n) { + if (__n >= 0) { + _M_incr(__n); + } else { + _M_decr(-__n); + } + return *this; } - __rope_const_iterator& operator--() { - decr(1); - return *this; + _Rope_const_iterator& operator--() { + _M_decr(1); + return *this; } - __rope_const_iterator& operator-=(ptrdiff_t n) { - if (n >= 0) { - decr(n); - } else { - incr(-n); - } - return *this; + _Rope_const_iterator& operator-=(ptrdiff_t __n) { + if (__n >= 0) { + _M_decr(__n); + } else { + _M_incr(-__n); + } + return *this; } - __rope_const_iterator operator++(int) { - size_t old_pos = current_pos; - incr(1); - return __rope_const_iterator<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 = _M_current_pos; + _M_incr(1); + return _Rope_const_iterator<_CharT,_Alloc>(_M_root, __old_pos); + // This makes a subsequent dereference expensive. + // Perhaps we should instead copy the iterator + // if it has a valid cache? } - __rope_const_iterator operator--(int) { - size_t old_pos = current_pos; - decr(1); - return __rope_const_iterator<charT,Alloc>(root, old_pos); + _Rope_const_iterator operator--(int) { + size_t __old_pos = _M_current_pos; + _M_decr(1); + return _Rope_const_iterator<_CharT,_Alloc>(_M_root, __old_pos); } - friend __rope_const_iterator<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 _Rope_const_iterator<_CharT,_Alloc> operator- __STL_NULL_TMPL_ARGS + (const _Rope_const_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n); + friend _Rope_const_iterator<_CharT,_Alloc> operator+ __STL_NULL_TMPL_ARGS + (const _Rope_const_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n); + friend _Rope_const_iterator<_CharT,_Alloc> operator+ __STL_NULL_TMPL_ARGS + (ptrdiff_t __n, + const _Rope_const_iterator<_CharT,_Alloc>& __x); + reference operator[](size_t __n) { + return rope<_CharT,_Alloc>::_S_fetch(_M_root, _M_current_pos + __n); } friend bool operator== __STL_NULL_TMPL_ARGS - (const __rope_const_iterator<charT,Alloc> & x, - const __rope_const_iterator<charT,Alloc> & y); + (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); + (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); + (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>; +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(); + rope<_CharT,_Alloc>* _M_root_rope; + // root is treated as a cached version of this, + // and is used to detect changes to the underlying + // rope. + // Root is included in the reference count. + // This is necessary so that we can detect changes reliably. + // Unfortunately, it requires careful bookkeeping for the + // nonGC case. + _Rope_iterator(rope<_CharT,_Alloc>* __r, size_t __pos) + : _Rope_iterator_base<_CharT,_Alloc>(__r->_M_tree_ptr, __pos), + _M_root_rope(__r) + { _RopeRep::_S_ref(_M_root); } + + void _M_check(); public: - typedef __rope_charT_ref_proxy<charT,Alloc> reference; - typedef __rope_charT_ref_proxy<charT,Alloc>* pointer; + typedef _Rope_char_ref_proxy<_CharT,_Alloc> reference; + typedef _Rope_char_ref_proxy<_CharT,_Alloc>* pointer; public: - rope<charT,Alloc>& container() { return *root_rope; } - __rope_iterator() { - root = 0; // Needed for reference counting. + rope<_CharT,_Alloc>& container() { return *_M_root_rope; } + _Rope_iterator() { + _M_root = 0; // Needed for reference counting. }; - __rope_iterator(const __rope_iterator & x) : - __rope_iterator_base<charT,Alloc>(x) { - root_rope = x.root_rope; - RopeBase::ref(root); + _Rope_iterator(const _Rope_iterator& __x) : + _Rope_iterator_base<_CharT,_Alloc>(__x) { + _M_root_rope = __x._M_root_rope; + _RopeRep::_S_ref(_M_root); } - __rope_iterator(rope<charT,Alloc>& r, size_t pos); - ~__rope_iterator() { - RopeBase::unref(root); + _Rope_iterator(rope<_CharT,_Alloc>& __r, size_t __pos); + ~_Rope_iterator() { + _RopeRep::_S_unref(_M_root); } - __rope_iterator& operator= (const __rope_iterator & x) { - RopeBase *old = root; - - RopeBase::ref(x.root); - if (0 != x.buf_ptr) { - *this = x; - } else { - current_pos = x.current_pos; - root = x.root; - root_rope = x.root_rope; - buf_ptr = 0; - } - RopeBase::unref(old); - return(*this); + _Rope_iterator& operator= (const _Rope_iterator& __x) { + _RopeRep* __old = _M_root; + + _RopeRep::_S_ref(__x._M_root); + if (0 != __x._M_buf_ptr) { + _M_root_rope = __x._M_root_rope; + *(static_cast<_Rope_iterator_base<_CharT,_Alloc>*>(this)) = __x; + } else { + _M_current_pos = __x._M_current_pos; + _M_root = __x._M_root; + _M_root_rope = __x._M_root_rope; + _M_buf_ptr = 0; + } + _RopeRep::_S_unref(__old); + return(*this); } reference operator*() { - check(); - if (0 == buf_ptr) { - return __rope_charT_ref_proxy<charT,Alloc>(root_rope, current_pos); - } else { - return __rope_charT_ref_proxy<charT,Alloc>(root_rope, - current_pos, *buf_ptr); - } + _M_check(); + if (0 == _M_buf_ptr) { + return _Rope_char_ref_proxy<_CharT,_Alloc>( + _M_root_rope, _M_current_pos); + } else { + return _Rope_char_ref_proxy<_CharT,_Alloc>( + _M_root_rope, _M_current_pos, *_M_buf_ptr); + } } - __rope_iterator& operator++() { - incr(1); - return *this; + _Rope_iterator& operator++() { + _M_incr(1); + return *this; } - __rope_iterator& operator+=(difference_type n) { - if (n >= 0) { - incr(n); - } else { - decr(-n); - } - return *this; + _Rope_iterator& operator+=(difference_type __n) { + if (__n >= 0) { + _M_incr(__n); + } else { + _M_decr(-__n); + } + return *this; } - __rope_iterator& operator--() { - decr(1); - return *this; + _Rope_iterator& operator--() { + _M_decr(1); + return *this; } - __rope_iterator& operator-=(difference_type n) { - if (n >= 0) { - decr(n); - } else { - incr(-n); - } - return *this; + _Rope_iterator& operator-=(difference_type __n) { + if (__n >= 0) { + _M_decr(__n); + } else { + _M_incr(-__n); + } + return *this; } - __rope_iterator operator++(int) { - size_t old_pos = current_pos; - incr(1); - return __rope_iterator<charT,Alloc>(root_rope, old_pos); + _Rope_iterator operator++(int) { + size_t __old_pos = _M_current_pos; + _M_incr(1); + return _Rope_iterator<_CharT,_Alloc>(_M_root_rope, __old_pos); } - __rope_iterator operator--(int) { - size_t old_pos = current_pos; - decr(1); - return __rope_iterator<charT,Alloc>(root_rope, old_pos); + _Rope_iterator operator--(int) { + size_t __old_pos = _M_current_pos; + _M_decr(1); + return _Rope_iterator<_CharT,_Alloc>(_M_root_rope, __old_pos); } - reference operator[](ptrdiff_t n) { - return __rope_charT_ref_proxy<charT,Alloc>(root_rope, current_pos + n); + reference operator[](ptrdiff_t __n) { + return _Rope_char_ref_proxy<_CharT,_Alloc>( + _M_root_rope, _M_current_pos + __n); } friend bool operator== __STL_NULL_TMPL_ARGS - (const __rope_iterator<charT,Alloc> & x, - const __rope_iterator<charT,Alloc> & y); + (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); + (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); + (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y); + friend _Rope_iterator<_CharT,_Alloc> operator- __STL_NULL_TMPL_ARGS + (const _Rope_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n); + friend _Rope_iterator<_CharT,_Alloc> operator+ __STL_NULL_TMPL_ARGS + (const _Rope_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n); + friend _Rope_iterator<_CharT,_Alloc> operator+ __STL_NULL_TMPL_ARGS + (ptrdiff_t __n, + const _Rope_iterator<_CharT,_Alloc>& __x); }; @@ -902,1199 +1153,1376 @@ class __rope_iterator : public __rope_iterator_base<charT,Alloc> { #pragma reset woff 1375 #endif -template <class charT, class Alloc> -class rope { +// The rope base class encapsulates +// the differences between SGI-style allocators and standard-conforming +// allocators. + +#ifdef __STL_USE_STD_ALLOCATORS + +// Base class for ordinary allocators. +template <class _CharT, class _Allocator, bool _IsStatic> +class _Rope_alloc_base { +public: + typedef _Rope_RopeRep<_CharT,_Allocator> _RopeRep; + typedef typename _Alloc_traits<_CharT,_Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return _M_data_allocator; } + _Rope_alloc_base(_RopeRep *__t, const allocator_type& __a) + : _M_tree_ptr(__t), _M_data_allocator(__a) {} + _Rope_alloc_base(const allocator_type& __a) + : _M_data_allocator(__a) {} + +protected: + // The only data members of a rope: + allocator_type _M_data_allocator; + _RopeRep* _M_tree_ptr; + +# define __ROPE_DEFINE_ALLOC(_Tp, __name) \ + typedef typename \ + _Alloc_traits<_Tp,_Allocator>::allocator_type __name##Allocator; \ + _Tp* __name##_allocate(size_t __n) const \ + { return __name##Allocator(_M_data_allocator).allocate(__n); } \ + void __name##_deallocate(_Tp *__p, size_t __n) const \ + { __name##Allocator(_M_data_allocator).deallocate(__p, __n); } + __ROPE_DEFINE_ALLOCS(_Allocator) +# undef __ROPE_DEFINE_ALLOC +}; + +// Specialization for allocators that have the property that we don't +// actually have to store an allocator object. +template <class _CharT, class _Allocator> +class _Rope_alloc_base<_CharT,_Allocator,true> { +public: + typedef _Rope_RopeRep<_CharT,_Allocator> _RopeRep; + typedef typename _Alloc_traits<_CharT,_Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + _Rope_alloc_base(_RopeRep *__t, const allocator_type&) + : _M_tree_ptr(__t) {} + _Rope_alloc_base(const allocator_type&) {} + +protected: + // The only data member of a rope: + _RopeRep *_M_tree_ptr; + +# define __ROPE_DEFINE_ALLOC(_Tp, __name) \ + typedef typename \ + _Alloc_traits<_Tp,_Allocator>::_Alloc_type __name##Alloc; \ + typedef typename \ + _Alloc_traits<_Tp,_Allocator>::allocator_type __name##Allocator; \ + static _Tp* __name##_allocate(size_t __n) \ + { return __name##Alloc::allocate(__n); } \ + static void __name##_deallocate(_Tp *__p, size_t __n) \ + { __name##Alloc::deallocate(__p, __n); } + __ROPE_DEFINE_ALLOCS(_Allocator) +# undef __ROPE_DEFINE_ALLOC +}; + +template <class _CharT, class _Alloc> +struct _Rope_base + : public _Rope_alloc_base<_CharT,_Alloc, + _Alloc_traits<_CharT,_Alloc>::_S_instanceless> +{ + typedef _Rope_alloc_base<_CharT,_Alloc, + _Alloc_traits<_CharT,_Alloc>::_S_instanceless> + _Base; + typedef typename _Base::allocator_type allocator_type; + _Rope_base(_RopeRep* __t, const allocator_type& __a) : _Base(__t, __a) {} + _Rope_base(const allocator_type& __a) : _Base(__a) {} +}; + +#else /* !__STL_USE_STD_ALLOCATORS */ + +template <class _CharT, class _Alloc> +class _Rope_base { +public: + typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep; + typedef _Alloc allocator_type; + static allocator_type get_allocator() { return allocator_type(); } + _Rope_base(_RopeRep * __t, const allocator_type&) : _M_tree_ptr(__t) {} + _Rope_base(const allocator_type&) {} + +protected: + // The only data member of a rope: + _RopeRep* _M_tree_ptr; + +# define __ROPE_DEFINE_ALLOC(_Tp, __name) \ + typedef simple_alloc<_Tp, _Alloc> __name##Alloc; \ + static _Tp* __name##_allocate(size_t __n) \ + { return __name##Alloc::allocate(__n); } \ + static void __name##_deallocate(_Tp *__p, size_t __n) \ + { __name##Alloc::deallocate(__p, __n); } + __ROPE_DEFINE_ALLOCS(_Alloc) +# undef __ROPE_DEFINE_ALLOC +}; + +#endif /* __STL_USE_STD_ALLOCATORS */ + + +template <class _CharT, class _Alloc> +class rope : public _Rope_base<_CharT,_Alloc> { public: - typedef charT value_type; - typedef ptrdiff_t difference_type; - typedef size_t size_type; - typedef charT const_reference; - typedef const charT* const_pointer; - typedef __rope_iterator<charT,Alloc> iterator; - typedef __rope_const_iterator<charT,Alloc> const_iterator; - typedef __rope_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>; + typedef _CharT value_type; + typedef ptrdiff_t difference_type; + typedef size_t size_type; + typedef _CharT const_reference; + typedef const _CharT* const_pointer; + typedef _Rope_iterator<_CharT,_Alloc> iterator; + typedef _Rope_const_iterator<_CharT,_Alloc> const_iterator; + typedef _Rope_char_ref_proxy<_CharT,_Alloc> reference; + typedef _Rope_char_ptr_proxy<_CharT,_Alloc> pointer; + + friend class _Rope_iterator<_CharT,_Alloc>; + friend class _Rope_const_iterator<_CharT,_Alloc>; + friend struct _Rope_RopeRep<_CharT,_Alloc>; + friend class _Rope_iterator_base<_CharT,_Alloc>; + friend class _Rope_char_ptr_proxy<_CharT,_Alloc>; + friend class _Rope_char_ref_proxy<_CharT,_Alloc>; + friend struct _Rope_RopeSubstring<_CharT,_Alloc>; protected: - typedef __GC_CONST charT * cstrptr; + typedef _Rope_base<_CharT,_Alloc> _Base; + typedef typename _Base::allocator_type allocator_type; +# ifdef __STL_USE_NAMESPACES + using _Base::_M_tree_ptr; +# endif + typedef __GC_CONST _CharT* _Cstrptr; # ifdef __STL_SGI_THREADS - static cstrptr atomic_swap(cstrptr *p, cstrptr q) { + static _Cstrptr _S_atomic_swap(_Cstrptr* __p, _Cstrptr __q) { # if __mips < 3 || !(defined (_ABIN32) || defined(_ABI64)) - return (cstrptr) test_and_set((unsigned long *)p, - (unsigned long)q); -# else - return (cstrptr) __test_and_set((unsigned long *)p, - (unsigned long)q); -# endif + return (_Cstrptr) test_and_set((unsigned long*)__p, + (unsigned long)__q); +# else + return (_Cstrptr) __test_and_set((unsigned long*)__p, + (unsigned long)__q); +# endif } # elif defined(__STL_WIN32THREADS) - static cstrptr atomic_swap(cstrptr *p, cstrptr q) { - return (cstrptr) InterlockedExchange((LPLONG)p, (LONG)q); - } -# elif defined(__STL_PTHREADS) - // This should be portable, but performance is expected - // to be quite awful. This really needs platform specific - // code. - static pthread_mutex_t swap_lock; - static cstrptr atomic_swap(cstrptr *p, cstrptr q) { - pthread_mutex_lock(&swap_lock); - cstrptr result = *p; - *p = q; - pthread_mutex_unlock(&swap_lock); - return result; + static _Cstrptr _S_atomic_swap(_Cstrptr* __p, _Cstrptr __q) { + return (_Cstrptr) InterlockedExchange( + (LPLONG)__p, (LONG)__q); + } +# elif defined(__STL_PTHREADS) + // This should be portable, but performance is expected + // to be quite awful. This really needs platform specific + // code. + static pthread_mutex_t _S_swap_lock; + static _Cstrptr _S_atomic_swap(_Cstrptr* __p, _Cstrptr __q) { + pthread_mutex_lock(&_S_swap_lock); + _Cstrptr __result = *__p; + *__p = __q; + pthread_mutex_unlock(&_S_swap_lock); + return __result; + } +# else + static _Cstrptr _S_atomic_swap(_Cstrptr* __p, _Cstrptr __q) { + _Cstrptr __result = *__p; + *__p = __q; + return __result; } -# else - static cstrptr atomic_swap(cstrptr *p, cstrptr q) { - cstrptr result = *p; - *p = q; - return result; - } # endif - static charT empty_c_str[1]; - - typedef simple_alloc<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); - } + static _CharT _S_empty_c_str[1]; + + static bool _S_is0(_CharT __c) { return __c == _S_eos((_CharT*)0); } + enum { _S_copy_max = 23 }; + // For strings shorter than _S_copy_max, we copy to + // concatenate. + + typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep; + typedef _Rope_RopeConcatenation<_CharT,_Alloc> _RopeConcatenation; + typedef _Rope_RopeLeaf<_CharT,_Alloc> _RopeLeaf; + typedef _Rope_RopeFunction<_CharT,_Alloc> _RopeFunction; + typedef _Rope_RopeSubstring<_CharT,_Alloc> _RopeSubstring; + + // Retrieve a character at the indicated position. + static _CharT _S_fetch(_RopeRep* __r, size_type __pos); + +# ifndef __GC + // Obtain a pointer to the character at the indicated position. + // The pointer can be used to change the character. + // If such a pointer cannot be produced, as is frequently the + // case, 0 is returned instead. + // (Returns nonzero only if all nodes in the path have a refcount + // of 1.) + static _CharT* _S_fetch_ptr(_RopeRep* __r, size_type __pos); +# endif + + static bool _S_apply_to_pieces( + // should be template parameter + _Rope_char_consumer<_CharT>& __c, + const _RopeRep* __r, + size_t __begin, size_t __end); + // begin and end are assumed to be in range. + +# ifndef __GC + static void _S_unref(_RopeRep* __t) + { + _RopeRep::_S_unref(__t); + } + static void _S_ref(_RopeRep* __t) + { + _RopeRep::_S_ref(__t); + } # else /* __GC */ - static void unref(RopeBase* t) {} - static void ref(RopeBase* t) {} + static void _S_unref(_RopeRep*) {} + static void _S_ref(_RopeRep*) {} # endif # ifdef __GC - typedef __rope_RopeBase<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. + typedef _Rope_RopeRep<_CharT,_Alloc>* _Self_destruct_ptr; +# else + typedef _Rope_self_destruct_ptr<_CharT,_Alloc> _Self_destruct_ptr; +# endif + + // _Result is counted in refcount. + static _RopeRep* _S_substring(_RopeRep* __base, + size_t __start, size_t __endp1); + + static _RopeRep* _S_concat_char_iter(_RopeRep* __r, + const _CharT* __iter, size_t __slen); + // Concatenate rope and char ptr, copying __s. + // Should really take an arbitrary iterator. + // Result is counted in refcount. + static _RopeRep* _S_destr_concat_char_iter(_RopeRep* __r, + const _CharT* __iter, size_t __slen) + // As above, but one reference to __r is about to be + // destroyed. Thus the pieces may be recycled if all + // relevent reference counts are 1. +# ifdef __GC + // We can't really do anything since refcounts are unavailable. + { return _S_concat_char_iter(__r, __iter, __slen); } +# else + ; +# endif + + static _RopeRep* _S_concat(_RopeRep* __left, _RopeRep* __right); + // General concatenation on _RopeRep. _Result + // has refcount of 1. Adjusts argument refcounts. public: - void apply_to_pieces( size_t begin, size_t end, - __rope_char_consumer<charT>& c) const { - apply_to_pieces(c, tree_ptr, begin, end); - } + void apply_to_pieces( size_t __begin, size_t __end, + _Rope_char_consumer<_CharT>& __c) const { + _S_apply_to_pieces(__c, _M_tree_ptr, __begin, __end); + } protected: - static size_t rounded_up_size(size_t n) { - return RopeBase::rounded_up_size(n); - } - - static size_t allocated_capacity(size_t n) { - if (__is_basic_char_type((charT *)0)) { - return rounded_up_size(n) - 1; - } else { - return rounded_up_size(n); - } - } - - // s should really be an arbitrary input iterator. - // Adds a trailing NULL for basic char types. - static charT * alloc_copy(const charT *s, size_t size) - { - charT * result = DataAlloc::allocate(rounded_up_size(size)); - - uninitialized_copy_n(s, size, result); - __cond_store_eos(result[size]); - return(result); - } - - // Basic constructors for rope tree nodes. - // These return tree nodes with a 0 reference count. - static RopeLeaf * RopeLeaf_from_char_ptr(__GC_CONST charT *s, - size_t size); - // Takes ownership of its argument. - // Result has refcount 1. - // In the nonGC, basic_char_type case it assumes that s - // is eos-terminated. - // In the nonGC case, it was allocated from Alloc with - // rounded_up_size(size). - - static RopeLeaf * RopeLeaf_from_unowned_char_ptr(const charT *s, - size_t size) { - charT * buf = alloc_copy(s, size); + static size_t _S_rounded_up_size(size_t __n) { + return _RopeLeaf::_S_rounded_up_size(__n); + } + + static size_t _S_allocated_capacity(size_t __n) { + if (_S_is_basic_char_type((_CharT*)0)) { + return _S_rounded_up_size(__n) - 1; + } else { + return _S_rounded_up_size(__n); + } + } + + // Allocate and construct a RopeLeaf using the supplied allocator + // Takes ownership of s instead of copying. + static _RopeLeaf* _S_new_RopeLeaf(__GC_CONST _CharT *__s, + size_t __size, allocator_type __a) + { +# ifdef __STL_USE_STD_ALLOCATORS + _RopeLeaf* __space = _LAllocator(__a).allocate(1); +# else + _RopeLeaf* __space = _L_allocate(1); +# endif + return new(__space) _RopeLeaf(__s, __size, __a); + } + + static _RopeConcatenation* _S_new_RopeConcatenation( + _RopeRep* __left, _RopeRep* __right, + allocator_type __a) + { +# ifdef __STL_USE_STD_ALLOCATORS + _RopeConcatenation* __space = _CAllocator(__a).allocate(1); +# else + _RopeConcatenation* __space = _C_allocate(1); +# endif + return new(__space) _RopeConcatenation(__left, __right, __a); + } + + static _RopeFunction* _S_new_RopeFunction(char_producer<_CharT>* __f, + size_t __size, bool __d, allocator_type __a) + { +# ifdef __STL_USE_STD_ALLOCATORS + _RopeFunction* __space = _FAllocator(__a).allocate(1); +# else + _RopeFunction* __space = _F_allocate(1); +# endif + return new(__space) _RopeFunction(__f, __size, __d, __a); + } + + static _RopeSubstring* _S_new_RopeSubstring( + _Rope_RopeRep<_CharT,_Alloc>* __b, size_t __s, + size_t __l, allocator_type __a) + { +# ifdef __STL_USE_STD_ALLOCATORS + _RopeSubstring* __space = _SAllocator(__a).allocate(1); +# else + _RopeSubstring* __space = _S_allocate(1); +# endif + return new(__space) _RopeSubstring(__b, __s, __l, __a); + } + +# ifdef __STL_USE_STD_ALLOCATORS + static + _RopeLeaf* _S_RopeLeaf_from_unowned_char_ptr(const _CharT *__s, + size_t __size, allocator_type __a) +# define __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __size, __a) \ + _S_RopeLeaf_from_unowned_char_ptr(__s, __size, __a) +# else + static + _RopeLeaf* _S_RopeLeaf_from_unowned_char_ptr2(const _CharT* __s, + size_t __size) +# define __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __size, __a) \ + _S_RopeLeaf_from_unowned_char_ptr2(__s, __size) +# endif + { + if (0 == __size) return 0; +# ifdef __STL_USE_STD_ALLOCATORS + _CharT* __buf = __a.allocate(_S_rounded_up_size(__size)); +# else + _CharT* __buf = _Data_allocate(_S_rounded_up_size(__size)); + allocator_type __a = allocator_type(); +# endif + + uninitialized_copy_n(__s, __size, __buf); + _S_cond_store_eos(__buf[__size]); __STL_TRY { - return RopeLeaf_from_char_ptr(buf, size); + return _S_new_RopeLeaf(__buf, __size, __a); } - __STL_UNWIND(RopeBase::free_string(buf, size)) - } - - - // Concatenation of nonempty strings. - // Always builds a concatenation node. - // Rebalances if the result is too deep. - // Result has refcount 1. - // Does not increment left and right ref counts even though - // they are referenced. - static RopeBase * tree_concat(RopeBase * left, RopeBase * right); - - // Result has refcount 1. - // If delete_fn is true, then fn is deleted when the rope - // becomes inaccessible. - static RopeFunction * RopeFunction_from_fn - (char_producer<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. + __STL_UNWIND(_RopeRep::__STL_FREE_STRING(__buf, __size, __a)) + } + + + // Concatenation of nonempty strings. + // Always builds a concatenation node. + // Rebalances if the result is too deep. + // Result has refcount 1. + // Does not increment left and right ref counts even though + // they are referenced. + static _RopeRep* + _S_tree_concat(_RopeRep* __left, _RopeRep* __right); + + // Concatenation helper functions + static _RopeLeaf* + _S_leaf_concat_char_iter(_RopeLeaf* __r, + const _CharT* __iter, size_t __slen); + // Concatenate by copying leaf. + // should take an arbitrary iterator + // result has refcount 1. +# ifndef __GC + static _RopeLeaf* _S_destr_leaf_concat_char_iter + (_RopeLeaf* __r, const _CharT* __iter, size_t __slen); + // A version that potentially clobbers __r if __r->_M_refcount == 1. # endif - // A helper function for exponentiating strings. - // This uses a nonstandard refcount convention. - // The result has refcount 0. - struct concat_fn; - friend struct rope<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); + // A helper function for exponentiating strings. + // This uses a nonstandard refcount convention. + // The result has refcount 0. + struct _Concat_fn + : public binary_function<rope<_CharT,_Alloc>, + rope<_CharT,_Alloc>, + rope<_CharT,_Alloc> > { + rope operator() (const rope& __x, const rope& __y) { + return __x + __y; + } + }; + + // Needed by the call to "power" used to build ropes + // consisting of n copies of a character. + friend rope identity_element(_Concat_fn) + { return rope<_CharT,_Alloc>(); } + + static size_t _S_char_ptr_len(const _CharT* __s); + // slightly generalized strlen + + rope(_RopeRep* __t, const allocator_type& __a = allocator_type()) + : _Base(__t,__a) { } + + + // Copy __r to the _CharT buffer. + // Returns __buffer + __r->_M_size. + // Assumes that buffer is uninitialized. + static _CharT* _S_flatten(_RopeRep* __r, _CharT* __buffer); + + // Again, with explicit starting position and length. + // Assumes that buffer is uninitialized. + static _CharT* _S_flatten(_RopeRep* __r, + size_t __start, size_t __len, + _CharT* __buffer); + + static const unsigned long + _S_min_len[_RopeRep::_S_max_rope_depth + 1]; + + static bool _S_is_balanced(_RopeRep* __r) + { return (__r->_M_size >= _S_min_len[__r->_M_depth]); } + + static bool _S_is_almost_balanced(_RopeRep* __r) + { return (__r->_M_depth == 0 || + __r->_M_size >= _S_min_len[__r->_M_depth - 1]); } + + static bool _S_is_roughly_balanced(_RopeRep* __r) + { return (__r->_M_depth <= 1 || + __r->_M_size >= _S_min_len[__r->_M_depth - 2]); } + + // Assumes the result is not empty. + static _RopeRep* _S_concat_and_set_balanced(_RopeRep* __left, + _RopeRep* __right) + { + _RopeRep* __result = _S_concat(__left, __right); + if (_S_is_balanced(__result)) __result->_M_is_balanced = true; + return __result; + } + + // The basic rebalancing operation. Logically copies the + // rope. The result has refcount of 1. The client will + // usually decrement the reference count of __r. + // The result is within height 2 of balanced by the above + // definition. + static _RopeRep* _S_balance(_RopeRep* __r); + + // Add all unbalanced subtrees to the forest of balanceed trees. + // Used only by balance. + static void _S_add_to_forest(_RopeRep*__r, _RopeRep** __forest); + + // Add __r to forest, assuming __r is already balanced. + static void _S_add_leaf_to_forest(_RopeRep* __r, _RopeRep** __forest); + + // Print to stdout, exposing structure + static void _S_dump(_RopeRep* __r, int __indent = 0); + + // Return -1, 0, or 1 if __x < __y, __x == __y, or __x > __y resp. + static int _S_compare(const _RopeRep* __x, const _RopeRep* __y); public: - bool empty() const { return 0 == tree_ptr; } - - // Comparison member function. This is public only for those - // clients that need a ternary comparison. Others - // should use the comparison operators below. - int compare(const rope &y) const { - return compare(tree_ptr, y.tree_ptr); - } - - rope(const charT *s) - { - size_t len = char_ptr_len(s); - - if (0 == len) { - tree_ptr = 0; - } else { - tree_ptr = RopeLeaf_from_unowned_char_ptr(s, len); -# ifndef __GC - __stl_assert(1 == tree_ptr -> refcount); -# endif - } - } - - rope(const charT *s, size_t len) - { - if (0 == len) { - tree_ptr = 0; - } else { - tree_ptr = RopeLeaf_from_unowned_char_ptr(s, len); - } - } - - rope(const charT *s, charT *e) - { - size_t len = e - s; - - if (0 == len) { - tree_ptr = 0; - } else { - tree_ptr = RopeLeaf_from_unowned_char_ptr(s, len); - } - } - - rope(const const_iterator& s, const const_iterator& e) - { - tree_ptr = substring(s.root, s.current_pos, e.current_pos); - } - - rope(const iterator& s, const iterator& e) - { - tree_ptr = substring(s.root, s.current_pos, e.current_pos); - } - - rope(charT c) - { - charT * buf = DataAlloc::allocate(rounded_up_size(1)); - - construct(buf, c); - __STL_TRY { - tree_ptr = RopeLeaf_from_char_ptr(buf, 1); + bool empty() const { return 0 == _M_tree_ptr; } + + // Comparison member function. This is public only for those + // clients that need a ternary comparison. Others + // should use the comparison operators below. + int compare(const rope& __y) const { + return _S_compare(_M_tree_ptr, __y._M_tree_ptr); + } + + rope(const _CharT* __s, const allocator_type& __a = allocator_type()) + : _Base(__STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, _S_char_ptr_len(__s), + __a),__a) + { } + + rope(const _CharT* __s, size_t __len, + const allocator_type& __a = allocator_type()) + : _Base(__STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __len, __a), __a) + { } + + // Should perhaps be templatized with respect to the iterator type + // and use Sequence_buffer. (It should perhaps use sequence_buffer + // even now.) + rope(const _CharT *__s, const _CharT *__e, + const allocator_type& __a = allocator_type()) + : _Base(__STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __e - __s, __a), __a) + { } + + rope(const const_iterator& __s, const const_iterator& __e, + const allocator_type& __a = allocator_type()) + : _Base(_S_substring(__s._M_root, __s._M_current_pos, + __e._M_current_pos), __a) + { } + + rope(const iterator& __s, const iterator& __e, + const allocator_type& __a = allocator_type()) + : _Base(_S_substring(__s._M_root, __s._M_current_pos, + __e._M_current_pos), __a) + { } + + rope(_CharT __c, const allocator_type& __a = allocator_type()) + : _Base(__a) + { + _CharT* __buf = _Data_allocate(_S_rounded_up_size(1)); + + construct(__buf, __c); + __STL_TRY { + _M_tree_ptr = _S_new_RopeLeaf(__buf, 1, __a); } - __STL_UNWIND(RopeBase::free_string(buf, 1)) - } - - rope(size_t n, charT c); - - // Should really be templatized with respect to the iterator type - // and use sequence_buffer. (It should perhaps use sequence_buffer - // even now.) - rope(const charT *i, const charT *j) - { - if (i == j) { - tree_ptr = 0; - } else { - size_t len = j - i; - tree_ptr = RopeLeaf_from_unowned_char_ptr(i, len); - } - } - - rope() - { - tree_ptr = 0; - } - - // Construct a rope from a function that can compute its members - rope(char_producer<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(_RopeRep::__STL_FREE_STRING(__buf, 1, __a)) + } + + rope(size_t __n, _CharT __c, + const allocator_type& __a = allocator_type()); + + rope(const allocator_type& __a = allocator_type()) + : _Base(0, __a) {} + + // Construct a rope from a function that can compute its members + rope(char_producer<_CharT> *__fn, size_t __len, bool __delete_fn, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { + _M_tree_ptr = (0 == __len) ? + 0 : _S_new_RopeFunction(__fn, __len, __delete_fn, __a); + } + + rope(const rope& __x, const allocator_type& __a = allocator_type()) + : _Base(__x._M_tree_ptr, __a) + { + _S_ref(_M_tree_ptr); + } + + ~rope() + { + _S_unref(_M_tree_ptr); + } + + rope& operator=(const rope& __x) + { + _RopeRep* __old = _M_tree_ptr; +# ifdef __STL_USE_STD_ALLOCATORS + __stl_assert(get_allocator() == __x.get_allocator()); +# endif + _M_tree_ptr = __x._M_tree_ptr; + _S_ref(_M_tree_ptr); + _S_unref(__old); + return(*this); + } + + void push_back(_CharT __x) + { + _RopeRep* __old = _M_tree_ptr; + _M_tree_ptr = _S_concat_char_iter(_M_tree_ptr, &__x, 1); + _S_unref(__old); + } + + void pop_back() + { + _RopeRep* __old = _M_tree_ptr; + _M_tree_ptr = + _S_substring(_M_tree_ptr, 0, _M_tree_ptr->_M_size - 1); + _S_unref(__old); + } + + _CharT back() const + { + return _S_fetch(_M_tree_ptr, _M_tree_ptr->_M_size - 1); + } + + void push_front(_CharT __x) + { + _RopeRep* __old = _M_tree_ptr; + _RopeRep* __left = + __STL_ROPE_FROM_UNOWNED_CHAR_PTR(&__x, 1, get_allocator()); + __STL_TRY { + _M_tree_ptr = _S_concat(__left, _M_tree_ptr); + _S_unref(__old); + _S_unref(__left); } - __STL_UNWIND(unref(left)) - } - - void pop_front() - { - RopeBase *old = tree_ptr; - tree_ptr = substring(tree_ptr, 1, tree_ptr -> size); - unref(old); - } - - charT front() const - { - return fetch(tree_ptr, 0); - } - - void balance() - { - RopeBase *old = tree_ptr; - tree_ptr = balance(tree_ptr); - unref(old); - } - - void copy(charT * buffer) const { - destroy(buffer, buffer + size()); - flatten(tree_ptr, buffer); - } - - // This is the copy function from the standard, but - // with the arguments reordered to make it consistent with the - // rest of the interface. - // Note that this guaranteed not to compile if the draft standard - // order is assumed. - size_type copy(size_type pos, size_type n, charT *buffer) const { - size_t sz = size(); - size_t len = (pos + n > sz? sz - pos : n); - - destroy(buffer, buffer + len); - flatten(tree_ptr, pos, len, buffer); - return len; - } - - // Print to stdout, exposing structure. May be useful for - // performance debugging. - void dump() { - dump(tree_ptr); - } - - // Convert to 0 terminated string in new allocated memory. - // Embedded 0s in the input do not terminate the copy. - const charT * c_str() const; - - // As above, but lso use the flattened representation as the - // the new rope representation. - const charT * replace_with_c_str(); - - // Reclaim memory for the c_str generated flattened string. - // Intentionally undocumented, since it's hard to say when this - // is safe for multiple threads. - void delete_c_str () { - if (0 == tree_ptr) return; - if (RopeBase::leaf == tree_ptr -> tag - && ((RopeLeaf *)tree_ptr) -> data == tree_ptr -> c_string) { - // Representation shared - return; - } -# ifndef __GC - tree_ptr -> free_c_string(); -# endif - tree_ptr -> c_string = 0; - } - - charT operator[] (size_type pos) const { - return fetch(tree_ptr, pos); - } - - charT at(size_type pos) const { - // if (pos >= size()) throw out_of_range; - return (*this)[pos]; - } - - const_iterator begin() const { - return(const_iterator(tree_ptr, 0)); - } - - // An easy way to get a const iterator from a non-const container. - const_iterator const_begin() const { - return(const_iterator(tree_ptr, 0)); - } - - const_iterator end() const { - return(const_iterator(tree_ptr, size())); - } - - const_iterator const_end() const { - return(const_iterator(tree_ptr, size())); - } - - size_type size() const { - return(0 == tree_ptr? 0 : tree_ptr -> size); - } - - size_type length() const { - return size(); - } - - size_type max_size() const { - return min_len[RopeBase::max_rope_depth-1] - 1; - // Guarantees that the result can be sufficirntly - // balanced. Longer ropes will probably still work, - // but it's harder to make guarantees. - } + __STL_UNWIND(_S_unref(__left)) + } + + void pop_front() + { + _RopeRep* __old = _M_tree_ptr; + _M_tree_ptr = _S_substring(_M_tree_ptr, 1, _M_tree_ptr->_M_size); + _S_unref(__old); + } + + _CharT front() const + { + return _S_fetch(_M_tree_ptr, 0); + } + + void balance() + { + _RopeRep* __old = _M_tree_ptr; + _M_tree_ptr = _S_balance(_M_tree_ptr); + _S_unref(__old); + } + + void copy(_CharT* __buffer) const { + destroy(__buffer, __buffer + size()); + _S_flatten(_M_tree_ptr, __buffer); + } + + // This is the copy function from the standard, but + // with the arguments reordered to make it consistent with the + // rest of the interface. + // Note that this guaranteed not to compile if the draft standard + // order is assumed. + size_type copy(size_type __pos, size_type __n, _CharT* __buffer) const + { + size_t __size = size(); + size_t __len = (__pos + __n > __size? __size - __pos : __n); + + destroy(__buffer, __buffer + __len); + _S_flatten(_M_tree_ptr, __pos, __len, __buffer); + return __len; + } + + // Print to stdout, exposing structure. May be useful for + // performance debugging. + void dump() { + _S_dump(_M_tree_ptr); + } + + // Convert to 0 terminated string in new allocated memory. + // Embedded 0s in the input do not terminate the copy. + const _CharT* c_str() const; + + // As above, but lso use the flattened representation as the + // the new rope representation. + const _CharT* replace_with_c_str(); + + // Reclaim memory for the c_str generated flattened string. + // Intentionally undocumented, since it's hard to say when this + // is safe for multiple threads. + void delete_c_str () { + if (0 == _M_tree_ptr) return; + if (_RopeRep::_S_leaf == _M_tree_ptr->_M_tag && + ((_RopeLeaf*)_M_tree_ptr)->_M_data == + _M_tree_ptr->_M_c_string) { + // Representation shared + return; + } +# ifndef __GC + _M_tree_ptr->_M_free_c_string(); +# endif + _M_tree_ptr->_M_c_string = 0; + } + + _CharT operator[] (size_type __pos) const { + return _S_fetch(_M_tree_ptr, __pos); + } + + _CharT at(size_type __pos) const { + // if (__pos >= size()) throw out_of_range; // XXX + return (*this)[__pos]; + } + + const_iterator begin() const { + return(const_iterator(_M_tree_ptr, 0)); + } + + // An easy way to get a const iterator from a non-const container. + const_iterator const_begin() const { + return(const_iterator(_M_tree_ptr, 0)); + } + + const_iterator end() const { + return(const_iterator(_M_tree_ptr, size())); + } + + const_iterator const_end() const { + return(const_iterator(_M_tree_ptr, size())); + } + + size_type size() const { + return(0 == _M_tree_ptr? 0 : _M_tree_ptr->_M_size); + } + + size_type length() const { + return size(); + } + + size_type max_size() const { + return _S_min_len[_RopeRep::_S_max_rope_depth-1] - 1; + // Guarantees that the result can be sufficirntly + // balanced. Longer ropes will probably still work, + // but it's harder to make guarantees. + } # ifdef __STL_CLASS_PARTIAL_SPECIALIZATION typedef reverse_iterator<const_iterator> const_reverse_iterator; # else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ - typedef reverse_iterator<const_iterator, value_type, const_reference, - difference_type> const_reverse_iterator; + 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; - } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } + + const_reverse_iterator const_rbegin() const { + return const_reverse_iterator(end()); + } + + const_reverse_iterator rend() const { + return const_reverse_iterator(begin()); + } + + const_reverse_iterator const_rend() const { + return const_reverse_iterator(begin()); + } + + friend rope<_CharT,_Alloc> + operator+ __STL_NULL_TMPL_ARGS (const rope<_CharT,_Alloc>& __left, + const rope<_CharT,_Alloc>& __right); + + friend rope<_CharT,_Alloc> + operator+ __STL_NULL_TMPL_ARGS (const rope<_CharT,_Alloc>& __left, + const _CharT* __right); + + friend rope<_CharT,_Alloc> + operator+ __STL_NULL_TMPL_ARGS (const rope<_CharT,_Alloc>& __left, + _CharT __right); + + // The symmetric cases are intentionally omitted, since they're presumed + // to be less common, and we don't handle them as well. + + // The following should really be templatized. + // The first argument should be an input iterator or + // forward iterator with value_type _CharT. + rope& append(const _CharT* __iter, size_t __n) { + _RopeRep* __result = + _S_destr_concat_char_iter(_M_tree_ptr, __iter, __n); + _S_unref(_M_tree_ptr); + _M_tree_ptr = __result; + return *this; + } + + rope& append(const _CharT* __c_string) { + size_t __len = _S_char_ptr_len(__c_string); + append(__c_string, __len); + return(*this); + } + + rope& append(const _CharT* __s, const _CharT* __e) { + _RopeRep* __result = + _S_destr_concat_char_iter(_M_tree_ptr, __s, __e - __s); + _S_unref(_M_tree_ptr); + _M_tree_ptr = __result; + return *this; + } + + rope& append(const_iterator __s, const_iterator __e) { + __stl_assert(__s._M_root == __e._M_root); +# ifdef __STL_USE_STD_ALLOCATORS + __stl_assert(get_allocator() == __s._M_root->get_allocator()); +# endif + _Self_destruct_ptr __appendee(_S_substring( + __s._M_root, __s._M_current_pos, __e._M_current_pos)); + _RopeRep* __result = + _S_concat(_M_tree_ptr, (_RopeRep*)__appendee); + _S_unref(_M_tree_ptr); + _M_tree_ptr = __result; + return *this; + } + + rope& append(_CharT __c) { + _RopeRep* __result = + _S_destr_concat_char_iter(_M_tree_ptr, &__c, 1); + _S_unref(_M_tree_ptr); + _M_tree_ptr = __result; + return *this; + } + + rope& append() { return append(_CharT()); } // XXX why? + + rope& append(const rope& __y) { +# ifdef __STL_USE_STD_ALLOCATORS + __stl_assert(__y.get_allocator() == get_allocator()); +# endif + _RopeRep* __result = _S_concat(_M_tree_ptr, __y._M_tree_ptr); + _S_unref(_M_tree_ptr); + _M_tree_ptr = __result; + return *this; + } + + rope& append(size_t __n, _CharT __c) { + rope<_CharT,_Alloc> __last(__n, __c); + return append(__last); + } + + void swap(rope& __b) { +# ifdef __STL_USE_STD_ALLOCATORS + __stl_assert(get_allocator() == __b.get_allocator()); +# endif + _RopeRep* __tmp = _M_tree_ptr; + _M_tree_ptr = __b._M_tree_ptr; + __b._M_tree_ptr = __tmp; + } protected: - // Result is included in refcount. - static RopeBase * replace(RopeBase *old, size_t pos1, - size_t pos2, RopeBase *r) { - if (0 == old) { ref(r); return r; } - self_destruct_ptr left(substring(old, 0, pos1)); - self_destruct_ptr right(substring(old, pos2, old -> size)); - RopeBase * result; - - if (0 == r) { - result = concat(left, right); - } else { - self_destruct_ptr left_result(concat(left, r)); - result = concat(left_result, right); - } - return result; - } + // Result is included in refcount. + static _RopeRep* replace(_RopeRep* __old, size_t __pos1, + size_t __pos2, _RopeRep* __r) { + if (0 == __old) { _S_ref(__r); return __r; } + _Self_destruct_ptr __left( + _S_substring(__old, 0, __pos1)); + _Self_destruct_ptr __right( + _S_substring(__old, __pos2, __old->_M_size)); + _RopeRep* __result; + +# ifdef __STL_USE_STD_ALLOCATORS + __stl_assert(__old->get_allocator() == __r->get_allocator()); +# endif + if (0 == __r) { + __result = _S_concat(__left, __right); + } else { + _Self_destruct_ptr __left_result(_S_concat(__left, __r)); + __result = _S_concat(__left_result, __right); + } + return __result; + } public: - void insert(size_t p, const rope& r) { - RopeBase * result = replace(tree_ptr, p, p, - r.tree_ptr); - unref(tree_ptr); - tree_ptr = result; - } - - void insert(size_t p, size_t n, charT c) { - rope<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())); - } + void insert(size_t __p, const rope& __r) { + _RopeRep* __result = + replace(_M_tree_ptr, __p, __p, __r._M_tree_ptr); +# ifdef __STL_USE_STD_ALLOCATORS + __stl_assert(get_allocator() == __r.get_allocator()); +# endif + _S_unref(_M_tree_ptr); + _M_tree_ptr = __result; + } + + void insert(size_t __p, size_t __n, _CharT __c) { + rope<_CharT,_Alloc> __r(__n,__c); + insert(__p, __r); + } + + void insert(size_t __p, const _CharT* __i, size_t __n) { + _Self_destruct_ptr __left(_S_substring(_M_tree_ptr, 0, __p)); + _Self_destruct_ptr __right(_S_substring(_M_tree_ptr, __p, size())); + _Self_destruct_ptr __left_result( + _S_concat_char_iter(__left, __i, __n)); + _RopeRep* __result = _S_concat(__left_result, __right); + _S_unref(_M_tree_ptr); + _M_tree_ptr = __result; + } + + void insert(size_t __p, const _CharT* __c_string) { + insert(__p, __c_string, _S_char_ptr_len(__c_string)); + } + + void insert(size_t __p, _CharT __c) { + insert(__p, &__c, 1); + } + + void insert(size_t __p) { + _CharT __c = _CharT(); + insert(__p, &__c, 1); + } + + void insert(size_t __p, const _CharT* __i, const _CharT* __j) { + rope __r(__i, __j); + insert(__p, __r); + } + + void insert(size_t __p, const const_iterator& __i, + const const_iterator& __j) { + rope __r(__i, __j); + insert(__p, __r); + } + + void insert(size_t __p, const iterator& __i, + const iterator& __j) { + rope __r(__i, __j); + insert(__p, __r); + } + + // (position, length) versions of replace operations: + + void replace(size_t __p, size_t __n, const rope& __r) { + _RopeRep* __result = + replace(_M_tree_ptr, __p, __p + __n, __r._M_tree_ptr); + _S_unref(_M_tree_ptr); + _M_tree_ptr = __result; + } + + void replace(size_t __p, size_t __n, + const _CharT* __i, size_t __i_len) { + rope __r(__i, __i_len); + replace(__p, __n, __r); + } + + void replace(size_t __p, size_t __n, _CharT __c) { + rope __r(__c); + replace(__p, __n, __r); + } + + void replace(size_t __p, size_t __n, const _CharT* __c_string) { + rope __r(__c_string); + replace(__p, __n, __r); + } + + void replace(size_t __p, size_t __n, + const _CharT* __i, const _CharT* __j) { + rope __r(__i, __j); + replace(__p, __n, __r); + } + + void replace(size_t __p, size_t __n, + const const_iterator& __i, const const_iterator& __j) { + rope __r(__i, __j); + replace(__p, __n, __r); + } + + void replace(size_t __p, size_t __n, + const iterator& __i, const iterator& __j) { + rope __r(__i, __j); + replace(__p, __n, __r); + } + + // Single character variants: + void replace(size_t __p, _CharT __c) { + iterator __i(this, __p); + *__i = __c; + } + + void replace(size_t __p, const rope& __r) { + replace(__p, 1, __r); + } + + void replace(size_t __p, const _CharT* __i, size_t __i_len) { + replace(__p, 1, __i, __i_len); + } + + void replace(size_t __p, const _CharT* __c_string) { + replace(__p, 1, __c_string); + } + + void replace(size_t __p, const _CharT* __i, const _CharT* __j) { + replace(__p, 1, __i, __j); + } + + void replace(size_t __p, const const_iterator& __i, + const const_iterator& __j) { + replace(__p, 1, __i, __j); + } + + void replace(size_t __p, const iterator& __i, + const iterator& __j) { + replace(__p, 1, __i, __j); + } + + // Erase, (position, size) variant. + void erase(size_t __p, size_t __n) { + _RopeRep* __result = replace(_M_tree_ptr, __p, __p + __n, 0); + _S_unref(_M_tree_ptr); + _M_tree_ptr = __result; + } + + // Erase, single character + void erase(size_t __p) { + erase(__p, __p + 1); + } + + // Insert, iterator variants. + iterator insert(const iterator& __p, const rope& __r) + { insert(__p.index(), __r); return __p; } + iterator insert(const iterator& __p, size_t __n, _CharT __c) + { insert(__p.index(), __n, __c); return __p; } + iterator insert(const iterator& __p, _CharT __c) + { insert(__p.index(), __c); return __p; } + iterator insert(const iterator& __p ) + { insert(__p.index()); return __p; } + iterator insert(const iterator& __p, const _CharT* c_string) + { insert(__p.index(), c_string); return __p; } + iterator insert(const iterator& __p, const _CharT* __i, size_t __n) + { insert(__p.index(), __i, __n); return __p; } + iterator insert(const iterator& __p, const _CharT* __i, + const _CharT* __j) + { insert(__p.index(), __i, __j); return __p; } + iterator insert(const iterator& __p, + const const_iterator& __i, const const_iterator& __j) + { insert(__p.index(), __i, __j); return __p; } + iterator insert(const iterator& __p, + const iterator& __i, const iterator& __j) + { insert(__p.index(), __i, __j); return __p; } + + // Replace, range variants. + void replace(const iterator& __p, const iterator& __q, + const rope& __r) + { replace(__p.index(), __q.index() - __p.index(), __r); } + void replace(const iterator& __p, const iterator& __q, _CharT __c) + { replace(__p.index(), __q.index() - __p.index(), __c); } + void replace(const iterator& __p, const iterator& __q, + const _CharT* __c_string) + { replace(__p.index(), __q.index() - __p.index(), __c_string); } + void replace(const iterator& __p, const iterator& __q, + const _CharT* __i, size_t __n) + { replace(__p.index(), __q.index() - __p.index(), __i, __n); } + void replace(const iterator& __p, const iterator& __q, + const _CharT* __i, const _CharT* __j) + { replace(__p.index(), __q.index() - __p.index(), __i, __j); } + void replace(const iterator& __p, const iterator& __q, + const const_iterator& __i, const const_iterator& __j) + { replace(__p.index(), __q.index() - __p.index(), __i, __j); } + void replace(const iterator& __p, const iterator& __q, + const iterator& __i, const iterator& __j) + { replace(__p.index(), __q.index() - __p.index(), __i, __j); } + + // Replace, iterator variants. + void replace(const iterator& __p, const rope& __r) + { replace(__p.index(), __r); } + void replace(const iterator& __p, _CharT __c) + { replace(__p.index(), __c); } + void replace(const iterator& __p, const _CharT* __c_string) + { replace(__p.index(), __c_string); } + void replace(const iterator& __p, const _CharT* __i, size_t __n) + { replace(__p.index(), __i, __n); } + void replace(const iterator& __p, const _CharT* __i, const _CharT* __j) + { replace(__p.index(), __i, __j); } + void replace(const iterator& __p, const_iterator __i, + const_iterator __j) + { replace(__p.index(), __i, __j); } + void replace(const iterator& __p, iterator __i, iterator __j) + { replace(__p.index(), __i, __j); } + + // Iterator and range variants of erase + iterator erase(const iterator& __p, const iterator& __q) { + size_t __p_index = __p.index(); + erase(__p_index, __q.index() - __p_index); + return iterator(this, __p_index); + } + iterator erase(const iterator& __p) { + size_t __p_index = __p.index(); + erase(__p_index, 1); + return iterator(this, __p_index); + } + + rope substr(size_t __start, size_t __len = 1) const { + return rope<_CharT,_Alloc>( + _S_substring(_M_tree_ptr, __start, __start + __len)); + } + + rope substr(iterator __start, iterator __end) const { + return rope<_CharT,_Alloc>( + _S_substring(_M_tree_ptr, __start.index(), __end.index())); + } + + rope substr(iterator __start) const { + size_t __pos = __start.index(); + return rope<_CharT,_Alloc>( + _S_substring(_M_tree_ptr, __pos, __pos + 1)); + } + + rope substr(const_iterator __start, const_iterator __end) const { + // This might eventually take advantage of the cache in the + // iterator. + return rope<_CharT,_Alloc>( + _S_substring(_M_tree_ptr, __start.index(), __end.index())); + } + + rope<_CharT,_Alloc> substr(const_iterator __start) { + size_t __pos = __start.index(); + return rope<_CharT,_Alloc>( + _S_substring(_M_tree_ptr, __pos, __pos + 1)); + } + + static const size_type npos; + + size_type find(_CharT __c, size_type __pos = 0) const; + size_type find(_CharT* __s, size_type __pos = 0) const { + size_type __result_pos; + const_iterator __result = search(const_begin() + __pos, const_end(), + __s, __s + _S_char_ptr_len(__s)); + __result_pos = __result.index(); +# ifndef __STL_OLD_ROPE_SEMANTICS + if (__result_pos == size()) __result_pos = npos; +# endif + return __result_pos; + } + + iterator mutable_begin() { + return(iterator(this, 0)); + } + + iterator mutable_end() { + return(iterator(this, size())); + } # ifdef __STL_CLASS_PARTIAL_SPECIALIZATION typedef reverse_iterator<iterator> reverse_iterator; # else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ - typedef reverse_iterator<iterator, value_type, reference, - difference_type> reverse_iterator; + 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_rbegin() { + return reverse_iterator(mutable_end()); + } - reverse_iterator mutable_rend() { - return reverse_iterator(mutable_begin()); - } + reverse_iterator mutable_rend() { + return reverse_iterator(mutable_begin()); + } - reference mutable_reference_at(size_type pos) { - return reference(this, pos); - } + reference mutable_reference_at(size_type __pos) { + return reference(this, __pos); + } -# ifdef __STD_STUFF - reference operator[] (size_type pos) { - return charT_ref_proxy(this, pos); - } +# ifdef __STD_STUFF + reference operator[] (size_type __pos) { + return _char_ref_proxy(this, __pos); + } - reference at(size_type pos) { - // if (pos >= size()) throw out_of_range; - return (*this)[pos]; - } + reference at(size_type __pos) { + // if (__pos >= size()) throw out_of_range; // XXX + return (*this)[__pos]; + } - void resize(size_type n, charT c) {} - void resize(size_type n) {} - void reserve(size_type res_arg = 0) {} - size_type capacity() const { - return max_size(); - } + void resize(size_type __n, _CharT __c) {} + void resize(size_type __n) {} + void reserve(size_type __res_arg = 0) {} + size_type capacity() const { + return max_size(); + } - // Stuff below this line is dangerous because it's error prone. - // I would really like to get rid of it. - // copy function with funny arg ordering. - size_type copy(charT *buffer, size_type n, size_type pos = 0) - const { - return copy(pos, n, buffer); - } + // Stuff below this line is dangerous because it's error prone. + // I would really like to get rid of it. + // copy function with funny arg ordering. + size_type copy(_CharT* __buffer, size_type __n, + size_type __pos = 0) const { + return copy(__pos, __n, __buffer); + } - iterator end() { return mutable_end(); } + iterator end() { return mutable_end(); } - iterator begin() { return mutable_begin(); } + iterator begin() { return mutable_begin(); } - reverse_iterator rend() { return mutable_rend(); } + reverse_iterator rend() { return mutable_rend(); } - reverse_iterator rbegin() { return mutable_rbegin(); } + reverse_iterator rbegin() { return mutable_rbegin(); } -# else +# else - const_iterator end() { return const_end(); } + const_iterator end() { return const_end(); } - const_iterator begin() { return const_begin(); } + const_iterator begin() { return const_begin(); } - const_reverse_iterator rend() { return const_rend(); } + const_reverse_iterator rend() { return const_rend(); } - const_reverse_iterator rbegin() { return const_rbegin(); } + const_reverse_iterator rbegin() { return const_rbegin(); } -# endif - +# endif + }; -template <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> +const rope<_CharT, _Alloc>::size_type rope<_CharT, _Alloc>::npos = + (size_type)(-1); + +template <class _CharT, class _Alloc> +inline bool operator== (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y) { + return (__x._M_current_pos == __y._M_current_pos && + __x._M_root == __y._M_root); } -template <class charT, class Alloc> -inline bool operator< (const __rope_const_iterator<charT,Alloc> & x, - const __rope_const_iterator<charT,Alloc> & y) { - return (x.current_pos < y.current_pos); +template <class _CharT, class _Alloc> +inline bool operator< (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y) { + return (__x._M_current_pos < __y._M_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 ptrdiff_t operator-(const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y) { + return (ptrdiff_t)__x._M_current_pos - (ptrdiff_t)__y._M_current_pos; } -template <class charT, class Alloc> -inline __rope_const_iterator<charT,Alloc> -operator-(const __rope_const_iterator<charT,Alloc> & x, - ptrdiff_t n) { - return __rope_const_iterator<charT,Alloc>(x.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._M_root, __x._M_current_pos - __n); } -template <class charT, class Alloc> -inline __rope_const_iterator<charT,Alloc> -operator+(const __rope_const_iterator<charT,Alloc> & x, - ptrdiff_t n) { - return __rope_const_iterator<charT,Alloc>(x.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._M_root, __x._M_current_pos + __n); } -template <class charT, class Alloc> -inline __rope_const_iterator<charT,Alloc> -operator+(ptrdiff_t n, - const __rope_const_iterator<charT,Alloc> & x) { - return __rope_const_iterator<charT,Alloc>(x.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._M_root, __x._M_current_pos + __n); } -template <class charT, class Alloc> -inline bool operator== (const __rope_iterator<charT,Alloc> & x, - const __rope_iterator<charT,Alloc> & y) { - return (x.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._M_current_pos == __y._M_current_pos && + __x._M_root_rope == __y._M_root_rope); } -template <class charT, class Alloc> -inline bool operator< (const __rope_iterator<charT,Alloc> & x, - const __rope_iterator<charT,Alloc> & y) { - return (x.current_pos < y.current_pos); +template <class _CharT, class _Alloc> +inline bool operator< (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y) { + return (__x._M_current_pos < __y._M_current_pos); } -template <class charT, class Alloc> -inline 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 ptrdiff_t operator-(const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y) { + return (ptrdiff_t)__x._M_current_pos - (ptrdiff_t)__y._M_current_pos; } -template <class charT, class Alloc> -inline __rope_iterator<charT,Alloc> -operator-(const __rope_iterator<charT,Alloc> & x, - ptrdiff_t n) { - return __rope_iterator<charT,Alloc>(x.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._M_root_rope, __x._M_current_pos - __n); } -template <class charT, class Alloc> -inline __rope_iterator<charT,Alloc> -operator+(const __rope_iterator<charT,Alloc> & x, - ptrdiff_t n) { - return __rope_iterator<charT,Alloc>(x.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._M_root_rope, __x._M_current_pos + __n); } -template <class charT, class Alloc> -inline __rope_iterator<charT,Alloc> -operator+(ptrdiff_t n, - const __rope_iterator<charT,Alloc> & x) { - return __rope_iterator<charT,Alloc>(x.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._M_root_rope, __x._M_current_pos + __n); } -template <class charT, class Alloc> +template <class _CharT, class _Alloc> inline -rope<charT,Alloc> -operator+ (const rope<charT,Alloc> &left, - const rope<charT,Alloc> &right) +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. +# ifdef __STL_USE_STD_ALLOCATORS + __stl_assert(__left.get_allocator() == __right.get_allocator()); +# endif + return rope<_CharT,_Alloc>( + rope<_CharT,_Alloc>::_S_concat(__left._M_tree_ptr, __right._M_tree_ptr)); + // Inlining this should make it possible to keep __left and + // __right in registers. } -template <class charT, class Alloc> +template <class _CharT, class _Alloc> inline -rope<charT,Alloc>& -operator+= (rope<charT,Alloc> &left, - const rope<charT,Alloc> &right) +rope<_CharT,_Alloc>& +operator+= (rope<_CharT,_Alloc>& __left, + const rope<_CharT,_Alloc>& __right) { - left.append(right); - return left; + __left.append(__right); + return __left; } -template <class charT, class Alloc> +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)); +rope<_CharT,_Alloc> +operator+ (const rope<_CharT,_Alloc>& __left, + const _CharT* __right) { + size_t __rlen = rope<_CharT,_Alloc>::_S_char_ptr_len(__right); + return rope<_CharT,_Alloc>( + rope<_CharT,_Alloc>::_S_concat_char_iter( + __left._M_tree_ptr, __right, __rlen)); } -template <class charT, class Alloc> +template <class _CharT, class _Alloc> inline -rope<charT,Alloc>& -operator+= (rope<charT,Alloc> &left, - const charT* right) { - left.append(right); - return left; +rope<_CharT,_Alloc>& +operator+= (rope<_CharT,_Alloc>& __left, + const _CharT* __right) { + __left.append(__right); + return __left; } -template <class charT, class Alloc> +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)); +rope<_CharT,_Alloc> +operator+ (const rope<_CharT,_Alloc>& __left, _CharT __right) { + return rope<_CharT,_Alloc>( + rope<_CharT,_Alloc>::_S_concat_char_iter( + __left._M_tree_ptr, &__right, 1)); } -template <class charT, class Alloc> +template <class _CharT, class _Alloc> inline -rope<charT,Alloc>& -operator+= (rope<charT,Alloc> &left, charT right) { - left.append(right); - return left; +rope<_CharT,_Alloc>& +operator+= (rope<_CharT,_Alloc>& __left, _CharT __right) { + __left.append(__right); + return __left; } -template <class charT, class Alloc> +template <class _CharT, class _Alloc> bool -operator< (const rope<charT,Alloc> &left, const rope<charT,Alloc> &right) { - return left.compare(right) < 0; +operator< (const rope<_CharT,_Alloc>& __left, + const rope<_CharT,_Alloc>& __right) { + return __left.compare(__right) < 0; } - -template <class charT, class Alloc> + +template <class _CharT, class _Alloc> bool -operator== (const rope<charT,Alloc> &left, const rope<charT,Alloc> &right) { - return left.compare(right) == 0; +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> +inline bool operator== (const _Rope_char_ptr_proxy<_CharT,_Alloc>& __x, + const _Rope_char_ptr_proxy<_CharT,_Alloc>& __y) { + return (__x._M_pos == __y._M_pos && __x._M_root == __y._M_root); } -template<class charT, class Alloc> -ostream& operator<< (ostream& o, const rope<charT, Alloc>& r); - -typedef rope<char, __ALLOC> crope; -typedef rope<wchar_t, __ALLOC> wrope; +template<class _CharT, class _Alloc> +ostream& operator<< (ostream& __o, const rope<_CharT,_Alloc>& __r); + +typedef rope<char> crope; +typedef rope<wchar_t> wrope; -inline crope::reference __mutable_reference_at(crope& c, size_t i) +inline crope::reference __mutable_reference_at(crope& __c, size_t __i) { - return c.mutable_reference_at(i); + return __c.mutable_reference_at(__i); } -inline wrope::reference __mutable_reference_at(wrope& c, size_t i) +inline wrope::reference __mutable_reference_at(wrope& __c, size_t __i) { - return c.mutable_reference_at(i); + return __c.mutable_reference_at(__i); } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER -template <class charT, class Alloc> -inline void swap(rope<charT, Alloc>& x, rope<charT, Alloc>& y) { - x.swap(y); +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); } +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 operator()(const crope& __str) const { - size_t sz = str.size(); + size_t __size = __str.size(); - if (0 == sz) return 0; - return 13*str[0] + 5*str[sz - 1] + sz; + if (0 == __size) return 0; + return 13*__str[0] + 5*__str[__size - 1] + __size; } }; __STL_TEMPLATE_NULL struct hash<wrope> { - size_t operator()(const wrope& str) const + size_t operator()(const wrope& __str) const { - size_t sz = str.size(); + size_t __size = __str.size(); - if (0 == sz) return 0; - return 13*str[0] + 5*str[sz - 1] + sz; + if (0 == __size) return 0; + return 13*__str[0] + 5*__str[__size - 1] + __size; } }; @@ -2105,6 +2533,7 @@ __STL_TEMPLATE_NULL struct hash<wrope> __STL_END_NAMESPACE # include <ropeimpl.h> + # endif /* __SGI_STL_INTERNAL_ROPE_H */ // Local Variables: diff --git a/contrib/libstdc++/stl/stl_set.h b/contrib/libstdc++/stl/stl_set.h index 9ffeaa7..003069c 100644 --- a/contrib/libstdc++/stl/stl_set.h +++ b/contrib/libstdc++/stl/stl_set.h @@ -35,158 +35,176 @@ __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 +#pragma set woff 1375 #endif #ifndef __STL_LIMITED_DEFAULT_TEMPLATES -template <class Key, class Compare = less<Key>, class Alloc = alloc> +template <class _Key, class _Compare = less<_Key>, + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Key) > #else -template <class Key, class Compare, class Alloc = alloc> +template <class _Key, class _Compare, + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Key) > #endif class set { public: // typedefs: - typedef Key key_type; - typedef Key value_type; - typedef Compare key_compare; - typedef Compare value_compare; + typedef _Key key_type; + typedef _Key value_type; + typedef _Compare key_compare; + typedef _Compare value_compare; private: - typedef rb_tree<key_type, value_type, - identity<value_type>, key_compare, Alloc> rep_type; - rep_type t; // red-black tree representing set + typedef _Rb_tree<key_type, value_type, + _Identity<value_type>, key_compare, _Alloc> _Rep_type; + _Rep_type _M_t; // red-black tree representing set public: - typedef typename rep_type::const_pointer pointer; - typedef typename rep_type::const_pointer const_pointer; - typedef typename rep_type::const_reference reference; - typedef typename rep_type::const_reference const_reference; - typedef typename rep_type::const_iterator iterator; - typedef typename rep_type::const_iterator const_iterator; - typedef typename rep_type::const_reverse_iterator reverse_iterator; - typedef typename rep_type::const_reverse_iterator const_reverse_iterator; - typedef typename rep_type::size_type size_type; - typedef typename rep_type::difference_type difference_type; + typedef typename _Rep_type::const_pointer pointer; + typedef typename _Rep_type::const_pointer const_pointer; + typedef typename _Rep_type::const_reference reference; + typedef typename _Rep_type::const_reference const_reference; + typedef typename _Rep_type::const_iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::const_reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + typedef typename _Rep_type::allocator_type allocator_type; // allocation/deallocation - set() : t(Compare()) {} - explicit set(const Compare& comp) : t(comp) {} + set() : _M_t(_Compare(), allocator_type()) {} + explicit set(const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) {} #ifdef __STL_MEMBER_TEMPLATES - template <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); } + template <class _InputIterator> + set(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_unique(__first, __last); } + + template <class _InputIterator> + set(_InputIterator __first, _InputIterator __last, const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); } #else - set(const value_type* first, const value_type* last) - : t(Compare()) { t.insert_unique(first, last); } - set(const value_type* first, const value_type* last, const Compare& comp) - : t(comp) { t.insert_unique(first, last); } - - set(const_iterator first, const_iterator last) - : t(Compare()) { t.insert_unique(first, last); } - set(const_iterator first, const_iterator last, const Compare& comp) - : t(comp) { t.insert_unique(first, last); } + set(const value_type* __first, const value_type* __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_unique(__first, __last); } + + set(const value_type* __first, + const value_type* __last, const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); } + + set(const_iterator __first, const_iterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_unique(__first, __last); } + + set(const_iterator __first, const_iterator __last, const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); } #endif /* __STL_MEMBER_TEMPLATES */ - set(const set<Key, Compare, Alloc>& x) : t(x.t) {} - set<Key, Compare, Alloc>& operator=(const set<Key, Compare, Alloc>& x) { - t = x.t; + set(const set<_Key,_Compare,_Alloc>& __x) : _M_t(__x._M_t) {} + set<_Key,_Compare,_Alloc>& operator=(const set<_Key, _Compare, _Alloc>& __x) + { + _M_t = __x._M_t; return *this; } // accessors: - key_compare key_comp() const { return t.key_comp(); } - value_compare value_comp() const { return t.key_comp(); } - iterator begin() const { return t.begin(); } - iterator end() const { return t.end(); } - reverse_iterator rbegin() const { return t.rbegin(); } - reverse_iterator rend() const { return t.rend(); } - bool empty() const { return t.empty(); } - size_type size() const { return t.size(); } - size_type max_size() const { return t.max_size(); } - void swap(set<Key, Compare, Alloc>& x) { t.swap(x.t); } + key_compare key_comp() const { return _M_t.key_comp(); } + value_compare value_comp() const { return _M_t.key_comp(); } + allocator_type get_allocator() const { return _M_t.get_allocator(); } + + iterator begin() const { return _M_t.begin(); } + iterator end() const { return _M_t.end(); } + reverse_iterator rbegin() const { return _M_t.rbegin(); } + reverse_iterator rend() const { return _M_t.rend(); } + bool empty() const { return _M_t.empty(); } + size_type size() const { return _M_t.size(); } + size_type max_size() const { return _M_t.max_size(); } + void swap(set<_Key,_Compare,_Alloc>& __x) { _M_t.swap(__x._M_t); } // insert/erase - typedef pair<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); + pair<iterator,bool> insert(const value_type& __x) { + pair<typename _Rep_type::iterator, bool> __p = _M_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); + iterator insert(iterator __position, const value_type& __x) { + typedef typename _Rep_type::iterator _Rep_iterator; + return _M_t.insert_unique((_Rep_iterator&)__position, __x); } #ifdef __STL_MEMBER_TEMPLATES - template <class InputIterator> - void insert(InputIterator first, InputIterator last) { - t.insert_unique(first, last); + template <class _InputIterator> + void insert(_InputIterator __first, _InputIterator __last) { + _M_t.insert_unique(__first, __last); } #else - void insert(const_iterator first, const_iterator last) { - t.insert_unique(first, last); + void insert(const_iterator __first, const_iterator __last) { + _M_t.insert_unique(__first, __last); } - void insert(const value_type* first, const value_type* last) { - t.insert_unique(first, last); + void insert(const value_type* __first, const value_type* __last) { + _M_t.insert_unique(__first, __last); } #endif /* __STL_MEMBER_TEMPLATES */ - void erase(iterator position) { - typedef typename rep_type::iterator rep_iterator; - t.erase((rep_iterator&)position); + void erase(iterator __position) { + typedef typename _Rep_type::iterator _Rep_iterator; + _M_t.erase((_Rep_iterator&)__position); } - size_type erase(const key_type& x) { - return t.erase(x); + size_type erase(const key_type& __x) { + return _M_t.erase(__x); } - void erase(iterator first, iterator last) { - typedef typename rep_type::iterator rep_iterator; - t.erase((rep_iterator&)first, (rep_iterator&)last); + void erase(iterator __first, iterator __last) { + typedef typename _Rep_type::iterator _Rep_iterator; + _M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last); } - void clear() { t.clear(); } + void clear() { _M_t.clear(); } // set operations: - iterator find(const key_type& x) const { return t.find(x); } - size_type count(const key_type& x) const { return t.count(x); } - iterator lower_bound(const key_type& x) const { - return t.lower_bound(x); + iterator find(const key_type& __x) const { return _M_t.find(__x); } + size_type count(const key_type& __x) const { return _M_t.count(__x); } + iterator lower_bound(const key_type& __x) const { + return _M_t.lower_bound(__x); } - iterator upper_bound(const key_type& x) const { - return t.upper_bound(x); + iterator upper_bound(const key_type& __x) const { + return _M_t.upper_bound(__x); } - pair<iterator,iterator> equal_range(const key_type& x) const { - return t.equal_range(x); + pair<iterator,iterator> equal_range(const key_type& __x) const { + return _M_t.equal_range(__x); } friend bool operator== __STL_NULL_TMPL_ARGS (const set&, const set&); friend bool operator< __STL_NULL_TMPL_ARGS (const set&, const set&); }; -template <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._M_t == __y._M_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; +template <class _Key, class _Compare, class _Alloc> +inline bool operator<(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y) { + return __x._M_t < __y._M_t; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER -template <class Key, class Compare, class Alloc> -inline void swap(set<Key, Compare, Alloc>& x, - set<Key, Compare, Alloc>& y) { - x.swap(y); +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 +#pragma reset woff 1375 #endif __STL_END_NAMESPACE diff --git a/contrib/libstdc++/stl/stl_slist.h b/contrib/libstdc++/stl/stl_slist.h index f31ea9e..6da234d 100644 --- a/contrib/libstdc++/stl/stl_slist.h +++ b/contrib/libstdc++/stl/stl_slist.h @@ -24,704 +24,908 @@ __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 +#pragma set woff 1375 #endif -struct __slist_node_base +struct _Slist_node_base { - __slist_node_base* next; + _Slist_node_base* _M_next; }; -inline __slist_node_base* __slist_make_link(__slist_node_base* prev_node, - __slist_node_base* new_node) +inline _Slist_node_base* +__slist_make_link(_Slist_node_base* __prev_node, + _Slist_node_base* __new_node) { - new_node->next = prev_node->next; - prev_node->next = new_node; - return new_node; + __new_node->_M_next = __prev_node->_M_next; + __prev_node->_M_next = __new_node; + return __new_node; } -inline __slist_node_base* __slist_previous(__slist_node_base* head, - const __slist_node_base* node) +inline _Slist_node_base* +__slist_previous(_Slist_node_base* __head, + const _Slist_node_base* __node) { - while (head && head->next != node) - head = head->next; - return head; + while (__head && __head->_M_next != __node) + __head = __head->_M_next; + return __head; } -inline const __slist_node_base* __slist_previous(const __slist_node_base* head, - const __slist_node_base* node) +inline const _Slist_node_base* +__slist_previous(const _Slist_node_base* __head, + const _Slist_node_base* __node) { - while (head && head->next != node) - head = head->next; - return head; + while (__head && __head->_M_next != __node) + __head = __head->_M_next; + return __head; } -inline void __slist_splice_after(__slist_node_base* pos, - __slist_node_base* before_first, - __slist_node_base* before_last) +inline void __slist_splice_after(_Slist_node_base* __pos, + _Slist_node_base* __before_first, + _Slist_node_base* __before_last) { - if (pos != before_first && pos != before_last) { - __slist_node_base* first = before_first->next; - __slist_node_base* after = pos->next; - before_first->next = before_last->next; - pos->next = first; - before_last->next = after; + if (__pos != __before_first && __pos != __before_last) { + _Slist_node_base* __first = __before_first->_M_next; + _Slist_node_base* __after = __pos->_M_next; + __before_first->_M_next = __before_last->_M_next; + __pos->_M_next = __first; + __before_last->_M_next = __after; } } -inline __slist_node_base* __slist_reverse(__slist_node_base* node) +inline _Slist_node_base* __slist_reverse(_Slist_node_base* __node) { - __slist_node_base* result = node; - node = node->next; - result->next = 0; - while(node) { - __slist_node_base* next = node->next; - node->next = result; - result = node; - node = next; - } - return result; + _Slist_node_base* __result = __node; + __node = __node->_M_next; + __result->_M_next = 0; + while(__node) { + _Slist_node_base* __next = __node->_M_next; + __node->_M_next = __result; + __result = __node; + __node = __next; + } + return __result; } -template <class T> -struct __slist_node : public __slist_node_base +inline size_t __slist_size(_Slist_node_base* __node) { - T data; + size_t __result = 0; + for ( ; __node != 0; __node = __node->_M_next) + ++__result; + return __result; +} + +template <class _Tp> +struct _Slist_node : public _Slist_node_base +{ + _Tp _M_data; }; -struct __slist_iterator_base +struct _Slist_iterator_base { - typedef size_t size_type; - typedef ptrdiff_t difference_type; + typedef size_t size_type; + typedef ptrdiff_t difference_type; typedef forward_iterator_tag iterator_category; - __slist_node_base* node; + _Slist_node_base* _M_node; - __slist_iterator_base(__slist_node_base* x) : node(x) {} - void incr() { node = node->next; } + _Slist_iterator_base(_Slist_node_base* __x) : _M_node(__x) {} + void _M_incr() { _M_node = _M_node->_M_next; } - bool operator==(const __slist_iterator_base& x) const { - return node == x.node; + bool operator==(const _Slist_iterator_base& __x) const { + return _M_node == __x._M_node; } - bool operator!=(const __slist_iterator_base& x) const { - return node != x.node; + bool operator!=(const _Slist_iterator_base& __x) const { + return _M_node != __x._M_node; } }; -template <class T, class Ref, class Ptr> -struct __slist_iterator : public __slist_iterator_base +template <class _Tp, 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 _Slist_iterator<_Tp, _Tp&, _Tp*> iterator; + typedef _Slist_iterator<_Tp, const _Tp&, const _Tp*> const_iterator; + typedef _Slist_iterator<_Tp, _Ref, _Ptr> _Self; - typedef T value_type; - typedef Ptr pointer; - typedef Ref reference; - typedef __slist_node<T> list_node; + typedef _Tp value_type; + typedef _Ptr pointer; + typedef _Ref reference; + typedef _Slist_node<_Tp> _Node; - __slist_iterator(list_node* x) : __slist_iterator_base(x) {} - __slist_iterator() : __slist_iterator_base(0) {} - __slist_iterator(const iterator& x) : __slist_iterator_base(x.node) {} + _Slist_iterator(_Node* __x) : _Slist_iterator_base(__x) {} + _Slist_iterator() : _Slist_iterator_base(0) {} + _Slist_iterator(const iterator& __x) : _Slist_iterator_base(__x._M_node) {} - reference operator*() const { return ((list_node*) node)->data; } + reference operator*() const { return ((_Node*) _M_node)->_M_data; } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ - self& operator++() + _Self& operator++() { - incr(); + _M_incr(); return *this; } - self operator++(int) + _Self operator++(int) { - self tmp = *this; - incr(); - return tmp; + _Self __tmp = *this; + _M_incr(); + return __tmp; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION -inline ptrdiff_t* -distance_type(const __slist_iterator_base&) -{ +inline ptrdiff_t* distance_type(const _Slist_iterator_base&) { return 0; } -inline forward_iterator_tag -iterator_category(const __slist_iterator_base&) -{ +inline forward_iterator_tag iterator_category(const _Slist_iterator_base&) { return forward_iterator_tag(); } -template <class T, class Ref, class Ptr> -inline T* -value_type(const __slist_iterator<T, Ref, Ptr>&) { +template <class _Tp, class _Ref, class _Ptr> +inline _Tp* value_type(const _Slist_iterator<_Tp, _Ref, _Ptr>&) { return 0; } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ -inline size_t __slist_size(__slist_node_base* node) +// Base class that encapsulates details of allocators. Three cases: +// an ordinary standard-conforming allocator, a standard-conforming +// allocator with no non-static data, and an SGI-style allocator. +// This complexity is necessary only because we're worrying about backward +// compatibility and because we want to avoid wasting storage on an +// allocator instance if it isn't necessary. + +#ifdef __STL_USE_STD_ALLOCATORS + +// Base for general standard-conforming allocators. +template <class _Tp, class _Allocator, bool _IsStatic> +class _Slist_alloc_base { +public: + typedef typename _Alloc_traits<_Tp,_Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return _M_node_allocator; } + + _Slist_alloc_base(const allocator_type& __a) : _M_node_allocator(__a) {} + +protected: + _Slist_node<_Tp>* _M_get_node() + { return _M_node_allocator.allocate(1); } + void _M_put_node(_Slist_node<_Tp>* __p) + { _M_node_allocator.deallocate(__p, 1); } + +protected: + typename _Alloc_traits<_Slist_node<_Tp>,_Allocator>::allocator_type + _M_node_allocator; + _Slist_node_base _M_head; +}; + +// Specialization for instanceless allocators. +template <class _Tp, class _Allocator> +class _Slist_alloc_base<_Tp,_Allocator, true> { +public: + typedef typename _Alloc_traits<_Tp,_Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Slist_alloc_base(const allocator_type&) {} + +protected: + typedef typename _Alloc_traits<_Slist_node<_Tp>, _Allocator>::_Alloc_type + _Alloc_type; + _Slist_node<_Tp>* _M_get_node() { return _Alloc_type::allocate(1); } + void _M_put_node(_Slist_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); } + +protected: + _Slist_node_base _M_head; +}; + + +template <class _Tp, class _Alloc> +struct _Slist_base + : public _Slist_alloc_base<_Tp, _Alloc, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> { - size_t result = 0; - for ( ; node != 0; node = node->next) - ++result; - return result; + typedef _Slist_alloc_base<_Tp, _Alloc, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> + _Base; + typedef typename _Base::allocator_type allocator_type; + + _Slist_base(const allocator_type& __a) : _Base(__a) { _M_head._M_next = 0; } + ~_Slist_base() { _M_erase_after(&_M_head, 0); } + +protected: + + _Slist_node_base* _M_erase_after(_Slist_node_base* __pos) + { + _Slist_node<_Tp>* __next = (_Slist_node<_Tp>*) (__pos->_M_next); + _Slist_node_base* __next_next = __next->_M_next; + __pos->_M_next = __next_next; + destroy(&__next->_M_data); + _M_put_node(__next); + return __next_next; + } + _Slist_node_base* _M_erase_after(_Slist_node_base*, _Slist_node_base*); +}; + +#else /* __STL_USE_STD_ALLOCATORS */ + +template <class _Tp, class _Alloc> +struct _Slist_base { + typedef _Alloc allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Slist_base(const allocator_type&) { _M_head._M_next = 0; } + ~_Slist_base() { _M_erase_after(&_M_head, 0); } + +protected: + typedef simple_alloc<_Slist_node<_Tp>, _Alloc> _Alloc_type; + _Slist_node<_Tp>* _M_get_node() { return _Alloc_type::allocate(1); } + void _M_put_node(_Slist_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); } + + _Slist_node_base* _M_erase_after(_Slist_node_base* __pos) + { + _Slist_node<_Tp>* __next = (_Slist_node<_Tp>*) (__pos->_M_next); + _Slist_node_base* __next_next = __next->_M_next; + __pos->_M_next = __next_next; + destroy(&__next->_M_data); + _M_put_node(__next); + return __next_next; + } + _Slist_node_base* _M_erase_after(_Slist_node_base*, _Slist_node_base*); + +protected: + _Slist_node_base _M_head; +}; + +#endif /* __STL_USE_STD_ALLOCATORS */ + +template <class _Tp, class _Alloc> +_Slist_node_base* +_Slist_base<_Tp,_Alloc>::_M_erase_after(_Slist_node_base* __before_first, + _Slist_node_base* __last_node) { + _Slist_node<_Tp>* __cur = (_Slist_node<_Tp>*) (__before_first->_M_next); + while (__cur != __last_node) { + _Slist_node<_Tp>* __tmp = __cur; + __cur = (_Slist_node<_Tp>*) __cur->_M_next; + destroy(&__tmp->_M_data); + _M_put_node(__tmp); + } + __before_first->_M_next = __last_node; + return __last_node; } -template <class T, class Alloc = alloc> -class slist +template <class _Tp, class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) > +class slist : private _Slist_base<_Tp,_Alloc> { +private: + typedef _Slist_base<_Tp,_Alloc> _Base; public: - typedef T value_type; - typedef value_type* pointer; + typedef _Tp value_type; + typedef value_type* pointer; typedef const value_type* const_pointer; - typedef value_type& reference; + typedef value_type& reference; typedef const value_type& const_reference; - typedef size_t size_type; - typedef ptrdiff_t difference_type; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + + typedef _Slist_iterator<_Tp, _Tp&, _Tp*> iterator; + typedef _Slist_iterator<_Tp, const _Tp&, const _Tp*> const_iterator; - typedef __slist_iterator<T, T&, T*> iterator; - typedef __slist_iterator<T, const T&, const T*> const_iterator; + typedef typename _Base::allocator_type allocator_type; + allocator_type get_allocator() const { return _Base::get_allocator(); } 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; + typedef _Slist_node<_Tp> _Node; + typedef _Slist_node_base _Node_base; + typedef _Slist_iterator_base _Iterator_base; - static list_node* create_node(const value_type& x) { - list_node* node = list_node_allocator::allocate(); + _Node* _M_create_node(const value_type& __x) { + _Node* __node = _M_get_node(); __STL_TRY { - construct(&node->data, x); - node->next = 0; + construct(&__node->_M_data, __x); + __node->_M_next = 0; } - __STL_UNWIND(list_node_allocator::deallocate(node)); - return node; + __STL_UNWIND(_M_put_node(__node)); + return __node; } - static void destroy_node(list_node* node) { - destroy(&node->data); - list_node_allocator::deallocate(node); - } - - void fill_initialize(size_type n, const value_type& x) { - head.next = 0; + _Node* _M_create_node() { + _Node* __node = _M_get_node(); __STL_TRY { - _insert_after_fill(&head, n, x); + construct(&__node->_M_data); + __node->_M_next = 0; } - __STL_UNWIND(clear()); - } + __STL_UNWIND(_M_put_node(__node)); + return __node; + } + +private: +#ifdef __STL_USE_NAMESPACES + using _Base::_M_get_node; + using _Base::_M_put_node; + using _Base::_M_erase_after; + using _Base::_M_head; +#endif /* __STL_USE_NAMESPACES */ + +public: + explicit slist(const allocator_type& __a = allocator_type()) : _Base(__a) {} + + slist(size_type __n, const value_type& __x, + const allocator_type& __a = allocator_type()) : _Base(__a) + { _M_insert_after_fill(&_M_head, __n, __x); } + + explicit slist(size_type __n) : _Base(allocator_type()) + { _M_insert_after_fill(&_M_head, __n, value_type()); } #ifdef __STL_MEMBER_TEMPLATES - template <class InputIterator> - void range_initialize(InputIterator first, InputIterator last) { - head.next = 0; - __STL_TRY { - _insert_after_range(&head, first, last); - } - __STL_UNWIND(clear()); - } + // We don't need any dispatching tricks here, because _M_insert_after_range + // already does them. + template <class _InputIterator> + slist(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) : _Base(__a) + { _M_insert_after_range(&_M_head, __first, __last); } + #else /* __STL_MEMBER_TEMPLATES */ - void range_initialize(const value_type* first, const value_type* last) { - head.next = 0; - __STL_TRY { - _insert_after_range(&head, first, last); - } - __STL_UNWIND(clear()); - } - void range_initialize(const_iterator first, const_iterator last) { - head.next = 0; - __STL_TRY { - _insert_after_range(&head, first, last); - } - __STL_UNWIND(clear()); - } + slist(const_iterator __first, const_iterator __last, + const allocator_type& __a = allocator_type()) : _Base(__a) + { _M_insert_after_range(&_M_head, __first, __last); } + slist(const value_type* __first, const value_type* __last, + const allocator_type& __a = allocator_type()) : _Base(__a) + { _M_insert_after_range(&_M_head, __first, __last); } #endif /* __STL_MEMBER_TEMPLATES */ -private: - list_node_base head; + slist(const slist& __x) : _Base(__x.get_allocator()) + { _M_insert_after_range(&_M_head, __x.begin(), __x.end()); } + + slist& operator= (const slist& __x); + + ~slist() {} public: - slist() { head.next = 0; } + // assign(), a generalized assignment member function. Two + // versions: one that takes a count, and one that takes a range. + // The range version is a member template, so we dispatch on whether + // or not the type is an integer. - slist(size_type n, const value_type& x) { fill_initialize(n, x); } - slist(int n, const value_type& x) { fill_initialize(n, x); } - slist(long n, const value_type& x) { fill_initialize(n, x); } - explicit slist(size_type n) { fill_initialize(n, value_type()); } + void assign(size_type __n, const _Tp& __val); #ifdef __STL_MEMBER_TEMPLATES - template <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); + template <class _InputIterator> + void assign(_InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_assign_dispatch(__first, __last, _Integral()); } - slist(const value_type* first, const value_type* last) { - range_initialize(first, last); - } -#endif /* __STL_MEMBER_TEMPLATES */ - slist(const slist& L) { range_initialize(L.begin(), L.end()); } + template <class _Integer> + void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { assign((size_type) __n, (_Tp) __val); } - slist& operator= (const slist& L); + template <class _InputIterator> + void _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type); - ~slist() { clear(); } +#endif /* __STL_MEMBER_TEMPLATES */ public: - iterator begin() { return iterator((list_node*)head.next); } - const_iterator begin() const { return const_iterator((list_node*)head.next);} + iterator begin() { return iterator((_Node*)_M_head._M_next); } + const_iterator begin() const + { return const_iterator((_Node*)_M_head._M_next);} iterator end() { return iterator(0); } const_iterator end() const { return const_iterator(0); } - size_type size() const { return __slist_size(head.next); } + size_type size() const { return __slist_size(_M_head._M_next); } size_type max_size() const { return size_type(-1); } - bool empty() const { return head.next == 0; } + bool empty() const { return _M_head._M_next == 0; } - void swap(slist& L) - { - list_node_base* tmp = head.next; - head.next = L.head.next; - L.head.next = tmp; - } + void swap(slist& __x) { __STD::swap(_M_head._M_next, __x._M_head._M_next); } public: - friend bool operator== __STL_NULL_TMPL_ARGS(const slist<T, Alloc>& L1, - const slist<T, Alloc>& L2); + friend bool operator== __STL_NULL_TMPL_ARGS (const slist<_Tp,_Alloc>& _SL1, + const slist<_Tp,_Alloc>& _SL2); public: - reference front() { return ((list_node*) head.next)->data; } - const_reference front() const { return ((list_node*) head.next)->data; } - void push_front(const value_type& x) { - __slist_make_link(&head, create_node(x)); + reference front() { return ((_Node*) _M_head._M_next)->_M_data; } + const_reference front() const + { return ((_Node*) _M_head._M_next)->_M_data; } + void push_front(const value_type& __x) { + __slist_make_link(&_M_head, _M_create_node(__x)); } + void push_front() { __slist_make_link(&_M_head, _M_create_node());} void pop_front() { - list_node* node = (list_node*) head.next; - head.next = node->next; - destroy_node(node); + _Node* __node = (_Node*) _M_head._M_next; + _M_head._M_next = __node->_M_next; + destroy(&__node->_M_data); + _M_put_node(__node); } - iterator previous(const_iterator pos) { - return iterator((list_node*) __slist_previous(&head, pos.node)); + iterator previous(const_iterator __pos) { + return iterator((_Node*) __slist_previous(&_M_head, __pos._M_node)); } - const_iterator previous(const_iterator pos) const { - return const_iterator((list_node*) __slist_previous(&head, pos.node)); + const_iterator previous(const_iterator __pos) const { + return const_iterator((_Node*) __slist_previous(&_M_head, __pos._M_node)); } private: - list_node* _insert_after(list_node_base* pos, const value_type& x) { - return (list_node*) (__slist_make_link(pos, create_node(x))); + _Node* _M_insert_after(_Node_base* __pos, const value_type& __x) { + return (_Node*) (__slist_make_link(__pos, _M_create_node(__x))); } - void _insert_after_fill(list_node_base* pos, - size_type n, const value_type& x) { - for (size_type i = 0; i < n; ++i) - pos = __slist_make_link(pos, create_node(x)); + _Node* _M_insert_after(_Node_base* __pos) { + return (_Node*) (__slist_make_link(__pos, _M_create_node())); + } + + void _M_insert_after_fill(_Node_base* __pos, + size_type __n, const value_type& __x) { + for (size_type __i = 0; __i < __n; ++__i) + __pos = __slist_make_link(__pos, _M_create_node(__x)); } #ifdef __STL_MEMBER_TEMPLATES - template <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; - } + + // Check whether it's an integral type. If so, it's not an iterator. + template <class _InIter> + void _M_insert_after_range(_Node_base* __pos, + _InIter __first, _InIter __last) { + typedef typename _Is_integer<_InIter>::_Integral _Integral; + _M_insert_after_range(__pos, __first, __last, _Integral()); } -#else /* __STL_MEMBER_TEMPLATES */ - void _insert_after_range(list_node_base* pos, - const_iterator first, const_iterator last) { - while (first != last) { - pos = __slist_make_link(pos, create_node(*first)); - ++first; - } + + template <class _Integer> + void _M_insert_after_range(_Node_base* __pos, _Integer __n, _Integer __x, + __true_type) { + _M_insert_after_fill(__pos, __n, __x); } - void _insert_after_range(list_node_base* pos, - const value_type* first, const value_type* last) { - while (first != last) { - pos = __slist_make_link(pos, create_node(*first)); - ++first; + + template <class _InIter> + void _M_insert_after_range(_Node_base* __pos, + _InIter __first, _InIter __last, + __false_type) { + while (__first != __last) { + __pos = __slist_make_link(__pos, _M_create_node(*__first)); + ++__first; } } -#endif /* __STL_MEMBER_TEMPLATES */ - list_node_base* erase_after(list_node_base* pos) { - list_node* next = (list_node*) (pos->next); - list_node_base* next_next = next->next; - pos->next = next_next; - destroy_node(next); - return next_next; - } - - list_node_base* erase_after(list_node_base* before_first, - list_node_base* last_node) { - list_node* cur = (list_node*) (before_first->next); - while (cur != last_node) { - list_node* tmp = cur; - cur = (list_node*) cur->next; - destroy_node(tmp); +#else /* __STL_MEMBER_TEMPLATES */ + + void _M_insert_after_range(_Node_base* __pos, + const_iterator __first, const_iterator __last) { + while (__first != __last) { + __pos = __slist_make_link(__pos, _M_create_node(*__first)); + ++__first; + } + } + void _M_insert_after_range(_Node_base* __pos, + const value_type* __first, + const value_type* __last) { + while (__first != __last) { + __pos = __slist_make_link(__pos, _M_create_node(*__first)); + ++__first; } - before_first->next = last_node; - return last_node; } +#endif /* __STL_MEMBER_TEMPLATES */ public: - iterator insert_after(iterator pos, const value_type& x) { - return iterator(_insert_after(pos.node, x)); + iterator insert_after(iterator __pos, const value_type& __x) { + return iterator(_M_insert_after(__pos._M_node, __x)); } - iterator insert_after(iterator pos) { - return insert_after(pos, value_type()); + iterator insert_after(iterator __pos) { + return insert_after(__pos, value_type()); } - void insert_after(iterator pos, size_type n, const value_type& x) { - _insert_after_fill(pos.node, n, x); - } - void insert_after(iterator pos, int n, const value_type& x) { - _insert_after_fill(pos.node, (size_type) n, x); - } - void insert_after(iterator pos, long n, const value_type& x) { - _insert_after_fill(pos.node, (size_type) n, x); + void insert_after(iterator __pos, size_type __n, const value_type& __x) { + _M_insert_after_fill(__pos._M_node, __n, __x); } #ifdef __STL_MEMBER_TEMPLATES - template <class InIter> - void insert_after(iterator pos, InIter first, InIter last) { - _insert_after_range(pos.node, first, last); + + // We don't need any dispatching tricks here, because _M_insert_after_range + // already does them. + template <class _InIter> + void insert_after(iterator __pos, _InIter __first, _InIter __last) { + _M_insert_after_range(__pos._M_node, __first, __last); } + #else /* __STL_MEMBER_TEMPLATES */ - void insert_after(iterator pos, const_iterator first, const_iterator last) { - _insert_after_range(pos.node, first, last); + + void insert_after(iterator __pos, + const_iterator __first, const_iterator __last) { + _M_insert_after_range(__pos._M_node, __first, __last); } - void insert_after(iterator pos, - const value_type* first, const value_type* last) { - _insert_after_range(pos.node, first, last); + void insert_after(iterator __pos, + const value_type* __first, const value_type* __last) { + _M_insert_after_range(__pos._M_node, __first, __last); } + #endif /* __STL_MEMBER_TEMPLATES */ - iterator insert(iterator pos, const value_type& x) { - return iterator(_insert_after(__slist_previous(&head, pos.node), x)); + iterator insert(iterator __pos, const value_type& __x) { + return iterator(_M_insert_after(__slist_previous(&_M_head, __pos._M_node), + __x)); } - iterator insert(iterator pos) { - return iterator(_insert_after(__slist_previous(&head, pos.node), - value_type())); + iterator insert(iterator __pos) { + return iterator(_M_insert_after(__slist_previous(&_M_head, __pos._M_node), + value_type())); } - void insert(iterator pos, size_type n, const value_type& x) { - _insert_after_fill(__slist_previous(&head, pos.node), n, x); - } - void insert(iterator pos, int n, const value_type& x) { - _insert_after_fill(__slist_previous(&head, pos.node), (size_type) n, x); - } - void insert(iterator pos, long n, const value_type& x) { - _insert_after_fill(__slist_previous(&head, pos.node), (size_type) n, x); + void insert(iterator __pos, size_type __n, const value_type& __x) { + _M_insert_after_fill(__slist_previous(&_M_head, __pos._M_node), __n, __x); } #ifdef __STL_MEMBER_TEMPLATES - template <class InIter> - void insert(iterator pos, InIter first, InIter last) { - _insert_after_range(__slist_previous(&head, pos.node), first, last); + + // We don't need any dispatching tricks here, because _M_insert_after_range + // already does them. + template <class _InIter> + void insert(iterator __pos, _InIter __first, _InIter __last) { + _M_insert_after_range(__slist_previous(&_M_head, __pos._M_node), + __first, __last); } + #else /* __STL_MEMBER_TEMPLATES */ - void insert(iterator pos, const_iterator first, const_iterator last) { - _insert_after_range(__slist_previous(&head, pos.node), first, last); + + void insert(iterator __pos, const_iterator __first, const_iterator __last) { + _M_insert_after_range(__slist_previous(&_M_head, __pos._M_node), + __first, __last); } - void insert(iterator pos, const value_type* first, const value_type* last) { - _insert_after_range(__slist_previous(&head, pos.node), first, last); + void insert(iterator __pos, const value_type* __first, + const value_type* __last) { + _M_insert_after_range(__slist_previous(&_M_head, __pos._M_node), + __first, __last); } + #endif /* __STL_MEMBER_TEMPLATES */ public: - iterator erase_after(iterator pos) { - return iterator((list_node*)erase_after(pos.node)); - } - iterator erase_after(iterator before_first, iterator last) { - return iterator((list_node*)erase_after(before_first.node, last.node)); + iterator erase_after(iterator __pos) { + return iterator((_Node*) _M_erase_after(__pos._M_node)); } + iterator erase_after(iterator __before_first, iterator __last) { + return iterator((_Node*) _M_erase_after(__before_first._M_node, + __last._M_node)); + } - iterator erase(iterator pos) { - return (list_node*) erase_after(__slist_previous(&head, pos.node)); + iterator erase(iterator __pos) { + return (_Node*) _M_erase_after(__slist_previous(&_M_head, + __pos._M_node)); } - iterator erase(iterator first, iterator last) { - return (list_node*) erase_after(__slist_previous(&head, first.node), - last.node); + iterator erase(iterator __first, iterator __last) { + return (_Node*) _M_erase_after( + __slist_previous(&_M_head, __first._M_node), __last._M_node); } - void resize(size_type new_size, const T& x); - void resize(size_type new_size) { resize(new_size, T()); } - void clear() { erase_after(&head, 0); } + void resize(size_type new_size, const _Tp& __x); + void resize(size_type new_size) { resize(new_size, _Tp()); } + void clear() { _M_erase_after(&_M_head, 0); } public: - // Moves the range [before_first + 1, before_last + 1) to *this, - // inserting it immediately after pos. This is constant time. - void splice_after(iterator pos, - iterator before_first, iterator before_last) + // Moves the range [__before_first + 1, __before_last + 1) to *this, + // inserting it immediately after __pos. This is constant time. + void splice_after(iterator __pos, + iterator __before_first, iterator __before_last) { - if (before_first != before_last) - __slist_splice_after(pos.node, before_first.node, before_last.node); + if (__before_first != __before_last) + __slist_splice_after(__pos._M_node, __before_first._M_node, + __before_last._M_node); } - // Moves the element that follows prev to *this, inserting it immediately - // after pos. This is constant time. - void splice_after(iterator pos, iterator prev) + // Moves the element that follows __prev to *this, inserting it immediately + // after __pos. This is constant time. + void splice_after(iterator __pos, iterator __prev) { - __slist_splice_after(pos.node, prev.node, prev.node->next); + __slist_splice_after(__pos._M_node, + __prev._M_node, __prev._M_node->_M_next); } - // Linear in distance(begin(), pos), and linear in L.size(). - void splice(iterator pos, slist& L) { - if (L.head.next) - __slist_splice_after(__slist_previous(&head, pos.node), - &L.head, - __slist_previous(&L.head, 0)); + // Linear in distance(begin(), __pos), and linear in __x.size(). + void splice(iterator __pos, slist& __x) { + if (__x._M_head._M_next) + __slist_splice_after(__slist_previous(&_M_head, __pos._M_node), + &__x._M_head, __slist_previous(&__x._M_head, 0)); } - // Linear in distance(begin(), pos), and in distance(L.begin(), i). - void splice(iterator pos, slist& L, iterator i) { - __slist_splice_after(__slist_previous(&head, pos.node), - __slist_previous(&L.head, i.node), - i.node); + // Linear in distance(begin(), __pos), and in distance(__x.begin(), __i). + void splice(iterator __pos, slist& __x, iterator __i) { + __slist_splice_after(__slist_previous(&_M_head, __pos._M_node), + __slist_previous(&__x._M_head, __i._M_node), + __i._M_node); } - // Linear in distance(begin(), pos), in distance(L.begin(), first), - // and in distance(first, last). - void splice(iterator pos, slist& L, iterator first, iterator last) + // Linear in distance(begin(), __pos), in distance(__x.begin(), __first), + // and in distance(__first, __last). + void splice(iterator __pos, slist& __x, iterator __first, iterator __last) { - if (first != last) - __slist_splice_after(__slist_previous(&head, pos.node), - __slist_previous(&L.head, first.node), - __slist_previous(first.node, last.node)); + if (__first != __last) + __slist_splice_after(__slist_previous(&_M_head, __pos._M_node), + __slist_previous(&__x._M_head, __first._M_node), + __slist_previous(__first._M_node, __last._M_node)); } public: - void reverse() { if (head.next) head.next = __slist_reverse(head.next); } + void reverse() { + if (_M_head._M_next) + _M_head._M_next = __slist_reverse(_M_head._M_next); + } - void remove(const T& val); + void remove(const _Tp& __val); void unique(); - void merge(slist& L); + void merge(slist& __x); void sort(); #ifdef __STL_MEMBER_TEMPLATES - template <class Predicate> void remove_if(Predicate pred); - template <class BinaryPredicate> void unique(BinaryPredicate pred); - template <class StrictWeakOrdering> void merge(slist&, StrictWeakOrdering); - template <class StrictWeakOrdering> void sort(StrictWeakOrdering comp); + template <class _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) +template <class _Tp, class _Alloc> +slist<_Tp,_Alloc>& slist<_Tp,_Alloc>::operator=(const slist<_Tp,_Alloc>& __x) { - if (&L != this) { - list_node_base* p1 = &head; - list_node* n1 = (list_node*) head.next; - const list_node* n2 = (const list_node*) L.head.next; - while (n1 && n2) { - n1->data = n2->data; - p1 = n1; - n1 = (list_node*) n1->next; - n2 = (const list_node*) n2->next; + if (&__x != this) { + _Node_base* __p1 = &_M_head; + _Node* __n1 = (_Node*) _M_head._M_next; + const _Node* __n2 = (const _Node*) __x._M_head._M_next; + while (__n1 && __n2) { + __n1->_M_data = __n2->_M_data; + __p1 = __n1; + __n1 = (_Node*) __n1->_M_next; + __n2 = (const _Node*) __n2->_M_next; } - if (n2 == 0) - erase_after(p1, 0); + if (__n2 == 0) + _M_erase_after(__p1, 0); else - _insert_after_range(p1, - const_iterator((list_node*)n2), const_iterator(0)); + _M_insert_after_range(__p1, const_iterator((_Node*)__n2), + const_iterator(0)); } return *this; -} +} + +template <class _Tp, class _Alloc> +void slist<_Tp, _Alloc>::assign(size_type __n, const _Tp& __val) { + _Node_base* __prev = &_M_head; + _Node* __node = (_Node*) _M_head._M_next; + for ( ; __node != 0 && __n > 0 ; --__n) { + __node->_M_data = __val; + __prev = __node; + __node = (_Node*) __node->_M_next; + } + if (__n > 0) + _M_insert_after_fill(__prev, __n, __val); + else + _M_erase_after(__prev, 0); +} + +#ifdef __STL_MEMBER_TEMPLATES + +template <class _Tp, class _Alloc> template <class _InputIter> +void +slist<_Tp, _Alloc>::_M_assign_dispatch(_InputIter __first, _InputIter __last, + __false_type) +{ + _Node_base* __prev = &_M_head; + _Node* __node = (_Node*) _M_head._M_next; + while (__node != 0 && __first != __last) { + __node->_M_data = *__first; + __prev = __node; + __node = (_Node*) __node->_M_next; + ++__first; + } + if (__first != __last) + _M_insert_after_range(__prev, __first, __last); + else + _M_erase_after(__prev, 0); +} + +#endif /* __STL_MEMBER_TEMPLATES */ -template <class T, class Alloc> -bool operator==(const slist<T, Alloc>& L1, const slist<T, Alloc>& L2) +template <class _Tp, class _Alloc> +inline bool +operator==(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) { - 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; + typedef typename slist<_Tp,_Alloc>::_Node _Node; + _Node* __n1 = (_Node*) _SL1._M_head._M_next; + _Node* __n2 = (_Node*) _SL2._M_head._M_next; + while (__n1 && __n2 && __n1->_M_data == __n2->_M_data) { + __n1 = (_Node*) __n1->_M_next; + __n2 = (_Node*) __n2->_M_next; + } + return __n1 == 0 && __n2 == 0; } -template <class T, class Alloc> -inline bool operator<(const slist<T, Alloc>& L1, const slist<T, Alloc>& L2) +template <class _Tp, class _Alloc> +inline bool operator<(const slist<_Tp,_Alloc>& _SL1, + const slist<_Tp,_Alloc>& _SL2) { - return lexicographical_compare(L1.begin(), L1.end(), L2.begin(), L2.end()); + return lexicographical_compare(_SL1.begin(), _SL1.end(), + _SL2.begin(), _SL2.end()); } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER -template <class T, class Alloc> -inline void swap(slist<T, Alloc>& x, slist<T, Alloc>& y) { - x.swap(y); +template <class _Tp, class _Alloc> +inline void swap(slist<_Tp,_Alloc>& __x, slist<_Tp,_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) +template <class _Tp, class _Alloc> +void slist<_Tp,_Alloc>::resize(size_type __len, const _Tp& __x) { - list_node_base* cur = &head; - while (cur->next != 0 && len > 0) { - --len; - cur = cur->next; + _Node_base* __cur = &_M_head; + while (__cur->_M_next != 0 && __len > 0) { + --__len; + __cur = __cur->_M_next; } - if (cur->next) - erase_after(cur, 0); + if (__cur->_M_next) + _M_erase_after(__cur, 0); else - _insert_after_fill(cur, len, x); + _M_insert_after_fill(__cur, __len, __x); } -template <class T, class Alloc> -void slist<T,Alloc>::remove(const T& val) +template <class _Tp, class _Alloc> +void slist<_Tp,_Alloc>::remove(const _Tp& __val) { - list_node_base* cur = &head; - while (cur && cur->next) { - if (((list_node*) cur->next)->data == val) - erase_after(cur); + _Node_base* __cur = &_M_head; + while (__cur && __cur->_M_next) { + if (((_Node*) __cur->_M_next)->_M_data == __val) + _M_erase_after(__cur); else - cur = cur->next; + __cur = __cur->_M_next; } } -template <class T, class Alloc> -void slist<T,Alloc>::unique() +template <class _Tp, class _Alloc> +void slist<_Tp,_Alloc>::unique() { - list_node_base* cur = head.next; - if (cur) { - while (cur->next) { - if (((list_node*)cur)->data == ((list_node*)(cur->next))->data) - erase_after(cur); + _Node_base* __cur = _M_head._M_next; + if (__cur) { + while (__cur->_M_next) { + if (((_Node*)__cur)->_M_data == + ((_Node*)(__cur->_M_next))->_M_data) + _M_erase_after(__cur); else - cur = cur->next; + __cur = __cur->_M_next; } } } -template <class T, class Alloc> -void slist<T,Alloc>::merge(slist<T,Alloc>& L) +template <class _Tp, class _Alloc> +void slist<_Tp,_Alloc>::merge(slist<_Tp,_Alloc>& __x) { - list_node_base* n1 = &head; - while (n1->next && L.head.next) { - if (((list_node*) L.head.next)->data < ((list_node*) n1->next)->data) - __slist_splice_after(n1, &L.head, L.head.next); - n1 = n1->next; + _Node_base* __n1 = &_M_head; + while (__n1->_M_next && __x._M_head._M_next) { + if (((_Node*) __x._M_head._M_next)->_M_data < + ((_Node*) __n1->_M_next)->_M_data) + __slist_splice_after(__n1, &__x._M_head, __x._M_head._M_next); + __n1 = __n1->_M_next; } - if (L.head.next) { - n1->next = L.head.next; - L.head.next = 0; + if (__x._M_head._M_next) { + __n1->_M_next = __x._M_head._M_next; + __x._M_head._M_next = 0; } } -template <class T, class Alloc> -void slist<T,Alloc>::sort() +template <class _Tp, class _Alloc> +void slist<_Tp,_Alloc>::sort() { - if (head.next && head.next->next) { - slist carry; - slist counter[64]; - int fill = 0; + if (_M_head._M_next && _M_head._M_next->_M_next) { + slist __carry; + slist __counter[64]; + int __fill = 0; while (!empty()) { - __slist_splice_after(&carry.head, &head, head.next); - int i = 0; - while (i < fill && !counter[i].empty()) { - counter[i].merge(carry); - carry.swap(counter[i]); - ++i; + __slist_splice_after(&__carry._M_head, &_M_head, _M_head._M_next); + int __i = 0; + while (__i < __fill && !__counter[__i].empty()) { + __counter[__i].merge(__carry); + __carry.swap(__counter[__i]); + ++__i; } - carry.swap(counter[i]); - if (i == fill) - ++fill; + __carry.swap(__counter[__i]); + if (__i == __fill) + ++__fill; } - for (int i = 1; i < fill; ++i) - counter[i].merge(counter[i-1]); - this->swap(counter[fill-1]); + for (int __i = 1; __i < __fill; ++__i) + __counter[__i].merge(__counter[__i-1]); + this->swap(__counter[__fill-1]); } } #ifdef __STL_MEMBER_TEMPLATES -template <class T, class Alloc> -template <class Predicate> void slist<T,Alloc>::remove_if(Predicate pred) +template <class _Tp, class _Alloc> +template <class _Predicate> +void slist<_Tp,_Alloc>::remove_if(_Predicate __pred) { - list_node_base* cur = &head; - while (cur->next) { - if (pred(((list_node*) cur->next)->data)) - erase_after(cur); + _Node_base* __cur = &_M_head; + while (__cur->_M_next) { + if (__pred(((_Node*) __cur->_M_next)->_M_data)) + _M_erase_after(__cur); else - cur = cur->next; + __cur = __cur->_M_next; } } -template <class T, class Alloc> template <class BinaryPredicate> -void slist<T,Alloc>::unique(BinaryPredicate pred) +template <class _Tp, class _Alloc> template <class _BinaryPredicate> +void slist<_Tp,_Alloc>::unique(_BinaryPredicate __pred) { - list_node* cur = (list_node*) head.next; - if (cur) { - while (cur->next) { - if (pred(((list_node*)cur)->data, ((list_node*)(cur->next))->data)) - erase_after(cur); + _Node* __cur = (_Node*) _M_head._M_next; + if (__cur) { + while (__cur->_M_next) { + if (__pred(((_Node*)__cur)->_M_data, + ((_Node*)(__cur->_M_next))->_M_data)) + _M_erase_after(__cur); else - cur = (list_node*) cur->next; + __cur = (_Node*) __cur->_M_next; } } } -template <class T, class Alloc> template <class StrictWeakOrdering> -void slist<T,Alloc>::merge(slist<T,Alloc>& L, StrictWeakOrdering comp) +template <class _Tp, class _Alloc> template <class _StrictWeakOrdering> +void slist<_Tp,_Alloc>::merge(slist<_Tp,_Alloc>& __x, + _StrictWeakOrdering __comp) { - list_node_base* n1 = &head; - while (n1->next && L.head.next) { - if (comp(((list_node*) L.head.next)->data, - ((list_node*) n1->next)->data)) - __slist_splice_after(n1, &L.head, L.head.next); - n1 = n1->next; + _Node_base* __n1 = &_M_head; + while (__n1->_M_next && __x._M_head._M_next) { + if (__comp(((_Node*) __x._M_head._M_next)->_M_data, + ((_Node*) __n1->_M_next)->_M_data)) + __slist_splice_after(__n1, &__x._M_head, __x._M_head._M_next); + __n1 = __n1->_M_next; } - if (L.head.next) { - n1->next = L.head.next; - L.head.next = 0; + if (__x._M_head._M_next) { + __n1->_M_next = __x._M_head._M_next; + __x._M_head._M_next = 0; } } -template <class T, class Alloc> template <class StrictWeakOrdering> -void slist<T,Alloc>::sort(StrictWeakOrdering comp) +template <class _Tp, class _Alloc> template <class _StrictWeakOrdering> +void slist<_Tp,_Alloc>::sort(_StrictWeakOrdering __comp) { - if (head.next && head.next->next) { - slist carry; - slist counter[64]; - int fill = 0; + if (_M_head._M_next && _M_head._M_next->_M_next) { + slist __carry; + slist __counter[64]; + int __fill = 0; while (!empty()) { - __slist_splice_after(&carry.head, &head, head.next); - int i = 0; - while (i < fill && !counter[i].empty()) { - counter[i].merge(carry, comp); - carry.swap(counter[i]); - ++i; + __slist_splice_after(&__carry._M_head, &_M_head, _M_head._M_next); + int __i = 0; + while (__i < __fill && !__counter[__i].empty()) { + __counter[__i].merge(__carry, __comp); + __carry.swap(__counter[__i]); + ++__i; } - carry.swap(counter[i]); - if (i == fill) - ++fill; + __carry.swap(__counter[__i]); + if (__i == __fill) + ++__fill; } - for (int i = 1; i < fill; ++i) - counter[i].merge(counter[i-1], comp); - this->swap(counter[fill-1]); + for (int __i = 1; __i < __fill; ++__i) + __counter[__i].merge(__counter[__i-1], __comp); + this->swap(__counter[__fill-1]); } } @@ -729,6 +933,7 @@ void slist<T,Alloc>::sort(StrictWeakOrdering comp) #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 +#pragma reset woff 1375 #endif __STL_END_NAMESPACE diff --git a/contrib/libstdc++/stl/stl_stack.h b/contrib/libstdc++/stl/stl_stack.h index d380e81..2a04b21 100644 --- a/contrib/libstdc++/stl/stl_stack.h +++ b/contrib/libstdc++/stl/stl_stack.h @@ -34,39 +34,74 @@ __STL_BEGIN_NAMESPACE #ifndef __STL_LIMITED_DEFAULT_TEMPLATES -template <class T, class Sequence = deque<T> > +template <class _Tp, class _Sequence = deque<_Tp> > #else -template <class T, class Sequence> +template <class _Tp, 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; + typedef typename _Sequence::value_type value_type; + typedef typename _Sequence::size_type size_type; + typedef _Sequence container_type; + + typedef typename _Sequence::reference reference; + typedef typename _Sequence::const_reference const_reference; protected: - Sequence c; + _Sequence _M_c; public: - bool empty() const { return c.empty(); } - size_type size() const { return c.size(); } - reference top() { return c.back(); } - const_reference top() const { return c.back(); } - void push(const value_type& x) { c.push_back(x); } - void pop() { c.pop_back(); } + stack() : _M_c() {} + explicit stack(const _Sequence& __s) : _M_c(__s) {} + + bool empty() const { return _M_c.empty(); } + size_type size() const { return _M_c.size(); } + reference top() { return _M_c.back(); } + const_reference top() const { return _M_c.back(); } + void push(const value_type& __x) { _M_c.push_back(__x); } + void pop() { _M_c.pop_back(); } }; -template <class T, class Sequence> -bool operator==(const stack<T, Sequence>& x, const stack<T, Sequence>& y) { - return x.c == y.c; +template <class _Tp, class _Seq> +bool operator==(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) +{ + return __x._M_c == __y._M_c; +} + +template <class _Tp, class _Seq> +bool operator<(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) +{ + return __x._M_c < __y._M_c; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template <class _Tp, class _Seq> +bool operator!=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) +{ + return !(__x == __y); +} + +template <class _Tp, class _Seq> +bool operator>(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) +{ + return __y < __x; } -template <class T, class Sequence> -bool operator<(const stack<T, Sequence>& x, const stack<T, Sequence>& y) { - return x.c < y.c; +template <class _Tp, class _Seq> +bool operator<=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) +{ + return !(__y < __x); } +template <class _Tp, class _Seq> +bool operator>=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) +{ + return !(__x < __y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_STACK_H */ diff --git a/contrib/libstdc++/stl/stl_tempbuf.h b/contrib/libstdc++/stl/stl_tempbuf.h index 9dbc238..e1b2ead 100644 --- a/contrib/libstdc++/stl/stl_tempbuf.h +++ b/contrib/libstdc++/stl/stl_tempbuf.h @@ -34,86 +34,119 @@ __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; +template <class _Tp> +pair<_Tp*, ptrdiff_t> +__get_temporary_buffer(ptrdiff_t __len, _Tp*) +{ + if (__len > ptrdiff_t(INT_MAX / sizeof(_Tp))) + __len = INT_MAX / sizeof(_Tp); + + while (__len > 0) { + _Tp* __tmp = (_Tp*) malloc((size_t)__len * sizeof(_Tp)); + if (__tmp != 0) + return pair<_Tp*, ptrdiff_t>(__tmp, __len); + __len /= 2; } - return pair<T*, ptrdiff_t>((T*)0, 0); + return pair<_Tp*, ptrdiff_t>((_Tp*)0, 0); } -template <class T> -void return_temporary_buffer(T* p) { - free(p); +#ifdef __STL_EXPLICIT_FUNCTION_TMPL_ARGS + +template <class _Tp> +inline pair<_Tp*, ptrdiff_t> get_temporary_buffer(ptrdiff_t __len) { + return __get_temporary_buffer(__len, (_Tp*) 0); } -template <class ForwardIterator, - class T -#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION - = iterator_traits<ForwardIterator>::value_type -#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ - > -class temporary_buffer { +#endif /* __STL_EXPLICIT_FUNCTION_TMPL_ARGS */ + +// This overload is not required by the standard; it is an extension. +// It is supported for backward compatibility with the HP STL, and +// because not all compilers support the language feature (explicit +// function template arguments) that is required for the standard +// version of get_temporary_buffer. +template <class _Tp> +inline pair<_Tp*, ptrdiff_t> get_temporary_buffer(ptrdiff_t __len, _Tp*) { + return __get_temporary_buffer(__len, (_Tp*) 0); +} + +template <class _Tp> +void return_temporary_buffer(_Tp* __p) { + free(__p); +} + +template <class _ForwardIterator, class _Tp> +class _Temporary_buffer { private: - ptrdiff_t original_len; - ptrdiff_t len; - T* buffer; + ptrdiff_t _M_original_len; + ptrdiff_t _M_len; + _Tp* _M_buffer; - void allocate_buffer() { - original_len = len; - buffer = 0; + void _M_allocate_buffer() { + _M_original_len = _M_len; + _M_buffer = 0; - if (len > (ptrdiff_t)(INT_MAX / sizeof(T))) - len = INT_MAX / sizeof(T); + if (_M_len > (ptrdiff_t)(INT_MAX / sizeof(_Tp))) + _M_len = INT_MAX / sizeof(_Tp); - while (len > 0) { - buffer = (T*) malloc(len * sizeof(T)); - if (buffer) + while (_M_len > 0) { + _M_buffer = (_Tp*) malloc(_M_len * sizeof(_Tp)); + if (_M_buffer) break; - len /= 2; + _M_len /= 2; } } - void initialize_buffer(const T&, __true_type) {} - void initialize_buffer(const T& val, __false_type) { - uninitialized_fill_n(buffer, len, val); + void _M_initialize_buffer(const _Tp&, __true_type) {} + void _M_initialize_buffer(const _Tp& val, __false_type) { + uninitialized_fill_n(_M_buffer, _M_len, val); } public: - ptrdiff_t size() const { return len; } - ptrdiff_t requested_size() const { return original_len; } - T* begin() { return buffer; } - T* end() { return buffer + len; } - - temporary_buffer(ForwardIterator first, ForwardIterator last) { + ptrdiff_t size() const { return _M_len; } + ptrdiff_t requested_size() const { return _M_original_len; } + _Tp* begin() { return _M_buffer; } + _Tp* end() { return _M_buffer + _M_len; } + + _Temporary_buffer(_ForwardIterator __first, _ForwardIterator __last) { + typedef typename __type_traits<_Tp>::has_trivial_default_constructor + _Trivial; __STL_TRY { - len = 0; - distance(first, last, len); - allocate_buffer(); - if (len > 0) - initialize_buffer(*first, - typename __type_traits<T>::has_trivial_default_constructor()); + _M_len = 0; + distance(__first, __last, _M_len); + _M_allocate_buffer(); + if (_M_len > 0) + _M_initialize_buffer(*__first, _Trivial()); } - __STL_UNWIND(free(buffer); buffer = 0; len = 0); + __STL_UNWIND(free(_M_buffer); _M_buffer = 0; _M_len = 0); } - ~temporary_buffer() { - destroy(buffer, buffer + len); - free(buffer); + ~_Temporary_buffer() { + destroy(_M_buffer, _M_buffer + _M_len); + free(_M_buffer); } private: - temporary_buffer(const temporary_buffer&) {} - void operator=(const temporary_buffer&) {} + // Disable copy constructor and assignment operator. + _Temporary_buffer(const _Temporary_buffer&) {} + void operator=(const _Temporary_buffer&) {} }; +// Class temporary_buffer is not part of the standard. It is an extension. + +template <class _ForwardIterator, + class _Tp +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + = typename iterator_traits<_ForwardIterator>::value_type +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + > +struct temporary_buffer : public _Temporary_buffer<_ForwardIterator, _Tp> +{ + temporary_buffer(_ForwardIterator __first, _ForwardIterator __last) + : _Temporary_buffer<_ForwardIterator, _Tp>(__first, __last) {} + ~temporary_buffer() {} +}; + __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_TEMPBUF_H */ diff --git a/contrib/libstdc++/stl/stl_tree.h b/contrib/libstdc++/stl/stl_tree.h index 55a6c0e..c82943f 100644 --- a/contrib/libstdc++/stl/stl_tree.h +++ b/contrib/libstdc++/stl/stl_tree.h @@ -60,439 +60,566 @@ iterators invalidated are those referring to the deleted node. __STL_BEGIN_NAMESPACE -typedef bool __rb_tree_color_type; -const __rb_tree_color_type __rb_tree_red = false; -const __rb_tree_color_type __rb_tree_black = true; +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1375 +#endif -struct __rb_tree_node_base +typedef bool _Rb_tree_Color_type; +const _Rb_tree_Color_type _S_rb_tree_red = false; +const _Rb_tree_Color_type _S_rb_tree_black = true; + +struct _Rb_tree_node_base { - typedef __rb_tree_color_type color_type; - typedef __rb_tree_node_base* base_ptr; + typedef _Rb_tree_Color_type _Color_type; + typedef _Rb_tree_node_base* _Base_ptr; - color_type color; - base_ptr parent; - base_ptr left; - base_ptr right; + _Color_type _M_color; + _Base_ptr _M_parent; + _Base_ptr _M_left; + _Base_ptr _M_right; - static base_ptr minimum(base_ptr x) + static _Base_ptr _S_minimum(_Base_ptr __x) { - while (x->left != 0) x = x->left; - return x; + while (__x->_M_left != 0) __x = __x->_M_left; + return __x; } - static base_ptr maximum(base_ptr x) + static _Base_ptr _S_maximum(_Base_ptr __x) { - while (x->right != 0) x = x->right; - return x; + while (__x->_M_right != 0) __x = __x->_M_right; + return __x; } }; -template <class Value> -struct __rb_tree_node : public __rb_tree_node_base +template <class _Value> +struct _Rb_tree_node : public _Rb_tree_node_base { - typedef __rb_tree_node<Value>* link_type; - Value value_field; + typedef _Rb_tree_node<_Value>* _Link_type; + _Value _M_value_field; }; -struct __rb_tree_base_iterator +struct _Rb_tree_base_iterator { - typedef __rb_tree_node_base::base_ptr base_ptr; + typedef _Rb_tree_node_base::_Base_ptr _Base_ptr; typedef bidirectional_iterator_tag iterator_category; typedef ptrdiff_t difference_type; - base_ptr node; + _Base_ptr _M_node; - void increment() + void _M_increment() { - if (node->right != 0) { - node = node->right; - while (node->left != 0) - node = node->left; + if (_M_node->_M_right != 0) { + _M_node = _M_node->_M_right; + while (_M_node->_M_left != 0) + _M_node = _M_node->_M_left; } else { - base_ptr y = node->parent; - while (node == y->right) { - node = y; - y = y->parent; + _Base_ptr __y = _M_node->_M_parent; + while (_M_node == __y->_M_right) { + _M_node = __y; + __y = __y->_M_parent; } - if (node->right != y) - node = y; + if (_M_node->_M_right != __y) + _M_node = __y; } } - void decrement() + void _M_decrement() { - if (node->color == __rb_tree_red && - node->parent->parent == node) - node = node->right; - else if (node->left != 0) { - base_ptr y = node->left; - while (y->right != 0) - y = y->right; - node = y; + if (_M_node->_M_color == _S_rb_tree_red && + _M_node->_M_parent->_M_parent == _M_node) + _M_node = _M_node->_M_right; + else if (_M_node->_M_left != 0) { + _Base_ptr __y = _M_node->_M_left; + while (__y->_M_right != 0) + __y = __y->_M_right; + _M_node = __y; } else { - base_ptr y = node->parent; - while (node == y->left) { - node = y; - y = y->parent; + _Base_ptr __y = _M_node->_M_parent; + while (_M_node == __y->_M_left) { + _M_node = __y; + __y = __y->_M_parent; } - node = y; + _M_node = __y; } } }; -template <class Value, class Ref, class Ptr> -struct __rb_tree_iterator : public __rb_tree_base_iterator +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; } + typedef _Value value_type; + typedef _Ref reference; + typedef _Ptr pointer; + typedef _Rb_tree_iterator<_Value, _Value&, _Value*> + iterator; + typedef _Rb_tree_iterator<_Value, const _Value&, const _Value*> + const_iterator; + typedef _Rb_tree_iterator<_Value, _Ref, _Ptr> + _Self; + typedef _Rb_tree_node<_Value>* _Link_type; + + _Rb_tree_iterator() {} + _Rb_tree_iterator(_Link_type __x) { _M_node = __x; } + _Rb_tree_iterator(const iterator& __it) { _M_node = __it._M_node; } + + reference operator*() const { return _Link_type(_M_node)->_M_value_field; } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ - self& operator++() { increment(); return *this; } - self operator++(int) { - self tmp = *this; - increment(); - return tmp; + _Self& operator++() { _M_increment(); return *this; } + _Self operator++(int) { + _Self __tmp = *this; + _M_increment(); + return __tmp; } - self& operator--() { decrement(); return *this; } - self operator--(int) { - self tmp = *this; - decrement(); - return tmp; + _Self& operator--() { _M_decrement(); return *this; } + _Self operator--(int) { + _Self __tmp = *this; + _M_decrement(); + return __tmp; } }; -inline bool operator==(const __rb_tree_base_iterator& x, - const __rb_tree_base_iterator& y) { - return x.node == y.node; +inline bool operator==(const _Rb_tree_base_iterator& __x, + const _Rb_tree_base_iterator& __y) { + return __x._M_node == __y._M_node; } -inline bool operator!=(const __rb_tree_base_iterator& x, - const __rb_tree_base_iterator& y) { - return x.node != y.node; +inline bool operator!=(const _Rb_tree_base_iterator& __x, + const _Rb_tree_base_iterator& __y) { + return __x._M_node != __y._M_node; } #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION inline bidirectional_iterator_tag -iterator_category(const __rb_tree_base_iterator&) { +iterator_category(const _Rb_tree_base_iterator&) { return bidirectional_iterator_tag(); } -inline __rb_tree_base_iterator::difference_type* -distance_type(const __rb_tree_base_iterator&) { - return (__rb_tree_base_iterator::difference_type*) 0; +inline _Rb_tree_base_iterator::difference_type* +distance_type(const _Rb_tree_base_iterator&) { + return (_Rb_tree_base_iterator::difference_type*) 0; } -template <class Value, class Ref, class Ptr> -inline Value* value_type(const __rb_tree_iterator<Value, Ref, Ptr>&) { - return (Value*) 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_rotate_left(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root) { - __rb_tree_node_base* y = x->right; - x->right = y->left; - if (y->left !=0) - y->left->parent = x; - y->parent = x->parent; - - if (x == root) - root = y; - else if (x == x->parent->left) - x->parent->left = y; + _Rb_tree_node_base* __y = __x->_M_right; + __x->_M_right = __y->_M_left; + if (__y->_M_left !=0) + __y->_M_left->_M_parent = __x; + __y->_M_parent = __x->_M_parent; + + if (__x == __root) + __root = __y; + else if (__x == __x->_M_parent->_M_left) + __x->_M_parent->_M_left = __y; else - x->parent->right = y; - y->left = x; - x->parent = y; + __x->_M_parent->_M_right = __y; + __y->_M_left = __x; + __x->_M_parent = __y; } inline void -__rb_tree_rotate_right(__rb_tree_node_base* x, __rb_tree_node_base*& root) +_Rb_tree_rotate_right(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root) { - __rb_tree_node_base* y = x->left; - x->left = y->right; - if (y->right != 0) - y->right->parent = x; - y->parent = x->parent; - - if (x == root) - root = y; - else if (x == x->parent->right) - x->parent->right = y; + _Rb_tree_node_base* __y = __x->_M_left; + __x->_M_left = __y->_M_right; + if (__y->_M_right != 0) + __y->_M_right->_M_parent = __x; + __y->_M_parent = __x->_M_parent; + + if (__x == __root) + __root = __y; + else if (__x == __x->_M_parent->_M_right) + __x->_M_parent->_M_right = __y; else - x->parent->left = y; - y->right = x; - x->parent = y; + __x->_M_parent->_M_left = __y; + __y->_M_right = __x; + __x->_M_parent = __y; } inline void -__rb_tree_rebalance(__rb_tree_node_base* x, __rb_tree_node_base*& root) +_Rb_tree_rebalance(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root) { - x->color = __rb_tree_red; - while (x != root && x->parent->color == __rb_tree_red) { - if (x->parent == x->parent->parent->left) { - __rb_tree_node_base* y = x->parent->parent->right; - if (y && y->color == __rb_tree_red) { - x->parent->color = __rb_tree_black; - y->color = __rb_tree_black; - x->parent->parent->color = __rb_tree_red; - x = x->parent->parent; + __x->_M_color = _S_rb_tree_red; + while (__x != __root && __x->_M_parent->_M_color == _S_rb_tree_red) { + if (__x->_M_parent == __x->_M_parent->_M_parent->_M_left) { + _Rb_tree_node_base* __y = __x->_M_parent->_M_parent->_M_right; + if (__y && __y->_M_color == _S_rb_tree_red) { + __x->_M_parent->_M_color = _S_rb_tree_black; + __y->_M_color = _S_rb_tree_black; + __x->_M_parent->_M_parent->_M_color = _S_rb_tree_red; + __x = __x->_M_parent->_M_parent; } else { - if (x == x->parent->right) { - x = x->parent; - __rb_tree_rotate_left(x, root); + if (__x == __x->_M_parent->_M_right) { + __x = __x->_M_parent; + _Rb_tree_rotate_left(__x, __root); } - x->parent->color = __rb_tree_black; - x->parent->parent->color = __rb_tree_red; - __rb_tree_rotate_right(x->parent->parent, root); + __x->_M_parent->_M_color = _S_rb_tree_black; + __x->_M_parent->_M_parent->_M_color = _S_rb_tree_red; + _Rb_tree_rotate_right(__x->_M_parent->_M_parent, __root); } } else { - __rb_tree_node_base* y = x->parent->parent->left; - if (y && y->color == __rb_tree_red) { - x->parent->color = __rb_tree_black; - y->color = __rb_tree_black; - x->parent->parent->color = __rb_tree_red; - x = x->parent->parent; + _Rb_tree_node_base* __y = __x->_M_parent->_M_parent->_M_left; + if (__y && __y->_M_color == _S_rb_tree_red) { + __x->_M_parent->_M_color = _S_rb_tree_black; + __y->_M_color = _S_rb_tree_black; + __x->_M_parent->_M_parent->_M_color = _S_rb_tree_red; + __x = __x->_M_parent->_M_parent; } else { - if (x == x->parent->left) { - x = x->parent; - __rb_tree_rotate_right(x, root); + if (__x == __x->_M_parent->_M_left) { + __x = __x->_M_parent; + _Rb_tree_rotate_right(__x, __root); } - x->parent->color = __rb_tree_black; - x->parent->parent->color = __rb_tree_red; - __rb_tree_rotate_left(x->parent->parent, root); + __x->_M_parent->_M_color = _S_rb_tree_black; + __x->_M_parent->_M_parent->_M_color = _S_rb_tree_red; + _Rb_tree_rotate_left(__x->_M_parent->_M_parent, __root); } } } - root->color = __rb_tree_black; + __root->_M_color = _S_rb_tree_black; } -inline __rb_tree_node_base* -__rb_tree_rebalance_for_erase(__rb_tree_node_base* z, - __rb_tree_node_base*& root, - __rb_tree_node_base*& leftmost, - __rb_tree_node_base*& rightmost) +inline _Rb_tree_node_base* +_Rb_tree_rebalance_for_erase(_Rb_tree_node_base* __z, + _Rb_tree_node_base*& __root, + _Rb_tree_node_base*& __leftmost, + _Rb_tree_node_base*& __rightmost) { - __rb_tree_node_base* y = z; - __rb_tree_node_base* x = 0; - __rb_tree_node_base* x_parent = 0; - if (y->left == 0) // z has at most one non-null child. y == z. - x = y->right; // x might be null. + _Rb_tree_node_base* __y = __z; + _Rb_tree_node_base* __x = 0; + _Rb_tree_node_base* __x_parent = 0; + if (__y->_M_left == 0) // __z has at most one non-null child. y == z. + __x = __y->_M_right; // __x might be null. else - if (y->right == 0) // z has exactly one non-null child. y == z. - x = y->left; // x is not null. - else { // z has two non-null children. Set y to - y = y->right; // z's successor. x might be null. - while (y->left != 0) - y = y->left; - x = y->right; + if (__y->_M_right == 0) // __z has exactly one non-null child. y == z. + __x = __y->_M_left; // __x is not null. + else { // __z has two non-null children. Set __y to + __y = __y->_M_right; // __z's successor. __x might be null. + while (__y->_M_left != 0) + __y = __y->_M_left; + __x = __y->_M_right; } - if (y != z) { // relink y in place of z. y is z's successor - z->left->parent = y; - y->left = z->left; - if (y != z->right) { - x_parent = y->parent; - if (x) x->parent = y->parent; - y->parent->left = x; // y must be a left child - y->right = z->right; - z->right->parent = y; + if (__y != __z) { // relink y in place of z. y is z's successor + __z->_M_left->_M_parent = __y; + __y->_M_left = __z->_M_left; + if (__y != __z->_M_right) { + __x_parent = __y->_M_parent; + if (__x) __x->_M_parent = __y->_M_parent; + __y->_M_parent->_M_left = __x; // __y must be a child of _M_left + __y->_M_right = __z->_M_right; + __z->_M_right->_M_parent = __y; } else - x_parent = y; - if (root == z) - root = y; - else if (z->parent->left == z) - z->parent->left = y; + __x_parent = __y; + if (__root == __z) + __root = __y; + else if (__z->_M_parent->_M_left == __z) + __z->_M_parent->_M_left = __y; else - z->parent->right = y; - y->parent = z->parent; - __STD::swap(y->color, z->color); - y = z; - // y now points to node to be actually deleted + __z->_M_parent->_M_right = __y; + __y->_M_parent = __z->_M_parent; + __STD::swap(__y->_M_color, __z->_M_color); + __y = __z; + // __y now points to node to be actually deleted } - else { // y == z - x_parent = y->parent; - if (x) x->parent = y->parent; - if (root == z) - root = x; + else { // __y == __z + __x_parent = __y->_M_parent; + if (__x) __x->_M_parent = __y->_M_parent; + if (__root == __z) + __root = __x; else - if (z->parent->left == z) - z->parent->left = x; + if (__z->_M_parent->_M_left == __z) + __z->_M_parent->_M_left = __x; else - z->parent->right = x; - if (leftmost == z) - if (z->right == 0) // z->left must be null also - leftmost = z->parent; - // makes leftmost == header if z == root + __z->_M_parent->_M_right = __x; + if (__leftmost == __z) + if (__z->_M_right == 0) // __z->_M_left must be null also + __leftmost = __z->_M_parent; + // makes __leftmost == _M_header if __z == __root else - leftmost = __rb_tree_node_base::minimum(x); - if (rightmost == z) - if (z->left == 0) // z->right must be null also - rightmost = z->parent; - // makes rightmost == header if z == root - else // x == z->left - rightmost = __rb_tree_node_base::maximum(x); + __leftmost = _Rb_tree_node_base::_S_minimum(__x); + if (__rightmost == __z) + if (__z->_M_left == 0) // __z->_M_right must be null also + __rightmost = __z->_M_parent; + // makes __rightmost == _M_header if __z == __root + else // __x == __z->_M_left + __rightmost = _Rb_tree_node_base::_S_maximum(__x); } - if (y->color != __rb_tree_red) { - while (x != root && (x == 0 || x->color == __rb_tree_black)) - if (x == x_parent->left) { - __rb_tree_node_base* w = x_parent->right; - if (w->color == __rb_tree_red) { - w->color = __rb_tree_black; - x_parent->color = __rb_tree_red; - __rb_tree_rotate_left(x_parent, root); - w = x_parent->right; + if (__y->_M_color != _S_rb_tree_red) { + while (__x != __root && (__x == 0 || __x->_M_color == _S_rb_tree_black)) + if (__x == __x_parent->_M_left) { + _Rb_tree_node_base* __w = __x_parent->_M_right; + if (__w->_M_color == _S_rb_tree_red) { + __w->_M_color = _S_rb_tree_black; + __x_parent->_M_color = _S_rb_tree_red; + _Rb_tree_rotate_left(__x_parent, __root); + __w = __x_parent->_M_right; } - if ((w->left == 0 || w->left->color == __rb_tree_black) && - (w->right == 0 || w->right->color == __rb_tree_black)) { - w->color = __rb_tree_red; - x = x_parent; - x_parent = x_parent->parent; + if ((__w->_M_left == 0 || + __w->_M_left->_M_color == _S_rb_tree_black) && + (__w->_M_right == 0 || + __w->_M_right->_M_color == _S_rb_tree_black)) { + __w->_M_color = _S_rb_tree_red; + __x = __x_parent; + __x_parent = __x_parent->_M_parent; } else { - if (w->right == 0 || w->right->color == __rb_tree_black) { - if (w->left) w->left->color = __rb_tree_black; - w->color = __rb_tree_red; - __rb_tree_rotate_right(w, root); - w = x_parent->right; + if (__w->_M_right == 0 || + __w->_M_right->_M_color == _S_rb_tree_black) { + if (__w->_M_left) __w->_M_left->_M_color = _S_rb_tree_black; + __w->_M_color = _S_rb_tree_red; + _Rb_tree_rotate_right(__w, __root); + __w = __x_parent->_M_right; } - w->color = x_parent->color; - x_parent->color = __rb_tree_black; - if (w->right) w->right->color = __rb_tree_black; - __rb_tree_rotate_left(x_parent, root); + __w->_M_color = __x_parent->_M_color; + __x_parent->_M_color = _S_rb_tree_black; + if (__w->_M_right) __w->_M_right->_M_color = _S_rb_tree_black; + _Rb_tree_rotate_left(__x_parent, __root); break; } - } else { // same as above, with right <-> left. - __rb_tree_node_base* w = x_parent->left; - if (w->color == __rb_tree_red) { - w->color = __rb_tree_black; - x_parent->color = __rb_tree_red; - __rb_tree_rotate_right(x_parent, root); - w = x_parent->left; + } else { // same as above, with _M_right <-> _M_left. + _Rb_tree_node_base* __w = __x_parent->_M_left; + if (__w->_M_color == _S_rb_tree_red) { + __w->_M_color = _S_rb_tree_black; + __x_parent->_M_color = _S_rb_tree_red; + _Rb_tree_rotate_right(__x_parent, __root); + __w = __x_parent->_M_left; } - if ((w->right == 0 || w->right->color == __rb_tree_black) && - (w->left == 0 || w->left->color == __rb_tree_black)) { - w->color = __rb_tree_red; - x = x_parent; - x_parent = x_parent->parent; + if ((__w->_M_right == 0 || + __w->_M_right->_M_color == _S_rb_tree_black) && + (__w->_M_left == 0 || + __w->_M_left->_M_color == _S_rb_tree_black)) { + __w->_M_color = _S_rb_tree_red; + __x = __x_parent; + __x_parent = __x_parent->_M_parent; } else { - if (w->left == 0 || w->left->color == __rb_tree_black) { - if (w->right) w->right->color = __rb_tree_black; - w->color = __rb_tree_red; - __rb_tree_rotate_left(w, root); - w = x_parent->left; + if (__w->_M_left == 0 || + __w->_M_left->_M_color == _S_rb_tree_black) { + if (__w->_M_right) __w->_M_right->_M_color = _S_rb_tree_black; + __w->_M_color = _S_rb_tree_red; + _Rb_tree_rotate_left(__w, __root); + __w = __x_parent->_M_left; } - w->color = x_parent->color; - x_parent->color = __rb_tree_black; - if (w->left) w->left->color = __rb_tree_black; - __rb_tree_rotate_right(x_parent, root); + __w->_M_color = __x_parent->_M_color; + __x_parent->_M_color = _S_rb_tree_black; + if (__w->_M_left) __w->_M_left->_M_color = _S_rb_tree_black; + _Rb_tree_rotate_right(__x_parent, __root); break; } } - if (x) x->color = __rb_tree_black; + if (__x) __x->_M_color = _S_rb_tree_black; } - return y; + return __y; } -template <class Key, class Value, class KeyOfValue, class Compare, - class Alloc = alloc> -class rb_tree { +// Base class to encapsulate the differences between old SGI-style +// allocators and standard-conforming allocators. In order to avoid +// having an empty base class, we arbitrarily move one of rb_tree's +// data members into the base class. + +#ifdef __STL_USE_STD_ALLOCATORS + +// _Base for general standard-conforming allocators. +template <class _Tp, class _Alloc, bool _S_instanceless> +class _Rb_tree_alloc_base { +public: + typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type; + allocator_type get_allocator() const { return _M_node_allocator; } + + _Rb_tree_alloc_base(const allocator_type& __a) + : _M_node_allocator(__a), _M_header(0) {} + protected: - typedef void* void_pointer; - typedef __rb_tree_node_base* base_ptr; - typedef __rb_tree_node<Value> rb_tree_node; - typedef simple_alloc<rb_tree_node, Alloc> rb_tree_node_allocator; - typedef __rb_tree_color_type color_type; + typename _Alloc_traits<_Rb_tree_node<_Tp>, _Alloc>::allocator_type + _M_node_allocator; + _Rb_tree_node<_Tp>* _M_header; + + _Rb_tree_node<_Tp>* _M_get_node() + { return _M_node_allocator.allocate(1); } + void _M_put_node(_Rb_tree_node<_Tp>* __p) + { _M_node_allocator.deallocate(__p, 1); } +}; + +// Specialization for instanceless allocators. +template <class _Tp, class _Alloc> +class _Rb_tree_alloc_base<_Tp, _Alloc, true> { public: - typedef Key key_type; - typedef Value value_type; + typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Rb_tree_alloc_base(const allocator_type&) : _M_header(0) {} + +protected: + _Rb_tree_node<_Tp>* _M_header; + + typedef typename _Alloc_traits<_Rb_tree_node<_Tp>, _Alloc>::_Alloc_type + _Alloc_type; + + _Rb_tree_node<_Tp>* _M_get_node() + { return _Alloc_type::allocate(1); } + void _M_put_node(_Rb_tree_node<_Tp>* __p) + { _Alloc_type::deallocate(__p, 1); } +}; + +template <class _Tp, class _Alloc> +struct _Rb_tree_base + : public _Rb_tree_alloc_base<_Tp, _Alloc, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> +{ + typedef _Rb_tree_alloc_base<_Tp, _Alloc, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> + _Base; + typedef typename _Base::allocator_type allocator_type; + + _Rb_tree_base(const allocator_type& __a) + : _Base(__a) { _M_header = _M_get_node(); } + ~_Rb_tree_base() { _M_put_node(_M_header); } + +}; + +#else /* __STL_USE_STD_ALLOCATORS */ + +template <class _Tp, class _Alloc> +struct _Rb_tree_base +{ + typedef _Alloc allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Rb_tree_base(const allocator_type&) + : _M_header(0) { _M_header = _M_get_node(); } + ~_Rb_tree_base() { _M_put_node(_M_header); } + +protected: + _Rb_tree_node<_Tp>* _M_header; + + typedef simple_alloc<_Rb_tree_node<_Tp>, _Alloc> _Alloc_type; + + _Rb_tree_node<_Tp>* _M_get_node() + { return _Alloc_type::allocate(1); } + void _M_put_node(_Rb_tree_node<_Tp>* __p) + { _Alloc_type::deallocate(__p, 1); } +}; + +#endif /* __STL_USE_STD_ALLOCATORS */ + +template <class _Key, class _Value, class _KeyOfValue, class _Compare, + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Value) > +class _Rb_tree : protected _Rb_tree_base<_Value, _Alloc> { + typedef _Rb_tree_base<_Value, _Alloc> _Base; +protected: + typedef _Rb_tree_node_base* _Base_ptr; + typedef _Rb_tree_node<_Value> _Rb_tree_node; + typedef _Rb_tree_Color_type _Color_type; +public: + typedef _Key key_type; + typedef _Value value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type& reference; typedef const value_type& const_reference; - typedef rb_tree_node* link_type; + typedef _Rb_tree_node* _Link_type; typedef size_t size_type; typedef ptrdiff_t difference_type; + + typedef typename _Base::allocator_type allocator_type; + allocator_type get_allocator() const { return _Base::get_allocator(); } + +protected: +#ifdef __STL_USE_NAMESPACES + using _Base::_M_get_node; + using _Base::_M_put_node; + using _Base::_M_header; +#endif /* __STL_USE_NAMESPACES */ + protected: - link_type get_node() { return rb_tree_node_allocator::allocate(); } - void put_node(link_type p) { rb_tree_node_allocator::deallocate(p); } - link_type create_node(const value_type& x) { - link_type tmp = get_node(); + _Link_type _M_create_node(const value_type& __x) + { + _Link_type __tmp = _M_get_node(); __STL_TRY { - construct(&tmp->value_field, x); + construct(&__tmp->_M_value_field, __x); } - __STL_UNWIND(put_node(tmp)); - return tmp; + __STL_UNWIND(_M_put_node(__tmp)); + return __tmp; } - link_type clone_node(link_type x) { - link_type tmp = create_node(x->value_field); - tmp->color = x->color; - tmp->left = 0; - tmp->right = 0; - return tmp; + _Link_type _M_clone_node(_Link_type __x) + { + _Link_type __tmp = _M_create_node(__x->_M_value_field); + __tmp->_M_color = __x->_M_color; + __tmp->_M_left = 0; + __tmp->_M_right = 0; + return __tmp; } - void destroy_node(link_type p) { - destroy(&p->value_field); - put_node(p); + void destroy_node(_Link_type __p) + { + destroy(&__p->_M_value_field); + _M_put_node(__p); } protected: - size_type node_count; // keeps track of size of tree - link_type header; - Compare key_compare; - - link_type& root() const { return (link_type&) header->parent; } - link_type& leftmost() const { return (link_type&) header->left; } - link_type& rightmost() const { return (link_type&) header->right; } - - static link_type& left(link_type x) { return (link_type&)(x->left); } - static link_type& right(link_type x) { return (link_type&)(x->right); } - static link_type& parent(link_type x) { return (link_type&)(x->parent); } - static reference value(link_type x) { return x->value_field; } - static const Key& key(link_type x) { return KeyOfValue()(value(x)); } - static color_type& color(link_type x) { return (color_type&)(x->color); } - - static link_type& left(base_ptr x) { return (link_type&)(x->left); } - static link_type& right(base_ptr x) { return (link_type&)(x->right); } - static link_type& parent(base_ptr x) { return (link_type&)(x->parent); } - static reference value(base_ptr x) { return ((link_type)x)->value_field; } - static const Key& key(base_ptr x) { return KeyOfValue()(value(link_type(x)));} - static color_type& color(base_ptr x) { return (color_type&)(link_type(x)->color); } - - static link_type minimum(link_type x) { - return (link_type) __rb_tree_node_base::minimum(x); - } - static link_type maximum(link_type x) { - return (link_type) __rb_tree_node_base::maximum(x); - } + size_type _M_node_count; // keeps track of size of tree + _Compare _M_key_compare; + + _Link_type& _M_root() const + { return (_Link_type&) _M_header->_M_parent; } + _Link_type& _M_leftmost() const + { return (_Link_type&) _M_header->_M_left; } + _Link_type& _M_rightmost() const + { return (_Link_type&) _M_header->_M_right; } + + static _Link_type& _S_left(_Link_type __x) + { return (_Link_type&)(__x->_M_left); } + static _Link_type& _S_right(_Link_type __x) + { return (_Link_type&)(__x->_M_right); } + static _Link_type& _S_parent(_Link_type __x) + { return (_Link_type&)(__x->_M_parent); } + static reference _S_value(_Link_type __x) + { return __x->_M_value_field; } + static const _Key& _S_key(_Link_type __x) + { return _KeyOfValue()(_S_value(__x)); } + static _Color_type& _S_color(_Link_type __x) + { return (_Color_type&)(__x->_M_color); } + + static _Link_type& _S_left(_Base_ptr __x) + { return (_Link_type&)(__x->_M_left); } + static _Link_type& _S_right(_Base_ptr __x) + { return (_Link_type&)(__x->_M_right); } + static _Link_type& _S_parent(_Base_ptr __x) + { return (_Link_type&)(__x->_M_parent); } + static reference _S_value(_Base_ptr __x) + { return ((_Link_type)__x)->_M_value_field; } + static const _Key& _S_key(_Base_ptr __x) + { return _KeyOfValue()(_S_value(_Link_type(__x)));} + static _Color_type& _S_color(_Base_ptr __x) + { return (_Color_type&)(_Link_type(__x)->_M_color); } + + static _Link_type _S_minimum(_Link_type __x) + { return (_Link_type) _Rb_tree_node_base::_S_minimum(__x); } + + static _Link_type _S_maximum(_Link_type __x) + { return (_Link_type) _Rb_tree_node_base::_S_maximum(__x); } public: - typedef __rb_tree_iterator<value_type, reference, pointer> iterator; - typedef __rb_tree_iterator<value_type, const_reference, const_pointer> + 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 @@ -506,57 +633,60 @@ public: const_reference, difference_type> const_reverse_iterator; #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + private: - iterator __insert(base_ptr x, base_ptr y, const value_type& v); - link_type __copy(link_type x, link_type p); - void __erase(link_type x); - void init() { - header = get_node(); - color(header) = __rb_tree_red; // used to distinguish header from - // root, in iterator.operator++ - root() = 0; - leftmost() = header; - rightmost() = header; - } + iterator _M_insert(_Base_ptr __x, _Base_ptr __y, const value_type& __v); + _Link_type _M_copy(_Link_type __x, _Link_type __p); + void _M_erase(_Link_type __x); + public: // allocation/deallocation - rb_tree(const Compare& comp = Compare()) - : node_count(0), key_compare(comp) { init(); } + _Rb_tree() + : _Base(allocator_type()), _M_node_count(0), _M_key_compare() + { _M_empty_initialize(); } + + _Rb_tree(const _Compare& __comp) + : _Base(allocator_type()), _M_node_count(0), _M_key_compare(__comp) + { _M_empty_initialize(); } - rb_tree(const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& x) - : node_count(0), key_compare(x.key_compare) + _Rb_tree(const _Compare& __comp, const allocator_type& __a) + : _Base(__a), _M_node_count(0), _M_key_compare(__comp) + { _M_empty_initialize(); } + + _Rb_tree(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x) + : _Base(__x.get_allocator()), + _M_node_count(0), _M_key_compare(__x._M_key_compare) { - header = get_node(); - color(header) = __rb_tree_red; - if (x.root() == 0) { - root() = 0; - leftmost() = header; - rightmost() = header; - } + if (__x._M_root() == 0) + _M_empty_initialize(); else { - __STL_TRY { - root() = __copy(x.root(), header); - } - __STL_UNWIND(put_node(header)); - leftmost() = minimum(root()); - rightmost() = maximum(root()); + _S_color(_M_header) = _S_rb_tree_red; + _M_root() = _M_copy(__x._M_root(), _M_header); + _M_leftmost() = _S_minimum(_M_root()); + _M_rightmost() = _S_maximum(_M_root()); } - node_count = x.node_count; + _M_node_count = __x._M_node_count; } - ~rb_tree() { - clear(); - put_node(header); + ~_Rb_tree() { clear(); } + _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& + operator=(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x); + +private: + void _M_empty_initialize() { + _S_color(_M_header) = _S_rb_tree_red; // used to distinguish header from + // __root, in iterator.operator++ + _M_root() = 0; + _M_leftmost() = _M_header; + _M_rightmost() = _M_header; } - rb_tree<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; } + _Compare key_comp() const { return _M_key_compare; } + iterator begin() { return _M_leftmost(); } + const_iterator begin() const { return _M_leftmost(); } + iterator end() { return _M_header; } + const_iterator end() const { return _M_header; } reverse_iterator rbegin() { return reverse_iterator(end()); } const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); @@ -565,531 +695,635 @@ public: const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } - bool empty() const { return node_count == 0; } - size_type size() const { return node_count; } + bool empty() const { return _M_node_count == 0; } + size_type size() const { return _M_node_count; } size_type max_size() const { return size_type(-1); } - void swap(rb_tree<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); + void swap(_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __t) { + __STD::swap(_M_header, __t._M_header); + __STD::swap(_M_node_count, __t._M_node_count); + __STD::swap(_M_key_compare, __t._M_key_compare); } public: // insert/erase - pair<iterator,bool> insert_unique(const value_type& x); - iterator insert_equal(const value_type& x); + 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); + 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); + 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); + void insert_unique(const_iterator __first, const_iterator __last); + void insert_unique(const value_type* __first, const value_type* __last); + void insert_equal(const_iterator __first, const_iterator __last); + void insert_equal(const value_type* __first, const value_type* __last); #endif /* __STL_MEMBER_TEMPLATES */ - void erase(iterator position); - size_type erase(const key_type& x); - void erase(iterator first, iterator last); - void erase(const key_type* first, const key_type* last); + void erase(iterator __position); + size_type erase(const key_type& __x); + void erase(iterator __first, iterator __last); + void erase(const key_type* __first, const key_type* __last); void clear() { - if (node_count != 0) { - __erase(root()); - leftmost() = header; - root() = 0; - rightmost() = header; - node_count = 0; + if (_M_node_count != 0) { + _M_erase(_M_root()); + _M_leftmost() = _M_header; + _M_root() = 0; + _M_rightmost() = _M_header; + _M_node_count = 0; } } public: // set operations: - iterator find(const key_type& x); - const_iterator find(const key_type& x) const; - size_type count(const key_type& x) const; - iterator lower_bound(const key_type& x); - const_iterator lower_bound(const key_type& x) const; - iterator upper_bound(const key_type& x); - const_iterator upper_bound(const key_type& x) const; - pair<iterator,iterator> equal_range(const key_type& x); - pair<const_iterator, const_iterator> equal_range(const key_type& x) const; + iterator find(const key_type& __x); + const_iterator find(const key_type& __x) const; + size_type count(const key_type& __x) const; + iterator lower_bound(const key_type& __x); + const_iterator lower_bound(const key_type& __x) const; + iterator upper_bound(const key_type& __x); + const_iterator upper_bound(const key_type& __x) const; + pair<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 __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()); +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); +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. +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; + _M_node_count = 0; + _M_key_compare = __x._M_key_compare; + if (__x._M_root() == 0) { + _M_root() = 0; + _M_leftmost() = _M_header; + _M_rightmost() = _M_header; } else { - root() = __copy(x.root(), header); - leftmost() = minimum(root()); - rightmost() = maximum(root()); - node_count = x.node_count; + _M_root() = _M_copy(__x._M_root(), _M_header); + _M_leftmost() = _S_minimum(_M_root()); + _M_rightmost() = _S_maximum(_M_root()); + _M_node_count = __x._M_node_count; } } return *this; } -template <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; +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> + ::_M_insert(_Base_ptr __x_, _Base_ptr __y_, const _Value& __v) +{ + _Link_type __x = (_Link_type) __x_; + _Link_type __y = (_Link_type) __y_; + _Link_type __z; + + if (__y == _M_header || __x != 0 || + _M_key_compare(_KeyOfValue()(__v), _S_key(__y))) { + __z = _M_create_node(__v); + _S_left(__y) = __z; // also makes _M_leftmost() = __z + // when __y == _M_header + if (__y == _M_header) { + _M_root() = __z; + _M_rightmost() = __z; } - else if (y == leftmost()) - leftmost() = z; // maintain leftmost() pointing to min node + else if (__y == _M_leftmost()) + _M_leftmost() = __z; // maintain _M_leftmost() pointing to min node } else { - z = create_node(v); - right(y) = z; - if (y == rightmost()) - rightmost() = z; // maintain rightmost() pointing to max node + __z = _M_create_node(__v); + _S_right(__y) = __z; + if (__y == _M_rightmost()) + _M_rightmost() = __z; // maintain _M_rightmost() pointing to max node } - parent(z) = y; - left(z) = 0; - right(z) = 0; - __rb_tree_rebalance(z, header->parent); - ++node_count; - return iterator(z); + _S_parent(__z) = __y; + _S_left(__z) = 0; + _S_right(__z) = 0; + _Rb_tree_rebalance(__z, _M_header->_M_parent); + ++_M_node_count; + return iterator(__z); } -template <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) +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); + _Link_type __y = _M_header; + _Link_type __x = _M_root(); + while (__x != 0) { + __y = __x; + __x = _M_key_compare(_KeyOfValue()(__v), _S_key(__x)) ? + _S_left(__x) : _S_right(__x); } - return __insert(x, y, v); + return _M_insert(__x, __y, __v); } -template <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) +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); + _Link_type __y = _M_header; + _Link_type __x = _M_root(); + bool __comp = true; + while (__x != 0) { + __y = __x; + __comp = _M_key_compare(_KeyOfValue()(__v), _S_key(__x)); + __x = __comp ? _S_left(__x) : _S_right(__x); } - iterator j = iterator(y); - if (comp) - if (j == begin()) - return pair<iterator,bool>(__insert(x, y, v), true); + iterator __j = iterator(__y); + if (__comp) + if (__j == begin()) + return pair<iterator,bool>(_M_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); + --__j; + if (_M_key_compare(_S_key(__j._M_node), _KeyOfValue()(__v))) + return pair<iterator,bool>(_M_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 +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._M_node == _M_header->_M_left) { // begin() + if (size() > 0 && + _M_key_compare(_KeyOfValue()(__v), _S_key(__position._M_node))) + return _M_insert(__position._M_node, __position._M_node, __v); + // first argument just needs to be non-null else - return insert_unique(v).first; - else if (position.node == header) // end() - if (key_compare(key(rightmost()), KeyOfValue()(v))) - return __insert(0, rightmost(), v); + return insert_unique(__v).first; + } else if (__position._M_node == _M_header) { // end() + if (_M_key_compare(_S_key(_M_rightmost()), _KeyOfValue()(__v))) + return _M_insert(0, _M_rightmost(), __v); else - return insert_unique(v).first; - else { - iterator before = position; - --before; - if (key_compare(key(before.node), KeyOfValue()(v)) - && key_compare(KeyOfValue()(v), key(position.node))) - if (right(before.node) == 0) - return __insert(0, before.node, v); + return insert_unique(__v).first; + } else { + iterator __before = __position; + --__before; + if (_M_key_compare(_S_key(__before._M_node), _KeyOfValue()(__v)) + && _M_key_compare(_KeyOfValue()(__v), _S_key(__position._M_node))) { + if (_S_right(__before._M_node) == 0) + return _M_insert(0, __before._M_node, __v); else - return __insert(position.node, position.node, v); + return _M_insert(__position._M_node, __position._M_node, __v); // first argument just needs to be non-null - else - return insert_unique(v).first; + } else + return insert_unique(__v).first; } } -template <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 +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._M_node == _M_header->_M_left) { // begin() + if (size() > 0 && + _M_key_compare(_KeyOfValue()(__v), _S_key(__position._M_node))) + return _M_insert(__position._M_node, __position._M_node, __v); + // first argument just needs to be non-null else - return insert_equal(v); - else if (position.node == header) // end() - if (!key_compare(KeyOfValue()(v), key(rightmost()))) - return __insert(0, rightmost(), v); + return insert_equal(__v); + } else if (__position._M_node == _M_header) {// end() + if (!_M_key_compare(_KeyOfValue()(__v), _S_key(_M_rightmost()))) + return _M_insert(0, _M_rightmost(), __v); else - return insert_equal(v); - else { - iterator before = position; - --before; - if (!key_compare(KeyOfValue()(v), key(before.node)) - && !key_compare(key(position.node), KeyOfValue()(v))) - if (right(before.node) == 0) - return __insert(0, before.node, v); + return insert_equal(__v); + } else { + iterator __before = __position; + --__before; + if (!_M_key_compare(_KeyOfValue()(__v), _S_key(__before._M_node)) + && !_M_key_compare(_S_key(__position._M_node), _KeyOfValue()(__v))) { + if (_S_right(__before._M_node) == 0) + return _M_insert(0, __before._M_node, __v); else - return __insert(position.node, position.node, v); + return _M_insert(__position._M_node, __position._M_node, __v); // first argument just needs to be non-null - else - return insert_equal(v); + } else + return insert_equal(__v); } } #ifdef __STL_MEMBER_TEMPLATES -template <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 _Key, class _Val, class _KoV, class _Cmp, class _Alloc> + template<class _II> +void _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc> + ::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); +template <class _Key, class _Val, class _KoV, class _Cmp, class _Alloc> + template<class _II> +void _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc> + ::insert_unique(_II __first, _II __last) { + for ( ; __first != __last; ++__first) + insert_unique(*__first); } #else /* __STL_MEMBER_TEMPLATES */ -template <class K, class V, class KoV, class Cmp, class Al> +template <class _Key, class _Val, class _KoV, class _Cmp, class _Alloc> void -rb_tree<K, V, KoV, Cmp, Al>::insert_equal(const V* first, const V* last) { - for ( ; first != last; ++first) - insert_equal(*first); +_Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc> + ::insert_equal(const _Val* __first, const _Val* __last) +{ + for ( ; __first != __last; ++__first) + insert_equal(*__first); } -template <class K, class V, class KoV, class Cmp, class Al> +template <class _Key, class _Val, class _KoV, class _Cmp, class _Alloc> void -rb_tree<K, V, KoV, Cmp, Al>::insert_equal(const_iterator first, - const_iterator last) { - for ( ; first != last; ++first) - insert_equal(*first); +_Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc> + ::insert_equal(const_iterator __first, const_iterator __last) +{ + for ( ; __first != __last; ++__first) + insert_equal(*__first); } -template <class K, class V, class KoV, class Cmp, class A> +template <class _Key, class _Val, class _KoV, class _Cmp, class _Alloc> void -rb_tree<K, V, KoV, Cmp, A>::insert_unique(const V* first, const V* last) { - for ( ; first != last; ++first) - insert_unique(*first); +_Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc> + ::insert_unique(const _Val* __first, const _Val* __last) +{ + for ( ; __first != __last; ++__first) + insert_unique(*__first); } -template <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); +template <class _Key, class _Val, class _KoV, class _Cmp, class _Alloc> +void _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc> + ::insert_unique(const_iterator __first, const_iterator __last) +{ + for ( ; __first != __last; ++__first) + insert_unique(*__first); } #endif /* __STL_MEMBER_TEMPLATES */ -template <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> +inline void _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::erase(iterator __position) +{ + _Link_type __y = + (_Link_type) _Rb_tree_rebalance_for_erase(__position._M_node, + _M_header->_M_parent, + _M_header->_M_left, + _M_header->_M_right); + destroy_node(__y); + --_M_node_count; } -template <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 _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; +template <class _Key, class _Val, class _KoV, class _Compare, class _Alloc> +typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::_Link_type +_Rb_tree<_Key,_Val,_KoV,_Compare,_Alloc> + ::_M_copy(_Link_type __x, _Link_type __p) +{ + // structural copy. __x and __p must be non-null. + _Link_type __top = _M_clone_node(__x); + __top->_M_parent = __p; __STL_TRY { - if (x->right) - top->right = __copy(right(x), top); - p = top; - x = left(x); - - while (x != 0) { - link_type y = clone_node(x); - p->left = y; - y->parent = p; - if (x->right) - y->right = __copy(right(x), y); - p = y; - x = left(x); + if (__x->_M_right) + __top->_M_right = _M_copy(_S_right(__x), __top); + __p = __top; + __x = _S_left(__x); + + while (__x != 0) { + _Link_type __y = _M_clone_node(__x); + __p->_M_left = __y; + __y->_M_parent = __p; + if (__x->_M_right) + __y->_M_right = _M_copy(_S_right(__x), __y); + __p = __y; + __x = _S_left(__x); } } - __STL_UNWIND(__erase(top)); + __STL_UNWIND(_M_erase(__top)); - return top; + return __top; } -template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> -void rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::__erase(link_type x) { +template <class _Key, class _Value, class _KeyOfValue, + class _Compare, class _Alloc> +void _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::_M_erase(_Link_type __x) +{ // erase without rebalancing - while (x != 0) { - __erase(right(x)); - link_type y = left(x); - destroy_node(x); - x = y; + while (__x != 0) { + _M_erase(_S_right(__x)); + _Link_type __y = _S_left(__x); + destroy_node(__x); + __x = __y; } } -template <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()) +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++); + 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> +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. +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 = _M_header; // Last node which is not less than __k. + _Link_type __x = _M_root(); // Current node. - while (x != 0) - if (!key_compare(key(x), k)) - y = x, x = left(x); + while (__x != 0) + if (!_M_key_compare(_S_key(__x), __k)) + __y = __x, __x = _S_left(__x); else - x = right(x); + __x = _S_right(__x); - iterator j = iterator(y); - return (j == end() || key_compare(k, key(j.node))) ? end() : j; + iterator __j = iterator(__y); + return (__j == end() || _M_key_compare(__k, _S_key(__j._M_node))) ? + end() : __j; } -template <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. */ +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 = _M_header; /* Last node which is not less than __k. */ + _Link_type __x = _M_root(); /* Current node. */ - while (x != 0) { - if (!key_compare(key(x), k)) - y = x, x = left(x); + while (__x != 0) { + if (!_M_key_compare(_S_key(__x), __k)) + __y = __x, __x = _S_left(__x); else - x = right(x); + __x = _S_right(__x); } - const_iterator j = const_iterator(y); - return (j == end() || key_compare(k, key(j.node))) ? end() : j; + const_iterator __j = const_iterator(__y); + return (__j == end() || _M_key_compare(__k, _S_key(__j._M_node))) ? + end() : __j; } -template <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>::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. */ +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 = _M_header; /* Last node which is not less than __k. */ + _Link_type __x = _M_root(); /* Current node. */ - while (x != 0) - if (!key_compare(key(x), k)) - y = x, x = left(x); + while (__x != 0) + if (!_M_key_compare(_S_key(__x), __k)) + __y = __x, __x = _S_left(__x); else - x = right(x); + __x = _S_right(__x); - return iterator(y); + return iterator(__y); } -template <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. */ +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 = _M_header; /* Last node which is not less than __k. */ + _Link_type __x = _M_root(); /* Current node. */ - while (x != 0) - if (!key_compare(key(x), k)) - y = x, x = left(x); + while (__x != 0) + if (!_M_key_compare(_S_key(__x), __k)) + __y = __x, __x = _S_left(__x); else - x = right(x); + __x = _S_right(__x); - return const_iterator(y); + return const_iterator(__y); } -template <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. */ +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 = _M_header; /* Last node which is greater than __k. */ + _Link_type __x = _M_root(); /* Current node. */ - while (x != 0) - if (key_compare(k, key(x))) - y = x, x = left(x); + while (__x != 0) + if (_M_key_compare(__k, _S_key(__x))) + __y = __x, __x = _S_left(__x); else - x = right(x); + __x = _S_right(__x); - return iterator(y); + return iterator(__y); } -template <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. */ +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 = _M_header; /* Last node which is greater than __k. */ + _Link_type __x = _M_root(); /* Current node. */ - while (x != 0) - if (key_compare(k, key(x))) - y = x, x = left(x); + while (__x != 0) + if (_M_key_compare(__k, _S_key(__x))) + __y = __x, __x = _S_left(__x); else - x = right(x); + __x = _S_right(__x); - return const_iterator(y); + return const_iterator(__y); } -template <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 _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)); +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) +inline int +__black_count(_Rb_tree_node_base* __node, _Rb_tree_node_base* __root) { - if (node == 0) + if (__node == 0) return 0; else { - int bc = node->color == __rb_tree_black ? 1 : 0; - if (node == root) - return bc; + int __bc = __node->_M_color == _S_rb_tree_black ? 1 : 0; + if (__node == __root) + return __bc; else - return bc + __black_count(node->parent, root); + return __bc + __black_count(__node->_M_parent, __root); } } -template <class Key, class Value, class KeyOfValue, class Compare, class Alloc> -bool -rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::__rb_verify() const +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; + if (_M_node_count == 0 || begin() == end()) + return _M_node_count == 0 && begin() == end() && + _M_header->_M_left == _M_header && _M_header->_M_right == _M_header; - int len = __black_count(leftmost(), root()); - for (const_iterator it = begin(); it != end(); ++it) { - link_type x = (link_type) it.node; - link_type L = left(x); - link_type R = right(x); - - if (x->color == __rb_tree_red) - if ((L && L->color == __rb_tree_red) || - (R && R->color == __rb_tree_red)) + int __len = __black_count(_M_leftmost(), _M_root()); + for (const_iterator __it = begin(); __it != end(); ++__it) { + _Link_type __x = (_Link_type) __it._M_node; + _Link_type __L = _S_left(__x); + _Link_type __R = _S_right(__x); + + if (__x->_M_color == _S_rb_tree_red) + if ((__L && __L->_M_color == _S_rb_tree_red) || + (__R && __R->_M_color == _S_rb_tree_red)) return false; - if (L && key_compare(key(x), key(L))) + if (__L && _M_key_compare(_S_key(__x), _S_key(__L))) return false; - if (R && key_compare(key(R), key(x))) + if (__R && _M_key_compare(_S_key(__R), _S_key(__x))) return false; - if (!L && !R && __black_count(x, root()) != len) + if (!__L && !__R && __black_count(__x, _M_root()) != __len) return false; } - if (leftmost() != __rb_tree_node_base::minimum(root())) + if (_M_leftmost() != _Rb_tree_node_base::_S_minimum(_M_root())) return false; - if (rightmost() != __rb_tree_node_base::maximum(root())) + if (_M_rightmost() != _Rb_tree_node_base::_S_maximum(_M_root())) return false; return true; } +// Class rb_tree is not part of the C++ standard. It is provided for +// compatibility with the HP STL. + +template <class _Key, class _Value, class _KeyOfValue, class _Compare, + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Value) > +struct rb_tree : public _Rb_tree<_Key, _Value, _KeyOfValue, _Compare, _Alloc> +{ + typedef _Rb_tree<_Key, _Value, _KeyOfValue, _Compare, _Alloc> _Base; + typedef typename _Base::allocator_type allocator_type; + + rb_tree(const _Compare& __comp = _Compare(), + const allocator_type& __a = allocator_type()) + : _Base(__comp, __a) {} + + ~rb_tree() {} +}; + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1375 +#endif + __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_TREE_H */ diff --git a/contrib/libstdc++/stl/stl_uninitialized.h b/contrib/libstdc++/stl/stl_uninitialized.h index 661bbe9..3146c82 100644 --- a/contrib/libstdc++/stl/stl_uninitialized.h +++ b/contrib/libstdc++/stl/stl_uninitialized.h @@ -33,204 +33,241 @@ __STL_BEGIN_NAMESPACE +// uninitialized_copy + // Valid if copy construction is equivalent to assignment, and if the // destructor is trivial. -template <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; +template <class _InputIter, class _ForwardIter> +inline _ForwardIter +__uninitialized_copy_aux(_InputIter __first, _InputIter __last, + _ForwardIter __result, + __true_type) +{ + return copy(__first, __last, __result); +} + +template <class _InputIter, class _ForwardIter> +_ForwardIter +__uninitialized_copy_aux(_InputIter __first, _InputIter __last, + _ForwardIter __result, + __false_type) +{ + _ForwardIter __cur = __result; __STL_TRY { - for ( ; first != last; ++first, ++cur) - construct(&*cur, *first); - return cur; + for ( ; __first != __last; ++__first, ++__cur) + construct(&*__cur, *__first); + return __cur; } - __STL_UNWIND(destroy(result, cur)); + __STL_UNWIND(destroy(__result, __cur)); } -template <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 _InputIter, class _ForwardIter, class _Tp> +inline _ForwardIter +__uninitialized_copy(_InputIter __first, _InputIter __last, + _ForwardIter __result, _Tp*) +{ + typedef typename __type_traits<_Tp>::is_POD_type _Is_POD; + return __uninitialized_copy_aux(__first, __last, __result, _Is_POD()); } -template <class InputIterator, class ForwardIterator> -inline ForwardIterator - uninitialized_copy(InputIterator first, InputIterator last, - ForwardIterator result) { - return __uninitialized_copy(first, last, result, value_type(result)); +template <class _InputIter, class _ForwardIter> +inline _ForwardIter + uninitialized_copy(_InputIter __first, _InputIter __last, + _ForwardIter __result) +{ + return __uninitialized_copy(__first, __last, __result, + __VALUE_TYPE(__result)); } -inline char* uninitialized_copy(const char* first, const char* last, - char* result) { - memmove(result, first, last - first); - return result + (last - first); +inline char* uninitialized_copy(const char* __first, const char* __last, + char* __result) { + memmove(__result, __first, __last - __first); + return __result + (__last - __first); } -inline wchar_t* uninitialized_copy(const wchar_t* first, const wchar_t* last, - wchar_t* result) { - memmove(result, first, sizeof(wchar_t) * (last - first)); - return result + (last - first); +inline wchar_t* +uninitialized_copy(const wchar_t* __first, const wchar_t* __last, + wchar_t* __result) +{ + memmove(__result, __first, sizeof(wchar_t) * (__last - __first)); + return __result + (__last - __first); } -template <class InputIterator, class Size, class ForwardIterator> -pair<InputIterator, ForwardIterator> -__uninitialized_copy_n(InputIterator first, Size count, - ForwardIterator result, - input_iterator_tag) { - ForwardIterator cur = result; +// uninitialized_copy_n (not part of the C++ standard) + +template <class _InputIter, class _Size, class _ForwardIter> +pair<_InputIter, _ForwardIter> +__uninitialized_copy_n(_InputIter __first, _Size __count, + _ForwardIter __result, + input_iterator_tag) +{ + _ForwardIter __cur = __result; __STL_TRY { - for ( ; count > 0 ; --count, ++first, ++cur) - construct(&*cur, *first); - return pair<InputIterator, ForwardIterator>(first, cur); + for ( ; __count > 0 ; --__count, ++__first, ++__cur) + construct(&*__cur, *__first); + return pair<_InputIter, _ForwardIter>(__first, __cur); } - __STL_UNWIND(destroy(result, cur)); + __STL_UNWIND(destroy(__result, __cur)); } -template <class RandomAccessIterator, class Size, class ForwardIterator> -inline pair<RandomAccessIterator, ForwardIterator> -__uninitialized_copy_n(RandomAccessIterator first, Size count, - ForwardIterator result, +template <class _RandomAccessIter, class _Size, class _ForwardIter> +inline pair<_RandomAccessIter, _ForwardIter> +__uninitialized_copy_n(_RandomAccessIter __first, _Size __count, + _ForwardIter __result, random_access_iterator_tag) { - RandomAccessIterator last = first + count; - return make_pair(last, uninitialized_copy(first, last, result)); + _RandomAccessIter __last = __first + __count; + return pair<_RandomAccessIter, _ForwardIter>( + __last, + uninitialized_copy(__first, __last, __result)); } -template <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)); +template <class _InputIter, class _Size, class _ForwardIter> +inline pair<_InputIter, _ForwardIter> +__uninitialized_copy_n(_InputIter __first, _Size __count, + _ForwardIter __result) { + return __uninitialized_copy_n(__first, __count, __result, + __ITERATOR_CATEGORY(__first)); +} + +template <class _InputIter, class _Size, class _ForwardIter> +inline pair<_InputIter, _ForwardIter> +uninitialized_copy_n(_InputIter __first, _Size __count, + _ForwardIter __result) { + return __uninitialized_copy_n(__first, __count, __result, + __ITERATOR_CATEGORY(__first)); } // Valid if copy construction is equivalent to assignment, and if the -// destructor is trivial. -template <class ForwardIterator, class T> +// destructor is trivial. +template <class _ForwardIter, class _Tp> inline void -__uninitialized_fill_aux(ForwardIterator first, ForwardIterator last, - const T& x, __true_type) +__uninitialized_fill_aux(_ForwardIter __first, _ForwardIter __last, + const _Tp& __x, __true_type) { - fill(first, last, x); + fill(__first, __last, __x); } -template <class ForwardIterator, class T> +template <class _ForwardIter, class _Tp> void -__uninitialized_fill_aux(ForwardIterator first, ForwardIterator last, - const T& x, __false_type) +__uninitialized_fill_aux(_ForwardIter __first, _ForwardIter __last, + const _Tp& __x, __false_type) { - ForwardIterator cur = first; + _ForwardIter __cur = __first; __STL_TRY { - for ( ; cur != last; ++cur) - construct(&*cur, x); + for ( ; __cur != __last; ++__cur) + construct(&*__cur, __x); } - __STL_UNWIND(destroy(first, cur)); + __STL_UNWIND(destroy(__first, __cur)); } -template <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 _ForwardIter, class _Tp, class _Tp1> +inline void __uninitialized_fill(_ForwardIter __first, + _ForwardIter __last, const _Tp& __x, _Tp1*) +{ + typedef typename __type_traits<_Tp1>::is_POD_type _Is_POD; + __uninitialized_fill_aux(__first, __last, __x, _Is_POD()); } -template <class ForwardIterator, class T> -inline void uninitialized_fill(ForwardIterator first, ForwardIterator last, - const T& x) { - __uninitialized_fill(first, last, x, value_type(first)); +template <class _ForwardIter, class _Tp> +inline void uninitialized_fill(_ForwardIter __first, + _ForwardIter __last, + const _Tp& __x) +{ + __uninitialized_fill(__first, __last, __x, __VALUE_TYPE(__first)); } // Valid if copy construction is equivalent to assignment, and if the // destructor is trivial. -template <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; +template <class _ForwardIter, class _Size, class _Tp> +inline _ForwardIter +__uninitialized_fill_n_aux(_ForwardIter __first, _Size __n, + const _Tp& __x, __true_type) +{ + return fill_n(__first, __n, __x); +} + +template <class _ForwardIter, class _Size, class _Tp> +_ForwardIter +__uninitialized_fill_n_aux(_ForwardIter __first, _Size __n, + const _Tp& __x, __false_type) +{ + _ForwardIter __cur = __first; __STL_TRY { - for ( ; n > 0; --n, ++cur) - construct(&*cur, x); - return cur; + for ( ; __n > 0; --__n, ++__cur) + construct(&*__cur, __x); + return __cur; } - __STL_UNWIND(destroy(first, cur)); + __STL_UNWIND(destroy(__first, __cur)); } -template <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 _ForwardIter, class _Size, class _Tp, class _Tp1> +inline _ForwardIter +__uninitialized_fill_n(_ForwardIter __first, _Size __n, const _Tp& __x, _Tp1*) +{ + typedef typename __type_traits<_Tp1>::is_POD_type _Is_POD; + return __uninitialized_fill_n_aux(__first, __n, __x, _Is_POD()); } -template <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)); +template <class _ForwardIter, class _Size, class _Tp> +inline _ForwardIter +uninitialized_fill_n(_ForwardIter __first, _Size __n, const _Tp& __x) +{ + return __uninitialized_fill_n(__first, __n, __x, __VALUE_TYPE(__first)); } +// Extensions: __uninitialized_copy_copy, __uninitialized_copy_fill, +// __uninitialized_fill_copy. + +// __uninitialized_copy_copy // Copies [first1, last1) into [result, result + (last1 - first1)), and // copies [first2, last2) into // [result, result + (last1 - first1) + (last2 - first2)). -template <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); +template <class _InputIter1, class _InputIter2, class _ForwardIter> +inline _ForwardIter +__uninitialized_copy_copy(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _ForwardIter __result) +{ + _ForwardIter __mid = uninitialized_copy(__first1, __last1, __result); __STL_TRY { - return uninitialized_copy(first2, last2, mid); + return uninitialized_copy(__first2, __last2, __mid); } - __STL_UNWIND(destroy(result, mid)); + __STL_UNWIND(destroy(__result, __mid)); } +// __uninitialized_fill_copy // Fills [result, mid) with x, and copies [first, last) into // [mid, mid + (last - first)). -template <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); +template <class _ForwardIter, class _Tp, class _InputIter> +inline _ForwardIter +__uninitialized_fill_copy(_ForwardIter __result, _ForwardIter __mid, + const _Tp& __x, + _InputIter __first, _InputIter __last) +{ + uninitialized_fill(__result, __mid, __x); __STL_TRY { - return uninitialized_copy(first, last, mid); + return uninitialized_copy(__first, __last, __mid); } - __STL_UNWIND(destroy(result, mid)); + __STL_UNWIND(destroy(__result, __mid)); } +// __uninitialized_copy_fill // Copies [first1, last1) into [first2, first2 + (last1 - first1)), and // fills [first2 + (last1 - first1), last2) with x. -template <class InputIterator, class ForwardIterator, class T> +template <class _InputIter, class _ForwardIter, class _Tp> inline void -__uninitialized_copy_fill(InputIterator first1, InputIterator last1, - ForwardIterator first2, ForwardIterator last2, - const T& x) { - ForwardIterator mid2 = uninitialized_copy(first1, last1, first2); +__uninitialized_copy_fill(_InputIter __first1, _InputIter __last1, + _ForwardIter __first2, _ForwardIter __last2, + const _Tp& __x) +{ + _ForwardIter __mid2 = uninitialized_copy(__first1, __last1, __first2); __STL_TRY { - uninitialized_fill(mid2, last2, x); + uninitialized_fill(__mid2, __last2, __x); } - __STL_UNWIND(destroy(first2, mid2)); + __STL_UNWIND(destroy(__first2, __mid2)); } __STL_END_NAMESPACE diff --git a/contrib/libstdc++/stl/stl_vector.h b/contrib/libstdc++/stl/stl_vector.h index cfa7fdb..d1149e9 100644 --- a/contrib/libstdc++/stl/stl_vector.h +++ b/contrib/libstdc++/stl/stl_vector.h @@ -35,12 +35,127 @@ __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 +#pragma set woff 1375 #endif -template <class T, class Alloc = alloc> -class vector { +// The vector base class serves two purposes. First, its constructor +// and destructor allocate (but don't initialize) storage. This makes +// exception safety easier. Second, the base class encapsulates all of +// the differences between SGI-style allocators and standard-conforming +// allocators. + +#ifdef __STL_USE_STD_ALLOCATORS + +// Base class for ordinary allocators. +template <class _Tp, class _Allocator, bool _IsStatic> +class _Vector_alloc_base { +public: + typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return _M_data_allocator; } + + _Vector_alloc_base(const allocator_type& __a) + : _M_data_allocator(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0) + {} + +protected: + allocator_type _M_data_allocator; + _Tp* _M_start; + _Tp* _M_finish; + _Tp* _M_end_of_storage; + + _Tp* _M_allocate(size_t __n) + { return _M_data_allocator.allocate(__n); } + void _M_deallocate(_Tp* __p, size_t __n) + { if (__p) _M_data_allocator.deallocate(__p, __n); } +}; + +// Specialization for allocators that have the property that we don't +// actually have to store an allocator object. +template <class _Tp, class _Allocator> +class _Vector_alloc_base<_Tp, _Allocator, true> { +public: + typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Vector_alloc_base(const allocator_type&) + : _M_start(0), _M_finish(0), _M_end_of_storage(0) + {} + +protected: + _Tp* _M_start; + _Tp* _M_finish; + _Tp* _M_end_of_storage; + + typedef typename _Alloc_traits<_Tp, _Allocator>::_Alloc_type _Alloc_type; + _Tp* _M_allocate(size_t __n) + { return _Alloc_type::allocate(__n); } + void _M_deallocate(_Tp* __p, size_t __n) + { _Alloc_type::deallocate(__p, __n);} +}; + +template <class _Tp, class _Alloc> +struct _Vector_base + : public _Vector_alloc_base<_Tp, _Alloc, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> +{ + typedef _Vector_alloc_base<_Tp, _Alloc, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> + _Base; + typedef typename _Base::allocator_type allocator_type; + + _Vector_base(const allocator_type& __a) : _Base(__a) {} + _Vector_base(size_t __n, const allocator_type& __a) : _Base(__a) { + _M_start = _M_allocate(__n); + _M_finish = _M_start; + _M_end_of_storage = _M_start + __n; + } + + ~_Vector_base() { _M_deallocate(_M_start, _M_end_of_storage - _M_start); } +}; + +#else /* __STL_USE_STD_ALLOCATORS */ + +template <class _Tp, class _Alloc> +class _Vector_base { public: - typedef T value_type; + typedef _Alloc allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Vector_base(const _Alloc&) + : _M_start(0), _M_finish(0), _M_end_of_storage(0) {} + _Vector_base(size_t __n, const _Alloc&) + : _M_start(0), _M_finish(0), _M_end_of_storage(0) + { + _M_start = _M_allocate(__n); + _M_finish = _M_start; + _M_end_of_storage = _M_start + __n; + } + + ~_Vector_base() { _M_deallocate(_M_start, _M_end_of_storage - _M_start); } + +protected: + _Tp* _M_start; + _Tp* _M_finish; + _Tp* _M_end_of_storage; + + typedef simple_alloc<_Tp, _Alloc> _M_data_allocator; + _Tp* _M_allocate(size_t __n) + { return _M_data_allocator::allocate(__n); } + void _M_deallocate(_Tp* __p, size_t __n) + { _M_data_allocator::deallocate(__p, __n); } +}; + +#endif /* __STL_USE_STD_ALLOCATORS */ + +template <class _Tp, class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) > +class vector : protected _Vector_base<_Tp, _Alloc> +{ +private: + typedef _Vector_base<_Tp, _Alloc> _Base; +public: + typedef _Tp value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type* iterator; @@ -50,6 +165,9 @@ public: typedef size_t size_type; typedef ptrdiff_t difference_type; + typedef typename _Base::allocator_type allocator_type; + allocator_type get_allocator() const { return _Base::get_allocator(); } + #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION typedef reverse_iterator<const_iterator> const_reverse_iterator; typedef reverse_iterator<iterator> reverse_iterator; @@ -59,462 +177,632 @@ public: 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); - } +#ifdef __STL_HAS_NAMESPACES + using _Base::_M_allocate; + using _Base::_M_deallocate; + using _Base::_M_start; + using _Base::_M_finish; + using _Base::_M_end_of_storage; +#endif /* __STL_HAS_NAMESPACES */ + +protected: + void _M_insert_aux(iterator __position, const _Tp& __x); + void _M_insert_aux(iterator __position); - void fill_initialize(size_type n, const T& value) { - start = allocate_and_fill(n, value); - finish = start + n; - end_of_storage = finish; - } public: - iterator begin() { return start; } - const_iterator begin() const { return start; } - iterator end() { return finish; } - const_iterator end() const { return finish; } - reverse_iterator rbegin() { return reverse_iterator(end()); } - const_reverse_iterator rbegin() const { - return const_reverse_iterator(end()); - } - reverse_iterator rend() { return reverse_iterator(begin()); } - const_reverse_iterator rend() const { - return const_reverse_iterator(begin()); - } - size_type size() const { return size_type(end() - begin()); } - size_type max_size() const { return size_type(-1) / sizeof(T); } - size_type capacity() const { return size_type(end_of_storage - begin()); } - bool empty() const { return begin() == end(); } - reference operator[](size_type n) { return *(begin() + n); } - const_reference operator[](size_type n) const { return *(begin() + n); } - - vector() : start(0), finish(0), end_of_storage(0) {} - vector(size_type n, const T& value) { fill_initialize(n, value); } - vector(int n, const T& value) { fill_initialize(n, value); } - vector(long n, const T& value) { fill_initialize(n, value); } - explicit vector(size_type n) { fill_initialize(n, T()); } - - vector(const vector<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; - } + iterator begin() { return _M_start; } + const_iterator begin() const { return _M_start; } + iterator end() { return _M_finish; } + const_iterator end() const { return _M_finish; } + + reverse_iterator rbegin() + { return reverse_iterator(end()); } + const_reverse_iterator rbegin() const + { return const_reverse_iterator(end()); } + reverse_iterator rend() + { return reverse_iterator(begin()); } + const_reverse_iterator rend() const + { return const_reverse_iterator(begin()); } + + size_type size() const + { return size_type(end() - begin()); } + size_type max_size() const + { return size_type(-1) / sizeof(_Tp); } + size_type capacity() const + { return size_type(_M_end_of_storage - begin()); } + bool empty() const + { return begin() == end(); } + + reference operator[](size_type __n) { return *(begin() + __n); } + const_reference operator[](size_type __n) const { return *(begin() + __n); } + + explicit vector(const allocator_type& __a = allocator_type()) + : _Base(__a) {} + + vector(size_type __n, const _Tp& __value, + const allocator_type& __a = allocator_type()) + : _Base(__n, __a) + { _M_finish = uninitialized_fill_n(_M_start, __n, __value); } + + explicit vector(size_type __n) + : _Base(__n, allocator_type()) + { _M_finish = uninitialized_fill_n(_M_start, __n, _Tp()); } + + vector(const vector<_Tp, _Alloc>& __x) + : _Base(__x.size(), __x.get_allocator()) + { _M_finish = uninitialized_copy(__x.begin(), __x.end(), _M_start); } + #ifdef __STL_MEMBER_TEMPLATES - template <class InputIterator> - vector(InputIterator first, InputIterator last) : - start(0), finish(0), end_of_storage(0) - { - range_initialize(first, last, iterator_category(first)); + // Check whether it's an integral type. If so, it's not an iterator. + template <class _InputIterator> + vector(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) : _Base(__a) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_initialize_aux(__first, __last, _Integral()); } -#else /* __STL_MEMBER_TEMPLATES */ - vector(const_iterator first, const_iterator last) { - size_type n = 0; - distance(first, last, n); - start = allocate_and_copy(n, first, last); - finish = start + n; - end_of_storage = finish; + + template <class _Integer> + void _M_initialize_aux(_Integer __n, _Integer __value, __true_type) { + _M_start = _M_allocate(__n); + _M_end_of_storage = _M_start + __n; + _M_finish = uninitialized_fill_n(_M_start, __n, __value); + } + + template <class _InputIterator> + void _M_initialize_aux(_InputIterator __first, _InputIterator __last, + __false_type) { + _M_range_initialize(__first, __last, __ITERATOR_CATEGORY(__first)); } + +#else + vector(const _Tp* __first, const _Tp* __last, + const allocator_type& __a = allocator_type()) + : _Base(__last - __first, __a) + { _M_finish = uninitialized_copy(__first, __last, _M_start); } #endif /* __STL_MEMBER_TEMPLATES */ - ~vector() { - destroy(start, finish); - deallocate(); - } - vector<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; + + ~vector() { destroy(_M_start, _M_finish); } + + vector<_Tp, _Alloc>& operator=(const vector<_Tp, _Alloc>& __x); + void reserve(size_type __n) { + if (capacity() < __n) { + const size_type __old_size = size(); + iterator __tmp = _M_allocate_and_copy(__n, _M_start, _M_finish); + destroy(_M_start, _M_finish); + _M_deallocate(_M_start, _M_end_of_storage - _M_start); + _M_start = __tmp; + _M_finish = __tmp + __old_size; + _M_end_of_storage = _M_start + __n; } } + + // assign(), a generalized assignment member function. Two + // versions: one that takes a count, and one that takes a range. + // The range version is a member template, so we dispatch on whether + // or not the type is an integer. + + void assign(size_type __n, const _Tp& __val); + +#ifdef __STL_MEMBER_TEMPLATES + + template <class _InputIterator> + void assign(_InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } + + template <class _Integer> + void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { assign((size_type) __n, (_Tp) __val); } + + template <class _InputIter> + void _M_assign_dispatch(_InputIter __first, _InputIter __last, __false_type) + { _M_assign_aux(__first, __last, __ITERATOR_CATEGORY(__first)); } + + template <class _InputIterator> + void _M_assign_aux(_InputIterator __first, _InputIterator __last, + input_iterator_tag); + + template <class _ForwardIterator> + void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag); + +#endif /* __STL_MEMBER_TEMPLATES */ + reference front() { return *begin(); } const_reference front() const { return *begin(); } reference back() { return *(end() - 1); } const_reference back() const { return *(end() - 1); } - void push_back(const T& x) { - if (finish != end_of_storage) { - construct(finish, x); - ++finish; + + void push_back(const _Tp& __x) { + if (_M_finish != _M_end_of_storage) { + construct(_M_finish, __x); + ++_M_finish; } else - insert_aux(end(), x); - } - void swap(vector<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; + _M_insert_aux(end(), __x); + } + void push_back() { + if (_M_finish != _M_end_of_storage) { + construct(_M_finish); + ++_M_finish; } else - insert_aux(position, x); - return begin() + n; + _M_insert_aux(end()); + } + void swap(vector<_Tp, _Alloc>& __x) { + __STD::swap(_M_start, __x._M_start); + __STD::swap(_M_finish, __x._M_finish); + __STD::swap(_M_end_of_storage, __x._M_end_of_storage); + } + + iterator insert(iterator __position, const _Tp& __x) { + size_type __n = __position - begin(); + if (_M_finish != _M_end_of_storage && __position == end()) { + construct(_M_finish, __x); + ++_M_finish; + } + else + _M_insert_aux(__position, __x); + return begin() + __n; + } + iterator insert(iterator __position) { + size_type __n = __position - begin(); + if (_M_finish != _M_end_of_storage && __position == end()) { + construct(_M_finish); + ++_M_finish; + } + else + _M_insert_aux(__position); + return begin() + __n; } - iterator insert(iterator position) { return insert(position, T()); } #ifdef __STL_MEMBER_TEMPLATES - template <class InputIterator> - void insert(iterator position, InputIterator first, InputIterator last) { - range_insert(position, first, last, iterator_category(first)); + // Check whether it's an integral type. If so, it's not an iterator. + template <class _InputIterator> + void insert(iterator __pos, _InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_insert_dispatch(__pos, __first, __last, _Integral()); + } + + template <class _Integer> + void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val, + __true_type) { + insert(__pos, (size_type) __n, (_Tp) __val); + } + + template <class _InputIterator> + void _M_insert_dispatch(iterator __pos, + _InputIterator __first, _InputIterator __last, + __false_type) { + _M_range_insert(__pos, __first, __last, __ITERATOR_CATEGORY(__first)); } #else /* __STL_MEMBER_TEMPLATES */ - void insert(iterator position, - const_iterator first, const_iterator last); + void insert(iterator __position, + const_iterator __first, const_iterator __last); #endif /* __STL_MEMBER_TEMPLATES */ - void insert (iterator pos, size_type n, const T& x); - void insert (iterator pos, int n, const T& x) { - insert(pos, (size_type) n, x); + void insert (iterator __pos, size_type __n, const _Tp& __x); + + void pop_back() { + --_M_finish; + destroy(_M_finish); + } + iterator erase(iterator __position) { + if (__position + 1 != end()) + copy(__position + 1, _M_finish, __position); + --_M_finish; + destroy(_M_finish); + return __position; } - void insert (iterator pos, long n, const T& x) { - insert(pos, (size_type) n, x); + iterator erase(iterator __first, iterator __last) { + iterator __i = copy(__last, _M_finish, __first); + destroy(__i, _M_finish); + _M_finish = _M_finish - (__last - __first); + return __first; } - void pop_back() { - --finish; - destroy(finish); - } - iterator erase(iterator position) { - if (position + 1 != end()) - copy(position + 1, finish, position); - --finish; - destroy(finish); - return position; - } - iterator erase(iterator first, iterator last) { - iterator i = copy(last, finish, first); - destroy(i, finish); - finish = finish - (last - first); - return first; - } - void resize(size_type new_size, const T& x) { - if (new_size < size()) - erase(begin() + new_size, end()); + void resize(size_type __new_size, const _Tp& __x) { + if (__new_size < size()) + erase(begin() + __new_size, end()); else - insert(end(), new_size - size(), x); + insert(end(), __new_size - size(), __x); } - void resize(size_type new_size) { resize(new_size, T()); } + void resize(size_type __new_size) { resize(__new_size, _Tp()); } void clear() { erase(begin(), end()); } protected: - iterator allocate_and_fill(size_type n, const T& x) { - iterator result = data_allocator::allocate(n); - __STL_TRY { - uninitialized_fill_n(result, n, x); - return result; - } - __STL_UNWIND(data_allocator::deallocate(result, n)); - } #ifdef __STL_MEMBER_TEMPLATES - template <class ForwardIterator> - iterator allocate_and_copy(size_type n, - ForwardIterator first, ForwardIterator last) { - iterator result = data_allocator::allocate(n); + template <class _ForwardIterator> + iterator _M_allocate_and_copy(size_type __n, _ForwardIterator __first, + _ForwardIterator __last) +{ + iterator __result = _M_allocate(__n); __STL_TRY { - uninitialized_copy(first, last, result); - return result; + uninitialized_copy(__first, __last, __result); + return __result; } - __STL_UNWIND(data_allocator::deallocate(result, n)); + __STL_UNWIND(_M_deallocate(__result, __n)); } #else /* __STL_MEMBER_TEMPLATES */ - iterator allocate_and_copy(size_type n, - const_iterator first, const_iterator last) { - iterator result = data_allocator::allocate(n); + iterator _M_allocate_and_copy(size_type __n, const_iterator __first, + const_iterator __last) + { + iterator __result = _M_allocate(__n); __STL_TRY { - uninitialized_copy(first, last, result); - return result; + uninitialized_copy(__first, __last, __result); + return __result; } - __STL_UNWIND(data_allocator::deallocate(result, n)); + __STL_UNWIND(_M_deallocate(__result, __n)); } #endif /* __STL_MEMBER_TEMPLATES */ #ifdef __STL_MEMBER_TEMPLATES - template <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); + template <class _InputIterator> + void _M_range_initialize(_InputIterator __first, + _InputIterator __last, input_iterator_tag) + { + for ( ; __first != __last; ++__first) + push_back(*__first); + } + + // This function is only called by the constructor. + template <class _ForwardIterator> + void _M_range_initialize(_ForwardIterator __first, + _ForwardIterator __last, forward_iterator_tag) + { + size_type __n = 0; + distance(__first, __last, __n); + _M_start = _M_allocate(__n); + _M_end_of_storage = _M_start + __n; + _M_finish = uninitialized_copy(__first, __last, _M_start); + } + + template <class _InputIterator> + void _M_range_insert(iterator __pos, + _InputIterator __first, _InputIterator __last, + input_iterator_tag); + + template <class _ForwardIterator> + void _M_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 _Tp, class _Alloc> +inline bool +operator==(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) +{ + return __x.size() == __y.size() && + equal(__x.begin(), __x.end(), __y.begin()); } -template <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()); +template <class _Tp, class _Alloc> +inline bool +operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) +{ + return lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER -template <class T, class Alloc> -inline void swap(vector<T, Alloc>& x, vector<T, Alloc>& y) { - x.swap(y); +template <class _Tp, class _Alloc> +inline void swap(vector<_Tp, _Alloc>& __x, vector<_Tp, _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()); +template <class _Tp, class _Alloc> +vector<_Tp,_Alloc>& +vector<_Tp,_Alloc>::operator=(const vector<_Tp, _Alloc>& __x) +{ + if (&__x != this) { + const size_type __xlen = __x.size(); + if (__xlen > capacity()) { + iterator __tmp = _M_allocate_and_copy(__xlen, __x.begin(), __x.end()); + destroy(_M_start, _M_finish); + _M_deallocate(_M_start, _M_end_of_storage - _M_start); + _M_start = __tmp; + _M_end_of_storage = _M_start + __xlen; } - else if (size() >= x.size()) { - iterator i = copy(x.begin(), x.end(), begin()); - destroy(i, finish); + else if (size() >= __xlen) { + iterator __i = copy(__x.begin(), __x.end(), begin()); + destroy(__i, _M_finish); } else { - copy(x.begin(), x.begin() + size(), start); - uninitialized_copy(x.begin() + size(), x.end(), finish); + copy(__x.begin(), __x.begin() + size(), _M_start); + uninitialized_copy(__x.begin() + size(), __x.end(), _M_finish); } - finish = start + x.size(); + _M_finish = _M_start + __xlen; } return *this; } -template <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; +template <class _Tp, class _Alloc> +void vector<_Tp, _Alloc>::assign(size_t __n, const value_type& __val) { + if (__n > capacity()) { + vector<_Tp, _Alloc> __tmp(__n, __val, get_allocator()); + __tmp.swap(*this); + } + else if (__n > size()) { + fill(begin(), end(), __val); + _M_finish = uninitialized_fill_n(_M_finish, __n - size(), __val); + } + else + erase(fill_n(begin(), __n, __val), end()); +} + +#ifdef __STL_MEMBER_TEMPLATES + +template <class _Tp, class _Alloc> template <class _InputIter> +void vector<_Tp, _Alloc>::_M_assign_aux(_InputIter __first, _InputIter __last, + input_iterator_tag) { + iterator __cur = begin(); + for ( ; __first != __last && __cur != end(); ++__cur, ++__first) + *__cur = *__first; + if (__first == __last) + erase(__cur, end()); + else + insert(end(), __first, __last); +} + +template <class _Tp, class _Alloc> template <class _ForwardIter> +void +vector<_Tp, _Alloc>::_M_assign_aux(_ForwardIter __first, _ForwardIter __last, + forward_iterator_tag) { + size_type __len = 0; + distance(__first, __last, __len); + + if (__len > capacity()) { + iterator __tmp = _M_allocate_and_copy(__len, __first, __last); + destroy(_M_start, _M_finish); + _M_deallocate(_M_start, _M_end_of_storage - _M_start); + _M_start = __tmp; + _M_end_of_storage = _M_finish = _M_start + __len; + } + else if (size() >= __len) { + iterator __new_finish = copy(__first, __last, _M_start); + destroy(__new_finish, _M_finish); + _M_finish = __new_finish; + } + else { + _ForwardIter __mid = __first; + advance(__mid, size()); + copy(__first, __mid, _M_start); + _M_finish = uninitialized_copy(__mid, __last, _M_finish); + } +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +template <class _Tp, class _Alloc> +void +vector<_Tp, _Alloc>::_M_insert_aux(iterator __position, const _Tp& __x) +{ + if (_M_finish != _M_end_of_storage) { + construct(_M_finish, *(_M_finish - 1)); + ++_M_finish; + _Tp __x_copy = __x; + copy_backward(__position, _M_finish - 2, _M_finish - 1); + *__position = __x_copy; } else { - const size_type old_size = size(); - const size_type len = old_size != 0 ? 2 * old_size : 1; - iterator new_start = data_allocator::allocate(len); - iterator new_finish = new_start; + const size_type __old_size = size(); + const size_type __len = __old_size != 0 ? 2 * __old_size : 1; + iterator __new_start = _M_allocate(__len); + iterator __new_finish = __new_start; __STL_TRY { - new_finish = uninitialized_copy(start, position, new_start); - construct(new_finish, x); - ++new_finish; - new_finish = uninitialized_copy(position, finish, new_finish); + __new_finish = uninitialized_copy(_M_start, __position, __new_start); + construct(__new_finish, __x); + ++__new_finish; + __new_finish = uninitialized_copy(__position, _M_finish, __new_finish); } + __STL_UNWIND((destroy(__new_start,__new_finish), + _M_deallocate(__new_start,__len))); + destroy(begin(), end()); + _M_deallocate(_M_start, _M_end_of_storage - _M_start); + _M_start = __new_start; + _M_finish = __new_finish; + _M_end_of_storage = __new_start + __len; + } +} -# ifdef __STL_USE_EXCEPTIONS - catch(...) { - destroy(new_start, new_finish); - data_allocator::deallocate(new_start, len); - throw; +template <class _Tp, class _Alloc> +void +vector<_Tp, _Alloc>::_M_insert_aux(iterator __position) +{ + if (_M_finish != _M_end_of_storage) { + construct(_M_finish, *(_M_finish - 1)); + ++_M_finish; + copy_backward(__position, _M_finish - 2, _M_finish - 1); + *__position = _Tp(); + } + else { + const size_type __old_size = size(); + const size_type __len = __old_size != 0 ? 2 * __old_size : 1; + iterator __new_start = _M_allocate(__len); + iterator __new_finish = __new_start; + __STL_TRY { + __new_finish = uninitialized_copy(_M_start, __position, __new_start); + construct(__new_finish); + ++__new_finish; + __new_finish = uninitialized_copy(__position, _M_finish, __new_finish); } -# endif /* __STL_USE_EXCEPTIONS */ + __STL_UNWIND((destroy(__new_start,__new_finish), + _M_deallocate(__new_start,__len))); destroy(begin(), end()); - deallocate(); - start = new_start; - finish = new_finish; - end_of_storage = new_start + len; + _M_deallocate(_M_start, _M_end_of_storage - _M_start); + _M_start = __new_start; + _M_finish = __new_finish; + _M_end_of_storage = __new_start + __len; } } -template <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); +template <class _Tp, class _Alloc> +void vector<_Tp, _Alloc>::insert(iterator __position, size_type __n, + const _Tp& __x) +{ + if (__n != 0) { + if (size_type(_M_end_of_storage - _M_finish) >= __n) { + _Tp __x_copy = __x; + const size_type __elems_after = _M_finish - __position; + iterator __old_finish = _M_finish; + if (__elems_after > __n) { + uninitialized_copy(_M_finish - __n, _M_finish, _M_finish); + _M_finish += __n; + copy_backward(__position, __old_finish - __n, __old_finish); + fill(__position, __position + __n, __x_copy); } else { - uninitialized_fill_n(finish, n - elems_after, x_copy); - finish += n - elems_after; - uninitialized_copy(position, old_finish, finish); - finish += elems_after; - fill(position, old_finish, x_copy); + uninitialized_fill_n(_M_finish, __n - __elems_after, __x_copy); + _M_finish += __n - __elems_after; + uninitialized_copy(__position, __old_finish, _M_finish); + _M_finish += __elems_after; + fill(__position, __old_finish, __x_copy); } } else { - const size_type old_size = size(); - const size_type len = old_size + max(old_size, n); - iterator new_start = data_allocator::allocate(len); - iterator new_finish = new_start; + const size_type __old_size = size(); + const size_type __len = __old_size + max(__old_size, __n); + iterator __new_start = _M_allocate(__len); + iterator __new_finish = __new_start; __STL_TRY { - new_finish = uninitialized_copy(start, position, new_start); - new_finish = uninitialized_fill_n(new_finish, n, x); - new_finish = uninitialized_copy(position, finish, new_finish); + __new_finish = uninitialized_copy(_M_start, __position, __new_start); + __new_finish = uninitialized_fill_n(__new_finish, __n, __x); + __new_finish + = uninitialized_copy(__position, _M_finish, __new_finish); } -# ifdef __STL_USE_EXCEPTIONS - catch(...) { - destroy(new_start, new_finish); - data_allocator::deallocate(new_start, len); - throw; - } -# endif /* __STL_USE_EXCEPTIONS */ - destroy(start, finish); - deallocate(); - start = new_start; - finish = new_finish; - end_of_storage = new_start + len; + __STL_UNWIND((destroy(__new_start,__new_finish), + _M_deallocate(__new_start,__len))); + destroy(_M_start, _M_finish); + _M_deallocate(_M_start, _M_end_of_storage - _M_start); + _M_start = __new_start; + _M_finish = __new_finish; + _M_end_of_storage = __new_start + __len; } } } #ifdef __STL_MEMBER_TEMPLATES -template <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 _Tp, class _Alloc> template <class _InputIterator> +void +vector<_Tp, _Alloc>::_M_range_insert(iterator __pos, + _InputIterator __first, + _InputIterator __last, + input_iterator_tag) +{ + for ( ; __first != __last; ++__first) { + __pos = insert(__pos, *__first); + ++__pos; } } -template <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); +template <class _Tp, class _Alloc> template <class _ForwardIterator> +void +vector<_Tp, _Alloc>::_M_range_insert(iterator __position, + _ForwardIterator __first, + _ForwardIterator __last, + forward_iterator_tag) +{ + if (__first != __last) { + size_type __n = 0; + distance(__first, __last, __n); + if (size_type(_M_end_of_storage - _M_finish) >= __n) { + const size_type __elems_after = _M_finish - __position; + iterator __old_finish = _M_finish; + if (__elems_after > __n) { + uninitialized_copy(_M_finish - __n, _M_finish, _M_finish); + _M_finish += __n; + copy_backward(__position, __old_finish - __n, __old_finish); + copy(__first, __last, __position); } else { - ForwardIterator mid = first; - advance(mid, elems_after); - uninitialized_copy(mid, last, finish); - finish += n - elems_after; - uninitialized_copy(position, old_finish, finish); - finish += elems_after; - copy(first, mid, position); + _ForwardIterator __mid = __first; + advance(__mid, __elems_after); + uninitialized_copy(__mid, __last, _M_finish); + _M_finish += __n - __elems_after; + uninitialized_copy(__position, __old_finish, _M_finish); + _M_finish += __elems_after; + copy(__first, __mid, __position); } } else { - const size_type old_size = size(); - const size_type len = old_size + max(old_size, n); - iterator new_start = data_allocator::allocate(len); - iterator new_finish = new_start; + const size_type __old_size = size(); + const size_type __len = __old_size + max(__old_size, __n); + iterator __new_start = _M_allocate(__len); + iterator __new_finish = __new_start; __STL_TRY { - new_finish = uninitialized_copy(start, position, new_start); - new_finish = uninitialized_copy(first, last, new_finish); - new_finish = uninitialized_copy(position, finish, new_finish); - } -# ifdef __STL_USE_EXCEPTIONS - catch(...) { - destroy(new_start, new_finish); - data_allocator::deallocate(new_start, len); - throw; + __new_finish = uninitialized_copy(_M_start, __position, __new_start); + __new_finish = uninitialized_copy(__first, __last, __new_finish); + __new_finish + = uninitialized_copy(__position, _M_finish, __new_finish); } -# endif /* __STL_USE_EXCEPTIONS */ - destroy(start, finish); - deallocate(); - start = new_start; - finish = new_finish; - end_of_storage = new_start + len; + __STL_UNWIND((destroy(__new_start,__new_finish), + _M_deallocate(__new_start,__len))); + destroy(_M_start, _M_finish); + _M_deallocate(_M_start, _M_end_of_storage - _M_start); + _M_start = __new_start; + _M_finish = __new_finish; + _M_end_of_storage = __new_start + __len; } } } #else /* __STL_MEMBER_TEMPLATES */ -template <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); +template <class _Tp, class _Alloc> +void +vector<_Tp, _Alloc>::insert(iterator __position, + const_iterator __first, + const_iterator __last) +{ + if (__first != __last) { + size_type __n = 0; + distance(__first, __last, __n); + if (size_type(_M_end_of_storage - _M_finish) >= __n) { + const size_type __elems_after = _M_finish - __position; + iterator __old_finish = _M_finish; + if (__elems_after > __n) { + uninitialized_copy(_M_finish - __n, _M_finish, _M_finish); + _M_finish += __n; + copy_backward(__position, __old_finish - __n, __old_finish); + copy(__first, __last, __position); } else { - uninitialized_copy(first + elems_after, last, finish); - finish += n - elems_after; - uninitialized_copy(position, old_finish, finish); - finish += elems_after; - copy(first, first + elems_after, position); + uninitialized_copy(__first + __elems_after, __last, _M_finish); + _M_finish += __n - __elems_after; + uninitialized_copy(__position, __old_finish, _M_finish); + _M_finish += __elems_after; + copy(__first, __first + __elems_after, __position); } } else { - const size_type old_size = size(); - const size_type len = old_size + max(old_size, n); - iterator new_start = data_allocator::allocate(len); - iterator new_finish = new_start; + const size_type __old_size = size(); + const size_type __len = __old_size + max(__old_size, __n); + iterator __new_start = _M_allocate(__len); + iterator __new_finish = __new_start; __STL_TRY { - new_finish = uninitialized_copy(start, position, new_start); - new_finish = uninitialized_copy(first, last, new_finish); - new_finish = uninitialized_copy(position, finish, new_finish); - } -# ifdef __STL_USE_EXCEPTIONS - catch(...) { - destroy(new_start, new_finish); - data_allocator::deallocate(new_start, len); - throw; + __new_finish = uninitialized_copy(_M_start, __position, __new_start); + __new_finish = uninitialized_copy(__first, __last, __new_finish); + __new_finish + = uninitialized_copy(__position, _M_finish, __new_finish); } -# endif /* __STL_USE_EXCEPTIONS */ - destroy(start, finish); - deallocate(); - start = new_start; - finish = new_finish; - end_of_storage = new_start + len; + __STL_UNWIND((destroy(__new_start,__new_finish), + _M_deallocate(__new_start,__len))); + destroy(_M_start, _M_finish); + _M_deallocate(_M_start, _M_end_of_storage - _M_start); + _M_start = __new_start; + _M_finish = __new_finish; + _M_end_of_storage = __new_start + __len; } } } @@ -523,6 +811,7 @@ void vector<T, Alloc>::insert(iterator position, #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 +#pragma reset woff 1375 #endif __STL_END_NAMESPACE diff --git a/contrib/libstdc++/stl/tempbuf.h b/contrib/libstdc++/stl/tempbuf.h index 8799393..aa4f289 100644 --- a/contrib/libstdc++/stl/tempbuf.h +++ b/contrib/libstdc++/stl/tempbuf.h @@ -30,15 +30,18 @@ #ifndef __SGI_STL_PAIR_H #include <pair.h> #endif -#include <limits.h> -#include <stddef.h> -#include <stdlib.h> +#include <limits.h> /* XXX should use <climits> */ +#include <stddef.h> /* XXX should use <cstddef> */ +#include <stdlib.h> /* XXX should use <cstdlib> */ #ifndef __TYPE_TRAITS_H #include <type_traits.h> #endif #ifndef __SGI_STL_INTERNAL_CONSTRUCT_H #include <stl_construct.h> #endif +#ifndef __SGI_STL_INTERNAL_UNINITIALIZED_H +#include <stl_uninitialized.h> +#endif #ifndef __SGI_STL_INTERNAL_TEMPBUF_H #include <stl_tempbuf.h> #endif diff --git a/contrib/libstdc++/stl/type_traits.h b/contrib/libstdc++/stl/type_traits.h index 40c6339..b6a7dfc6 100644 --- a/contrib/libstdc++/stl/type_traits.h +++ b/contrib/libstdc++/stl/type_traits.h @@ -40,13 +40,14 @@ attain their correct values by one of these means: EXAMPLE: //Copy an array of elements which have non-trivial copy constructors -template <class T> void copy(T* source,T* destination,int n,__false_type); +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); +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()); + copy(source, destination, n, + typename __type_traits<T>::has_trivial_copy_constructor()); } */ @@ -57,7 +58,7 @@ struct __true_type { struct __false_type { }; -template <class type> +template <class _Tp> struct __type_traits { typedef __true_type this_dummy_member_must_be_first; /* Do not remove this member. It informs a compiler which @@ -90,6 +91,18 @@ struct __type_traits { // have built-in __types_traits support, and essential for compilers // that don't. +#ifndef __STL_NO_BOOL + +__STL_TEMPLATE_NULL struct __type_traits<bool> { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +#endif /* __STL_NO_BOOL */ + __STL_TEMPLATE_NULL struct __type_traits<char> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; @@ -114,6 +127,18 @@ __STL_TEMPLATE_NULL struct __type_traits<unsigned char> { typedef __true_type is_POD_type; }; +#ifdef __STL_HAS_WCHAR_T + +__STL_TEMPLATE_NULL struct __type_traits<wchar_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; +}; + +#endif /* __STL_HAS_WCHAR_T */ + __STL_TEMPLATE_NULL struct __type_traits<short> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; @@ -162,6 +187,26 @@ __STL_TEMPLATE_NULL struct __type_traits<unsigned long> { typedef __true_type is_POD_type; }; +#ifdef __STL_LONG_LONG + +__STL_TEMPLATE_NULL struct __type_traits<long 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 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; +}; + +#endif /* __STL_LONG_LONG */ + __STL_TEMPLATE_NULL struct __type_traits<float> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; @@ -188,8 +233,8 @@ __STL_TEMPLATE_NULL struct __type_traits<long double> { #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION -template <class T> -struct __type_traits<T*> { +template <class _Tp> +struct __type_traits<_Tp*> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; @@ -199,7 +244,31 @@ struct __type_traits<T*> { #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ -struct __type_traits<char*> { +__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<const char*> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; @@ -207,7 +276,7 @@ struct __type_traits<char*> { typedef __true_type is_POD_type; }; -struct __type_traits<signed char*> { +__STL_TEMPLATE_NULL struct __type_traits<const signed char*> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; @@ -215,7 +284,7 @@ struct __type_traits<signed char*> { typedef __true_type is_POD_type; }; -struct __type_traits<unsigned char*> { +__STL_TEMPLATE_NULL struct __type_traits<const unsigned char*> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; @@ -226,6 +295,77 @@ struct __type_traits<unsigned char*> { #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ +// The following could be written in terms of numeric_limits. +// We're doing it separately to reduce the number of dependencies. + +template <class _Tp> struct _Is_integer { + typedef __false_type _Integral; +}; + +#ifndef __STL_NO_BOOL + +__STL_TEMPLATE_NULL struct _Is_integer<bool> { + typedef __true_type _Integral; +}; + +#endif /* __STL_NO_BOOL */ + +__STL_TEMPLATE_NULL struct _Is_integer<char> { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer<signed char> { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer<unsigned char> { + typedef __true_type _Integral; +}; + +#ifdef __STL_HAS_WCHAR_T + +__STL_TEMPLATE_NULL struct _Is_integer<wchar_t> { + typedef __true_type _Integral; +}; + +#endif /* __STL_HAS_WCHAR_T */ + +__STL_TEMPLATE_NULL struct _Is_integer<short> { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer<unsigned short> { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer<int> { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer<unsigned int> { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer<long> { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer<unsigned long> { + typedef __true_type _Integral; +}; + +#ifdef __STL_LONG_LONG + +__STL_TEMPLATE_NULL struct _Is_integer<long long> { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer<unsigned long long> { + typedef __true_type _Integral; +}; + +#endif /* __STL_LONG_LONG */ + #endif /* __TYPE_TRAITS_H */ // Local Variables: diff --git a/contrib/libstdc++/stlinst.cc b/contrib/libstdc++/stlinst.cc index b71dc7e..2a221fb 100644 --- a/contrib/libstdc++/stlinst.cc +++ b/contrib/libstdc++/stlinst.cc @@ -3,6 +3,8 @@ #include <alloc.h> +#ifndef __USE_MALLOC template class __default_alloc_template<__NODE_ALLOCATOR_THREADS, 0>; +#endif template class __malloc_alloc_template<0>; diff --git a/contrib/libstdc++/tests/ChangeLog b/contrib/libstdc++/tests/ChangeLog index 8c036b7..dcec430 100644 --- a/contrib/libstdc++/tests/ChangeLog +++ b/contrib/libstdc++/tests/ChangeLog @@ -1,6 +1,14 @@ -Sun Mar 14 02:38:07 PST 1999 Jeff Law (law@cygnus.com) +Mon Aug 16 01:29:24 PDT 1999 Jeff Law (law@cygnus.com) - * egcs-1.1.2 Released. + * gcc-2.95.1 Released. + +Wed Jul 28 21:39:31 PDT 1999 Jeff Law (law@cygnus.com) + + * gcc-2.95 Released. + +Sun Jul 25 23:40:51 PDT 1999 Jeff Law (law@cygnus.com) + + * gcc-2.95 Released. 1998-07-17 Jason Merrill <jason@yorick.cygnus.com> diff --git a/contrib/libstdc++/testsuite/ChangeLog b/contrib/libstdc++/testsuite/ChangeLog index 5809989..784b623 100644 --- a/contrib/libstdc++/testsuite/ChangeLog +++ b/contrib/libstdc++/testsuite/ChangeLog @@ -1,6 +1,18 @@ -Sun Mar 14 02:38:07 PST 1999 Jeff Law (law@cygnus.com) +Mon Aug 16 01:29:24 PDT 1999 Jeff Law (law@cygnus.com) - * egcs-1.1.2 Released. + * gcc-2.95.1 Released. + +Wed Jul 28 21:39:31 PDT 1999 Jeff Law (law@cygnus.com) + + * gcc-2.95 Released. + +Sun Jul 25 23:40:51 PDT 1999 Jeff Law (law@cygnus.com) + + * gcc-2.95 Released. + +Wed Nov 25 01:00:07 1998 Marc Espie <espie@quatramaran.ens.fr> + + * Makefile.in (just-check): Ignore errors. Sun Jun 28 00:00:10 1998 Carlo Wood <carlo@runaway.xs4all.nl> diff --git a/contrib/libstdc++/testsuite/Makefile.in b/contrib/libstdc++/testsuite/Makefile.in index b279d72..7c85678 100644 --- a/contrib/libstdc++/testsuite/Makefile.in +++ b/contrib/libstdc++/testsuite/Makefile.in @@ -13,7 +13,8 @@ # # 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. +# the Free Software Foundation, 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. */ srcdir = libstdc++.tests @@ -57,7 +58,7 @@ site.exp: ./config.status Makefile -@rm -f ./tmp? just-check: site.exp - rootme=`pwd`; export rootme; \ + -rootme=`pwd`; export rootme; \ srcdir=${srcdir} ; export srcdir ; \ EXPECT=${EXPECT} ; export EXPECT ; \ if [ -f $${rootme}/../../expect/expect ] ; then \ diff --git a/contrib/libstdc++/valarray b/contrib/libstdc++/valarray new file mode 100644 index 0000000..a938b6a --- /dev/null +++ b/contrib/libstdc++/valarray @@ -0,0 +1,8 @@ +// Main header for -*- C++ -*- valarray classes. + +#ifndef __VALARRAY__ +#define __VALARRAY__ + +#include <std/std_valarray.h> + +#endif diff --git a/contrib/libstdc++/valarray.cc b/contrib/libstdc++/valarray.cc new file mode 100644 index 0000000..5e7fe0c --- /dev/null +++ b/contrib/libstdc++/valarray.cc @@ -0,0 +1,50 @@ +#include <std/std_valarray.h> + +// Some Explicit Instanciations. +template class multiplies<size_t>; +template size_t accumulate(size_t*, size_t*, size_t, multiplies<size_t>); + +template void + __valarray_fill(size_t* __restrict__, size_t, const size_t&); + +template void + __valarray_copy(const size_t* __restrict__, size_t, size_t* __restrict__); + +template valarray<size_t>::valarray(size_t); +template valarray<size_t>::~valarray(); +template valarray<size_t>::valarray(const valarray<size_t>&); +template size_t valarray<size_t>::size() const; +template size_t& valarray<size_t>::operator[](size_t); +template size_t valarray<size_t>::product() const; + + +void __gslice_to_index(size_t __o, const valarray<size_t>& __l, + const valarray<size_t>& __s, + valarray<size_t>& __i) +{ + const size_t __n = __l.size(); + size_t* const __t = static_cast<size_t*>(alloca(__n*sizeof(size_t))); + __valarray_fill(__t, __n, size_t(0)); + const size_t __z = __i.size(); + __valarray_fill(&__i[0], __z, __o); + for (size_t __j=0; __j<__z; ++__j) { + for (size_t __k=0; __k<__n; ++__k) + __i[__j] += __s[__k]*__t[__k]; + ++__t[__n-1]; + for (size_t __k=__n-1; __k; --__k) { + if (__t[__k] >= __l[__k]) { + __t[__k] = 0; + ++__t[__k-1]; + } + } + } +} + +_Indexer::_Indexer(size_t __o, const valarray<size_t>& __l, + const valarray<size_t>& __s) + : _M_count(1), _M_start(__o), _M_size(__l), _M_stride(__s), + _M_index(__l.size() ? __l.product() : 0) +{ __gslice_to_index(__o, __l, __s, _M_index); } + + + |